diff --git a/app_darwin.go b/app_darwin.go index 3bea38a..b67ede1 100644 --- a/app_darwin.go +++ b/app_darwin.go @@ -10,53 +10,18 @@ package unison import ( - "strings" "time" - "github.com/progrium/macdriver/objc" "github.com/richardwilkes/unison/internal/ns" ) func platformEarlyInit() { - if openURLsCallback != nil { - appDelegate := ns.App().GetDelegate() - cls := objc.NewClass("UnisonAppDelegate", "NSObject") - cls.AddMethod("applicationShouldTerminate:", func(_, p1 objc.Object) uint { - return uint(appDelegate.Send("applicationShouldTerminte:", p1).Uint()) - }) - cls.AddMethod("applicationDidChangeScreenParameters:", func(_, p1 objc.Object) { - appDelegate.Send("applicationDidChangeScreenParameters:", p1) - }) - cls.AddMethod("applicationWillFinishLaunching:", func(_, p1 objc.Object) { - appDelegate.Send("applicationWillFinishLaunching:", p1) - }) - cls.AddMethod("applicationDidFinishLaunching:", func(_, p1 objc.Object) { - appDelegate.Send("applicationDidFinishLaunching:", p1) - }) - cls.AddMethod("applicationDidHide:", func(_, p1 objc.Object) { - appDelegate.Send("applicationDidHide:", p1) - }) - // All of the methods above this point are just pass-throughs to glfw. If glfw adds more methods, corresponding - // additions should be made here. - cls.AddMethod("application:openURLs:", func(_, app, urls objc.Object) { - if data := ns.URLArrayToStringSlice(ns.Array{Object: urls}); len(data) != 0 { - openURLsCallback(data) - } - }) - ns.App().SetDelegate(cls.Alloc().Init()) - } + ns.InstallAppDelegate(openURLsCallback) } func platformLateInit() { - cls := objc.NewClass("ThemeDelegate", "NSObject") - cls.AddMethod("themeChanged:", func(objc.Object) { themeChanged() }) - delegate := cls.Alloc().Init() - def := ns.DefaultCenter() - selector := objc.Sel("themeChanged:") - def.AddObserver(delegate, selector, "AppleInterfaceThemeChangedNotification") - def.AddObserver(delegate, selector, "AppleColorPreferencesChangedNotification") - - ns.App().SetActivationPolicy(ns.ActivationPolicyRegular) + ns.InstallSystemThemeChangedCallback(themeChanged) + ns.SetActivationPolicy(ns.ActivationPolicyRegular) } func platformBeep() { @@ -68,7 +33,7 @@ func platformIsDarkModeTrackingPossible() bool { } func platformIsDarkModeEnabled() bool { - return strings.Contains(strings.ToLower(ns.StandardUserDefaults().StringForKey("AppleInterfaceStyle")), "dark") + return ns.IsDarkModeEnabled() } func platformDoubleClickInterval() time.Duration { diff --git a/go.mod b/go.mod index ab50b83..414582b 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,6 @@ go 1.17 require ( github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec - github.com/progrium/macdriver v0.2.0 github.com/richardwilkes/toolbox v1.54.0 github.com/stretchr/testify v1.7.0 golang.org/x/image v0.0.0-20211028202545-6944b10bf410 diff --git a/go.sum b/go.sum index a3182e1..23b28c8 100644 --- a/go.sum +++ b/go.sum @@ -1,120 +1,13 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/chromedp/cdproto v0.0.0-20210323015217-0942afbea50e/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U= -github.com/chromedp/chromedp v0.6.10/go.mod h1:Q8L2uDLH9YFYbThK5fqPpyWa3CT4y9dqHLxaQr+Yhl8= -github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 h1:zDw5v7qm4yH7N8C8uWd+8Ii9rROdgWxQuGoJ9WDXxfk= github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec h1:3FLiRYO6PlQFDpUU7OEFlWgjGD1jnBIVSJ5SYRWk+9c= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8= -github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= -github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.4/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jackpal/gateway v1.0.7/go.mod h1:aRcO0UFKt+MgIZmRmvOmnejdDT4Y1DNiNOsSd1AcIbA= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= @@ -123,212 +16,33 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/term v1.1.0 h1:xIAAdCMh3QIAy+5FrE8Ad8XoDhEU4ufwbaSozViP9kk= github.com/pkg/term v1.1.0/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/progrium/macdriver v0.2.0 h1:+b90k/lyX0K0sV/aYs9EzWSgVhOFMGytKsnCsa1Uh7M= -github.com/progrium/macdriver v0.2.0/go.mod h1:QkZLlOeMkYF92euEWqUBpry7/tXrZuM575xZRwnuiig= -github.com/progrium/macschema v0.1.0/go.mod h1:XzxlqYAo4vKozoZd837LBMjPcfJNlvwB5yBn5Nu+RDE= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/richardwilkes/toolbox v1.54.0 h1:s5TMkrHONGOjZp7o8UiHxSYbBeX8QRiVdsKTa84jbCw= github.com/richardwilkes/toolbox v1.54.0/go.mod h1:PJe2CGtD+8r+PnwiLBZVCvLm3d5lDSnJgH167+zWWhk= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yookoala/realpath v1.0.0 h1:7OA9pj4FZd+oZDsyvXWQvjn5oBdcHRTV44PpdMSuImQ= github.com/yookoala/realpath v1.0.0/go.mod h1:gJJMA9wuX7AcqLy1+ffPatSCySA1FQ2S8Ya9AIoYBpE= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ= golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/internal/ns/application_darwin.go b/internal/ns/application_darwin.go deleted file mode 100644 index 78e0e5d..0000000 --- a/internal/ns/application_darwin.go +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright ©2021 by Richard A. Wilkes. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with -// this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// This Source Code Form is "Incompatible With Secondary Licenses", as -// defined by the Mozilla Public License, version 2.0. - -package ns - -import ( - "github.com/progrium/macdriver/objc" -) - -// ActivationPolicy https://developer.apple.com/documentation/appkit/nsapplicationactivationpolicy?language=objc -type ActivationPolicy uint - -// https://developer.apple.com/documentation/appkit/nsapplicationactivationpolicy?language=objc -const ( - ActivationPolicyRegular ActivationPolicy = iota - ActivationPolicyAccessory - ActivationPolicyProhibited -) - -var applicationClass = objc.Get("NSApplication") - -// Application https://developer.apple.com/documentation/appkit/nsapplication?language=objc -type Application struct { - objc.Object -} - -// App https://developer.apple.com/documentation/appkit/nsapp?language=objc -func App() Application { - return Application{Object: applicationClass.Send("sharedApplication")} -} - -// GetDelegate https://developer.apple.com/documentation/appkit/nsapplication/1428705-delegate?language=objc -func (a Application) GetDelegate() objc.Object { - return a.Send("delegate") -} - -// SetDelegate https://developer.apple.com/documentation/appkit/nsapplication/1428705-delegate?language=objc -func (a Application) SetDelegate(delegate objc.Object) { - a.Send("setDelegate:", delegate) -} - -// HideOtherApplications https://developer.apple.com/documentation/appkit/nsapplication/1428746-hideotherapplications?language=objc -func (a Application) HideOtherApplications() { - a.Send("hideOtherApplications:", nil) -} - -// UnhideAllApplications https://developer.apple.com/documentation/appkit/nsapplication/1428737-unhideallapplications?language=objc -func (a Application) UnhideAllApplications() { - a.Send("unhideAllApplications:", nil) -} - -// SetActivationPolicy https://developer.apple.com/documentation/appkit/nsapplication/1428621-setactivationpolicy?language=objc -func (a Application) SetActivationPolicy(policy ActivationPolicy) { - a.Send("setActivationPolicy:", policy) -} - -// SetMainMenu https://developer.apple.com/documentation/appkit/nsapplication/1428634-mainmenu?language=objc -func (a Application) SetMainMenu(menu Menu) { - a.Send("setMainMenu:", menu) -} - -// SetServicesMenu https://developer.apple.com/documentation/appkit/nsapplication/1428608-servicesmenu?language=objc -func (a Application) SetServicesMenu(menu Menu) { - a.Send("setServicesMenu:", menu) -} - -// SetWindowsMenu https://developer.apple.com/documentation/appkit/nsapplication/1428547-windowsmenu?language=objc -func (a Application) SetWindowsMenu(menu Menu) { - a.Send("setWindowsMenu:", menu) -} - -// SetHelpMenu https://developer.apple.com/documentation/appkit/nsapplication/1428644-helpmenu?language=objc -func (a Application) SetHelpMenu(menu Menu) { - a.Send("setHelpMenu:", menu) -} diff --git a/internal/ns/array_darwin.go b/internal/ns/array_darwin.go deleted file mode 100644 index 0532864..0000000 --- a/internal/ns/array_darwin.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright ©2021 by Richard A. Wilkes. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with -// this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// This Source Code Form is "Incompatible With Secondary Licenses", as -// defined by the Mozilla Public License, version 2.0. - -package ns - -import "github.com/progrium/macdriver/objc" - -// Array https://developer.apple.com/documentation/foundation/nsarray?language=objc -type Array struct { - objc.Object -} - -// Count https://developer.apple.com/documentation/foundation/nsarray/1409982-count?language=objc -func (a Array) Count() int { - return int(a.Send("count").Uint()) -} - -// ObjectAtIndex https://developer.apple.com/documentation/foundation/nsarray/1417555-objectatindex?language=objc -func (a Array) ObjectAtIndex(index int) objc.Object { - return a.Send("objectAtIndex:", uint(index)) -} - -// StringAtIndex returns the String at the specified index. No check is made to verify the object is actually a String. -func (a Array) StringAtIndex(index int) String { - return String{Object: a.ObjectAtIndex(index)} -} diff --git a/internal/ns/beep_darwin.go b/internal/ns/beep_darwin.go deleted file mode 100644 index 3354a98..0000000 --- a/internal/ns/beep_darwin.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright ©2021 by Richard A. Wilkes. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with -// this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// This Source Code Form is "Incompatible With Secondary Licenses", as -// defined by the Mozilla Public License, version 2.0. - -package ns - -import ( - "github.com/progrium/macdriver/misc/variadic" -) - -var beepFunc = variadic.NewFunctionCall("NSBeep") - -// Beep https://developer.apple.com/documentation/appkit/1473622-nsbeep?language=objc -func Beep() { - beepFunc.Call() -} diff --git a/internal/ns/callbacks_darwin.go b/internal/ns/callbacks_darwin.go new file mode 100644 index 0000000..a23f169 --- /dev/null +++ b/internal/ns/callbacks_darwin.go @@ -0,0 +1,67 @@ +// Copyright ©2022 by Richard A. Wilkes. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, version 2.0. If a copy of the MPL was not distributed with +// this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// +// This Source Code Form is "Incompatible With Secondary Licenses", as +// defined by the Mozilla Public License, version 2.0. + +package ns + +/* +#import + +typedef CFTypeRef NSMenuRef; +typedef CFTypeRef NSMenuItemRef; +*/ +import "C" + +var ( + menuUpdaters = make(map[Menu]func(Menu)) + menuItemValidators = make(map[MenuItem]func(item MenuItem) bool) + menuItemHandlers = make(map[MenuItem]func(item MenuItem)) + openURLsCallback func([]string) + systemThemeChangedCallback func() +) + +//export updateMenuCallback +func updateMenuCallback(m C.NSMenuRef) { + menu := Menu(m) + if updater, ok := menuUpdaters[menu]; ok && updater != nil { + updater(menu) + } +} + +//export menuItemValidateCallback +func menuItemValidateCallback(mi C.NSMenuItemRef) bool { + item := MenuItem(mi) + if validator, ok := menuItemValidators[item]; ok && validator != nil { + return validator(item) + } + return true +} + +//export menuItemHandleCallback +func menuItemHandleCallback(mi C.NSMenuItemRef) { + item := MenuItem(mi) + if handler, ok := menuItemHandlers[item]; ok && handler != nil { + handler(item) + } +} + +//export appOpenURLsCallback +func appOpenURLsCallback(a C.CFArrayRef) { + if openURLsCallback != nil { + if urls := Array(a).ArrayOfURLToStringSlice(); len(urls) > 0 { + openURLsCallback(urls) + } + } +} + +//export themeChangedCallback +func themeChangedCallback() { + if systemThemeChangedCallback != nil { + systemThemeChangedCallback() + } +} diff --git a/internal/ns/distributed_notification_center_darwin.go b/internal/ns/distributed_notification_center_darwin.go deleted file mode 100644 index 0d2cd5c..0000000 --- a/internal/ns/distributed_notification_center_darwin.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright ©2021 by Richard A. Wilkes. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with -// this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// This Source Code Form is "Incompatible With Secondary Licenses", as -// defined by the Mozilla Public License, version 2.0. - -package ns - -import "github.com/progrium/macdriver/objc" - -var distributedNotificationCenterClass = objc.Get("NSDistributedNotificationCenter") - -// DistributedNotificationCenter https://developer.apple.com/documentation/foundation/nsdistributednotificationcenter/ -type DistributedNotificationCenter struct { - objc.Object -} - -// DefaultCenter https://developer.apple.com/documentation/foundation/nsdistributednotificationcenter/1412063-defaultcenter -func DefaultCenter() DistributedNotificationCenter { - return DistributedNotificationCenter{Object: distributedNotificationCenterClass.Send("defaultCenter")} -} - -// AddObserver https://developer.apple.com/documentation/foundation/nsdistributednotificationcenter/1414151-addobserver -func (c DistributedNotificationCenter) AddObserver(delegate objc.Object, selector objc.Selector, name string) { - str := StringFromString(name) - defer str.Release() - c.Send("addObserver:selector:name:object:", delegate, selector, str, nil) -} diff --git a/internal/ns/event_darwin.go b/internal/ns/event_darwin.go deleted file mode 100644 index 4c36ee0..0000000 --- a/internal/ns/event_darwin.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright ©2021 by Richard A. Wilkes. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with -// this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// This Source Code Form is "Incompatible With Secondary Licenses", as -// defined by the Mozilla Public License, version 2.0. - -package ns - -import ( - "time" - - "github.com/progrium/macdriver/objc" -) - -var eventClass = objc.Get("NSEvent") - -// DoubleClickInterval https://developer.apple.com/documentation/appkit/nsevent/1528384-doubleclickinterval?language=objc -func DoubleClickInterval() time.Duration { - return time.Duration(eventClass.Send("doubleClickInterval").Float()*1000) * time.Millisecond -} diff --git a/internal/ns/menu_darwin.go b/internal/ns/menu_darwin.go deleted file mode 100644 index aad353b..0000000 --- a/internal/ns/menu_darwin.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright ©2021 by Richard A. Wilkes. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with -// this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// This Source Code Form is "Incompatible With Secondary Licenses", as -// defined by the Mozilla Public License, version 2.0. - -package ns - -import "github.com/progrium/macdriver/objc" - -var menuClass = objc.Get("NSMenu") - -// Menu https://developer.apple.com/documentation/appkit/nsmenu?language=objc -type Menu struct { - objc.Object -} - -// NewMenu https://developer.apple.com/documentation/appkit/nsmenu/1518144-initwithtitle?language=objc -func NewMenu(title string) Menu { - titleStr := StringFromString(title) - defer titleStr.Release() - obj := menuClass.Alloc() - obj.Send("initWithTitle:", titleStr) - obj.Retain() - return Menu{Object: obj} -} - -// SetDelegate https://developer.apple.com/documentation/appkit/nsmenu/1518169-delegate?language=objc -func (m Menu) SetDelegate(delegate objc.Object) { - m.Send("setDelegate:", delegate) -} - -// NumberOfItems https://developer.apple.com/documentation/appkit/nsmenu/1518202-numberofitems?language=objc -func (m Menu) NumberOfItems() int { - return int(m.Send("numberOfItems").Int()) -} - -// ItemAtIndex https://developer.apple.com/documentation/appkit/nsmenu/1518218-itematindex?language=objc -func (m Menu) ItemAtIndex(index int) MenuItem { - return MenuItem{Object: m.Send("itemAtIndex:", index)} -} - -// InsertItemAtIndex https://developer.apple.com/documentation/appkit/nsmenu/1518201-insertitem?language=objc -func (m Menu) InsertItemAtIndex(item MenuItem, index int) { - m.Send("insertItem:atIndex:", item, index) -} - -// RemoveItemAtIndex https://developer.apple.com/documentation/appkit/nsmenu/1518207-removeitematindex?language=objc -func (m Menu) RemoveItemAtIndex(index int) { - m.Send("removeItemAtIndex:", index) -} - -// Title https://developer.apple.com/documentation/appkit/nsmenu/1518192-title?language=objc -func (m Menu) Title() string { - return m.Send("title").String() -} diff --git a/internal/ns/menu_item_darwin.go b/internal/ns/menu_item_darwin.go deleted file mode 100644 index 167eb76..0000000 --- a/internal/ns/menu_item_darwin.go +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright ©2021 by Richard A. Wilkes. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with -// this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// This Source Code Form is "Incompatible With Secondary Licenses", as -// defined by the Mozilla Public License, version 2.0. - -package ns - -import "github.com/progrium/macdriver/objc" - -var menuItemClass = objc.Get("NSMenuItem") - -// EventModifierFlags https://developer.apple.com/documentation/appkit/nseventmodifierflags?language=objc -type EventModifierFlags uint - -// https://developer.apple.com/documentation/appkit/nseventmodifierflags?language=objc -const ( - EventModifierFlagCapsLock EventModifierFlags = 1 << (16 + iota) - EventModifierFlagShift - EventModifierFlagControl - EventModifierFlagOption - EventModifierFlagCommand -) - -// ControlStateValue https://developer.apple.com/documentation/appkit/nscontrolstatevalue?language=objc -type ControlStateValue int - -// https://developer.apple.com/documentation/appkit/nscontrolstatevalue?language=objc -const ( - ControlStateValueMixed ControlStateValue = iota - 1 - ControlStateValueOff - ControlStateValueOn -) - -// MenuItem https://developer.apple.com/documentation/appkit/nsmenuitem?language=objc -type MenuItem struct { - objc.Object -} - -// NewMenuItem https://developer.apple.com/documentation/appkit/nsmenuitem/1514858-initwithtitle?language=objc -func NewMenuItem(title string, action objc.Selector, keyEquivalent string) MenuItem { - titleStr := StringFromString(title) - defer titleStr.Release() - keyStr := StringFromString(keyEquivalent) - defer keyStr.Release() - obj := menuItemClass.Alloc() - obj.Send("initWithTitle:action:keyEquivalent:", titleStr, action, keyStr) - obj.Retain() - return MenuItem{Object: obj} -} - -// NewSeparatorMenuItem https://developer.apple.com/documentation/appkit/nsmenuitem/1514838-separatoritem?language=objc -func NewSeparatorMenuItem() MenuItem { - return MenuItem{Object: menuItemClass.Send("separatorItem").Retain()} -} - -// Tag https://developer.apple.com/documentation/appkit/nsmenuitem/1514840-tag?language=objc -func (m MenuItem) Tag() int { - return int(m.Send("tag").Int()) -} - -// SetTag https://developer.apple.com/documentation/appkit/nsmenuitem/1514840-tag?language=objc -func (m MenuItem) SetTag(tag int) { - m.Send("setTag:", tag) -} - -// SetKeyEquivalentModifierMask https://developer.apple.com/documentation/appkit/nsmenuitem/1514815-keyequivalentmodifiermask?language=objc -func (m MenuItem) SetKeyEquivalentModifierMask(modifiers EventModifierFlags) { - m.Send("setKeyEquivalentModifierMask:", modifiers) -} - -// SetTarget https://developer.apple.com/documentation/appkit/nsmenuitem/1514843-target?language=objc -func (m MenuItem) SetTarget(target objc.Object) { - m.Send("setTarget:", target) -} - -// IsSeparatorItem https://developer.apple.com/documentation/appkit/nsmenuitem/1514837-separatoritem?language=objc -func (m MenuItem) IsSeparatorItem() bool { - return m.Send("isSeparatorItem").Bool() -} - -// Title https://developer.apple.com/documentation/appkit/nsmenuitem/1514805-title?language=objc -func (m MenuItem) Title() string { - return m.Send("title").String() -} - -// SetTitle https://developer.apple.com/documentation/appkit/nsmenuitem/1514805-title?language=objc -func (m MenuItem) SetTitle(title string) { - titleStr := StringFromString(title) - defer titleStr.Release() - m.Send("setTitle:", titleStr) -} - -// Menu https://developer.apple.com/documentation/appkit/nsmenuitem/1514830-menu?language=objc -func (m MenuItem) Menu() Menu { - return Menu{Object: m.Send("menu")} -} - -// SubMenu https://developer.apple.com/documentation/appkit/nsmenuitem/1514845-submenu?language=objc -func (m MenuItem) SubMenu() Menu { - return Menu{Object: m.Send("submenu")} -} - -// SetSubMenu https://developer.apple.com/documentation/appkit/nsmenuitem/1514845-submenu?language=objc -func (m MenuItem) SetSubMenu(menu Menu) { - m.Send("setSubmenu:", menu) -} - -// State https://developer.apple.com/documentation/appkit/nsmenuitem/1514804-state?language=objc -func (m MenuItem) State() ControlStateValue { - return ControlStateValue(m.Send("state").Int()) -} - -// SetState https://developer.apple.com/documentation/appkit/nsmenuitem/1514804-state?language=objc -func (m MenuItem) SetState(state ControlStateValue) { - m.Send("setState:", int(state)) -} diff --git a/internal/ns/mutable_array_darwin.go b/internal/ns/mutable_array_darwin.go deleted file mode 100644 index beccd45..0000000 --- a/internal/ns/mutable_array_darwin.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright ©2021 by Richard A. Wilkes. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with -// this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// This Source Code Form is "Incompatible With Secondary Licenses", as -// defined by the Mozilla Public License, version 2.0. - -package ns - -import "github.com/progrium/macdriver/objc" - -var mutableArrayClass = objc.Get("NSMutableArray") - -// MutableArray https://developer.apple.com/documentation/foundation/nsmutablearray?language=objc -type MutableArray struct { - Array -} - -// MutableArrayWithCapacity https://developer.apple.com/documentation/foundation/nsmutablearray/1460057-arraywithcapacity?language=objc -func MutableArrayWithCapacity(capacity int) MutableArray { - return MutableArray{Array: Array{Object: mutableArrayClass.Send("arrayWithCapacity:", uint(capacity))}} -} - -// AddObject https://developer.apple.com/documentation/foundation/nsmutablearray/1411274-addobject?language=objc -func (a MutableArray) AddObject(obj objc.Object) { - a.Send("addObject:", obj) -} diff --git a/internal/ns/ns_darwin.go b/internal/ns/ns_darwin.go new file mode 100644 index 0000000..5fef29c --- /dev/null +++ b/internal/ns/ns_darwin.go @@ -0,0 +1,802 @@ +// Copyright ©2022 by Richard A. Wilkes. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, version 2.0. If a copy of the MPL was not distributed with +// this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// +// This Source Code Form is "Incompatible With Secondary Licenses", as +// defined by the Mozilla Public License, version 2.0. + +package ns + +// Important information about memory management: +// https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html#//apple_ref/doc/uid/20001148 + +/* +#cgo CFLAGS: -x objective-c -Wno-deprecated-declarations +#cgo LDFLAGS: -framework Cocoa + +#import + +void hideRunningApplication() { + [[NSRunningApplication currentApplication] hide]; +} + +void beep() { + NSBeep(); +} + +double doubleClickInterval() { + return [NSEvent doubleClickInterval]; +} + +typedef CFTypeRef NSOpenPanelRef; + +NSOpenPanelRef newOpenPanel() { + return [[NSOpenPanel openPanel] retain]; +} + +CFURLRef openPanelDirectoryURL(NSOpenPanelRef openPanel) { + return (CFURLRef)[(NSOpenPanel *)openPanel directoryURL]; +} + +void openPanelSetDirectoryURL(NSOpenPanelRef openPanel, CFURLRef url) { + [(NSOpenPanel *)openPanel setDirectoryURL:(NSURL *)url]; +} + +CFArrayRef openPanelAllowedFileTypes(NSOpenPanelRef openPanel) { + return (CFArrayRef)([(NSOpenPanel *)openPanel allowedFileTypes]); +} + +void openPanelSetAllowedFileTypes(NSOpenPanelRef openPanel, CFArrayRef types) { + [(NSOpenPanel *)openPanel setAllowedFileTypes:(NSArray*)(types)]; +} + +bool openPanelCanChooseFiles(NSOpenPanelRef openPanel) { + return [(NSOpenPanel *)openPanel canChooseFiles]; +} + +void openPanelSetCanChooseFiles(NSOpenPanelRef openPanel, bool set) { + [(NSOpenPanel *)openPanel setCanChooseFiles:set]; +} + +bool openPanelCanChooseDirectories(NSOpenPanelRef openPanel) { + return [(NSOpenPanel *)openPanel canChooseDirectories]; +} + +void openPanelSetCanChooseDirectories(NSOpenPanelRef openPanel, bool set) { + [(NSOpenPanel *)openPanel setCanChooseDirectories:set]; +} + +bool openPanelResolvesAliases(NSOpenPanelRef openPanel) { + return [(NSOpenPanel *)openPanel resolvesAliases]; +} + +void openPanelSetResolvesAliases(NSOpenPanelRef openPanel, bool set) { + [(NSOpenPanel *)openPanel setResolvesAliases:set]; +} + +bool openPanelAllowsMultipleSelection(NSOpenPanelRef openPanel) { + return [(NSOpenPanel *)openPanel allowsMultipleSelection]; +} + +void openPanelSetAllowsMultipleSelection(NSOpenPanelRef openPanel, bool set) { + [(NSOpenPanel *)openPanel setAllowsMultipleSelection:set]; +} + +CFArrayRef openPanelURLs(NSOpenPanelRef openPanel) { + return (CFArrayRef)[(NSOpenPanel *)openPanel URLs]; +} + +bool openPanelRunModal(NSOpenPanelRef openPanel) { + return [(NSOpenPanel *)openPanel runModal] == NSModalResponseOK; +} + +typedef CFTypeRef NSSavePanelRef; + +NSSavePanelRef newSavePanel() { + return [[NSSavePanel savePanel] retain]; +} + +CFURLRef savePanelDirectoryURL(NSSavePanelRef savePanel) { + return (CFURLRef)[(NSSavePanel *)savePanel directoryURL]; +} + +void savePanelSetDirectoryURL(NSSavePanelRef savePanel, CFURLRef url) { + [(NSSavePanel *)savePanel setDirectoryURL:(NSURL *)url]; +} + +CFArrayRef savePanelAllowedFileTypes(NSSavePanelRef savePanel) { + return (CFArrayRef)[(NSSavePanel *)savePanel allowedFileTypes]; +} + +void savePanelSetAllowedFileTypes(NSSavePanelRef savePanel, CFArrayRef types) { + [(NSSavePanel *)savePanel setAllowedFileTypes:(NSArray*)types]; +} + +CFURLRef savePanelURL(NSSavePanelRef savePanel) { + return (CFURLRef)[(NSSavePanel *)savePanel URL]; +} + +bool savePanelRunModal(NSSavePanelRef savePanel) { + return [(NSSavePanel *)savePanel runModal] == NSModalResponseOK; +} + +typedef CFTypeRef NSViewRef; + +void viewFrame(NSViewRef v, NSRect *frame) { + *frame = [(NSView *)v frame]; +} + +typedef CFTypeRef NSWindowRef; + +NSViewRef windowContentView(NSWindowRef w) { + return (NSViewRef)[(NSWindow *)w contentView]; +} + + +typedef CFTypeRef NSMenuRef; +typedef CFTypeRef NSMenuItemRef; + +void updateMenuCallback(NSMenuRef menu); + +@interface MenuDelegate : NSObject +@end + +@implementation MenuDelegate +- (void)menuNeedsUpdate:(NSMenu *)menu { + updateMenuCallback((NSMenuRef)(menu)); +} +@end + +static MenuDelegate *menuDelegate = nil; + +NSMenuRef newMenu(CFStringRef title) { + NSMenu *menu = [[[NSMenu alloc] initWithTitle:(NSString *)title] retain]; + if (!menuDelegate) { + menuDelegate = [MenuDelegate new]; + } + [menu setDelegate:menuDelegate]; + return (NSMenuRef)menu; +} + +int menuNumberOfItems(NSMenuRef m) { + return [(NSMenu *)m numberOfItems]; +} + +NSMenuItemRef menuItemAtIndex(NSMenuRef m, int index) { + return (NSMenuItemRef)[(NSMenu *)m itemAtIndex:index]; +} + +void menuInsertItemAtIndex(NSMenuRef m, NSMenuItemRef mi, int index) { + [(NSMenu *)m insertItem:(NSMenuItem *)mi atIndex:index]; +} + +void menuRemoveItemAtIndex(NSMenuRef m, int index) { + [(NSMenu *)m removeItemAtIndex:index]; +} + +CFStringRef menuTitle(NSMenuRef m) { + return (CFStringRef)[(NSMenu *)m title]; +} + +bool menuItemValidateCallback(NSMenuItemRef item); +void menuItemHandleCallback(NSMenuItemRef item); + +@interface MenuItemDelegate : NSObject +@end + +@implementation MenuItemDelegate +- (BOOL)validateMenuItem:(NSMenuItem *)menuItem { + return menuItemValidateCallback((NSMenuItemRef)menuItem) ? YES : NO; +} + +- (void)handleMenuItem:(id)sender { + menuItemHandleCallback((NSMenuItemRef)sender); +} +@end + +static MenuItemDelegate *menuItemDelegate = nil; + +NSMenuItemRef newMenuItem(int tag, CFStringRef title, CFStringRef keyEquiv, NSEventModifierFlags modifiers) { + NSMenuItem *item = [[[NSMenuItem alloc] initWithTitle:(NSString *)title + action:NSSelectorFromString(@"handleMenuItem:") keyEquivalent:(NSString *)keyEquiv] retain]; + [item setTag:tag]; + [item setKeyEquivalentModifierMask:modifiers]; + if (!menuItemDelegate) { + menuItemDelegate = [MenuItemDelegate new]; + } + [item setTarget:menuItemDelegate]; + return (NSMenuItemRef)item; +} + +NSMenuItemRef newMenuSeparatorItem() { + return (NSMenuItemRef)[[NSMenuItem separatorItem] retain]; +} + +bool menuItemIsSeparator(NSMenuItemRef mi) { + return [(NSMenuItem *)mi isSeparatorItem]; +} + +int menuItemTag(NSMenuItemRef mi) { + return [(NSMenuItem *)mi tag]; +} + +CFStringRef menuItemTitle(NSMenuItemRef mi) { + return (CFStringRef)[(NSMenuItem *)mi title]; +} + +void menuItemSetTitle(NSMenuItemRef mi, CFStringRef title) { + [(NSMenuItem *)mi setTitle:(NSString *)title]; +} + +NSMenuRef menuItemMenu(NSMenuItemRef mi) { + return (NSMenuRef)[(NSMenuItem *)mi menu]; +} + +NSMenuRef menuItemSubMenu(NSMenuItemRef mi) { + return [(NSMenuItem *)mi submenu]; +} + +void menuItemSetSubMenu(NSMenuItemRef mi, NSMenuRef m) { + [(NSMenuItem *)mi setSubmenu:(NSMenu *)m]; +} + +NSControlStateValue menuItemState(NSMenuItemRef mi) { + return [(NSMenuItem *)mi state]; +} + +void menuItemSetState(NSMenuItemRef mi, NSControlStateValue state) { + [(NSMenuItem *)mi setState:(NSControlStateValue)state]; +} + +void menuPopup(NSWindowRef wnd, NSMenuRef m, NSMenuItemRef mi, CGRect bounds) { + // popupMenuPositioningItem:atLocation:inView: is not being used here because it fails to work when a modal dialog + // is being used. + NSPopUpButtonCell *popUpButtonCell = [[NSPopUpButtonCell alloc] initTextCell:@"" pullsDown:NO]; + [popUpButtonCell setAutoenablesItems:NO]; + [popUpButtonCell setAltersStateOfSelectedItem:NO]; + [popUpButtonCell setMenu:(NSMenu *)m]; + [popUpButtonCell selectItem:(NSMenuItem *)mi]; + [popUpButtonCell performClickWithFrame:bounds inView:[(NSWindow *)wnd contentView]]; + [popUpButtonCell release]; +} + +static id underlyingAppDelegate; + +void appOpenURLsCallback(CFArrayRef urls); + +@interface UnisonAppDelegate : NSObject +@end + +@implementation UnisonAppDelegate + +- (void)applicationWillFinishLaunching:(NSNotification *)notification { + [underlyingAppDelegate applicationWillFinishLaunching:notification]; +} + +- (void)applicationDidFinishLaunching:(NSNotification *)notification { + [underlyingAppDelegate applicationDidFinishLaunching:notification]; +} + +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { + return [underlyingAppDelegate applicationShouldTerminate:sender]; +} + +- (void)applicationDidChangeScreenParameters:(NSNotification *)notification { + [underlyingAppDelegate applicationDidChangeScreenParameters:notification]; +} + +- (void)applicationDidHide:(NSNotification *)notification { + [underlyingAppDelegate applicationDidHide:notification]; +} + +// All of the methods above this point are just pass-throughs to glfw. If glfw adds more methods, corresponding +// additions should be made here. + +- (void)application:(NSApplication *)application openURLs:(NSArray *)urls { + appOpenURLsCallback((CFArrayRef)(urls)); +} + +@end + +void installAppDelegate() { + NSApplication *app = [NSApplication sharedApplication]; + underlyingAppDelegate = [app delegate]; + UnisonAppDelegate *delegate = [UnisonAppDelegate new]; + [app setDelegate:delegate]; +} + +void themeChangedCallback(); + +@interface ThemeDelegate : NSObject +@end + +@implementation ThemeDelegate + +- (void)themeChanged:(NSNotification *)unused { + themeChangedCallback(); +} + +@end + +void installThemeChangedCallback() { + ThemeDelegate *delegate = [ThemeDelegate new]; + [NSDistributedNotificationCenter.defaultCenter addObserver:delegate + selector:@selector(themeChanged:) name:@"AppleInterfaceThemeChangedNotification" object: nil]; + [NSDistributedNotificationCenter.defaultCenter addObserver:delegate + selector:@selector(themeChanged:) name:@"AppleColorPreferencesChangedNotification" object: nil]; +} + +void hideOtherApplications() { + NSApplication *app = [NSApplication sharedApplication]; + [app hideOtherApplications:app]; +} + +void unhideAllApplications() { + NSApplication *app = [NSApplication sharedApplication]; + [app unhideAllApplications:app]; +} + +void setActivationPolicy(NSApplicationActivationPolicy policy) { + [[NSApplication sharedApplication] setActivationPolicy:policy]; +} + +void setMainMenu(NSMenuRef menu) { + [[NSApplication sharedApplication] setMainMenu:(NSMenu *)menu]; +} + +void setServicesMenu(NSMenuRef menu) { + [[NSApplication sharedApplication] setServicesMenu:(NSMenu *)menu]; +} + +void setWindowsMenu(NSMenuRef menu) { + [[NSApplication sharedApplication] setWindowsMenu:(NSMenu *)menu]; +} + +void setHelpMenu(NSMenuRef menu) { + [[NSApplication sharedApplication] setHelpMenu:(NSMenu *)menu]; +} +*/ +import "C" + +import ( + "net/url" + "reflect" + "strings" + "time" + "unsafe" + + "github.com/richardwilkes/toolbox/errs" + "github.com/richardwilkes/toolbox/log/jot" + "github.com/richardwilkes/toolbox/xio/fs" + "github.com/richardwilkes/toolbox/xmath/geom32" +) + +type EventModifierFlags uint + +const ( + EventModifierFlagCapsLock EventModifierFlags = 1 << (16 + iota) + EventModifierFlagShift + EventModifierFlagControl + EventModifierFlagOption + EventModifierFlagCommand +) + +type ControlStateValue int + +const ( + ControlStateValueMixed ControlStateValue = iota - 1 + ControlStateValueOff + ControlStateValueOn +) + +func InstallAppDelegate(urlOpener func([]string)) { + openURLsCallback = urlOpener + if urlOpener != nil { + C.installAppDelegate() + } +} + +func InstallSystemThemeChangedCallback(f func()) { + systemThemeChangedCallback = f + if f != nil { + C.installThemeChangedCallback() + } +} + +func Beep() { + C.beep() +} + +func DoubleClickInterval() time.Duration { + return time.Duration(C.doubleClickInterval()*1000) * time.Millisecond +} + +type String C.CFStringRef + +func NewString(str string) String { + header := (*reflect.StringHeader)(unsafe.Pointer(&str)) + return String(C.CFStringCreateWithBytes(0, (*C.uint8)(unsafe.Pointer(header.Data)), C.long(header.Len), + C.kCFStringEncodingUTF8, 0)) +} + +func (s String) String() string { + strPtr := C.CFStringGetCStringPtr(C.CFStringRef(s), C.kCFStringEncodingUTF8) + if strPtr == nil { + maxBytes := 4*C.CFStringGetLength(C.CFStringRef(s)) + 1 + strPtr = (*C.char)(C.malloc(C.size_t(maxBytes))) + defer C.free(unsafe.Pointer(strPtr)) + if C.CFStringGetCString(C.CFStringRef(s), strPtr, maxBytes, C.kCFStringEncodingUTF8) == 0 { + jot.Warn(errs.New("failed to convert string")) + return "" + } + } + return C.GoString(strPtr) +} + +func (s String) Release() { + C.CFRelease(C.CFTypeRef(s)) +} + +type MutableArray C.CFMutableArrayRef +type Array C.CFArrayRef + +func NewArrayFromStringSlice(slice []string) Array { + a := C.CFArrayCreateMutable(0, C.long(len(slice)), &C.kCFTypeArrayCallBacks) + for _, s := range slice { + str := NewString(s) + C.CFArrayAppendValue(a, unsafe.Pointer(str)) + str.Release() + } + return Array(a) +} + +func (a Array) Count() int { + return int(C.CFArrayGetCount(C.CFArrayRef(a))) +} + +func (a Array) URLAtIndex(index int) URL { + return URL(C.CFArrayGetValueAtIndex(C.CFArrayRef(a), C.long(index))) +} + +func (a Array) StringAtIndex(index int) String { + return String(C.CFArrayGetValueAtIndex(C.CFArrayRef(a), C.long(index))) +} + +func (a Array) Release() { + C.CFRelease(C.CFTypeRef(a)) +} +func (a Array) ArrayOfURLToStringSlice() []string { + count := a.Count() + result := make([]string, 0, count) + for i := 0; i < count; i++ { + u, err := url.Parse(a.URLAtIndex(i).AbsoluteString()) + if err != nil { + jot.Warn(errs.NewWithCause("unable to parse URL", err)) + continue + } + result = append(result, u.Path) + } + return result +} + +func (a Array) ArrayOfStringToStringSlice() []string { + count := a.Count() + result := make([]string, 0, count) + for i := 0; i < count; i++ { + result = append(result, a.StringAtIndex(i).String()) + } + return result +} + +type URL C.CFURLRef + +func NewFileURL(str string) URL { + var isDir C.uchar + if strings.HasSuffix(str, "/") || fs.IsDir(str) { + isDir = 1 + } + header := (*reflect.StringHeader)(unsafe.Pointer(&str)) + return URL(C.CFURLCreateFromFileSystemRepresentation(0, (*C.uint8)(unsafe.Pointer(header.Data)), C.long(header.Len), isDir)) +} + +func (u URL) AbsoluteString() string { + other := C.CFURLCopyAbsoluteURL(C.CFURLRef(u)) + s := String(C.CFURLGetString(other)) + URL(other).Release() + defer s.Release() + return s.String() +} + +func (u URL) Release() { + C.CFRelease(C.CFTypeRef(u)) +} + +type OpenPanel C.NSOpenPanelRef + +func NewOpenPanel() OpenPanel { + return OpenPanel(C.newOpenPanel()) +} + +func (p OpenPanel) DirectoryURL() URL { + return URL(C.openPanelDirectoryURL(C.NSOpenPanelRef(p))) +} + +func (p OpenPanel) SetDirectoryURL(url URL) { + C.openPanelSetDirectoryURL(C.NSOpenPanelRef(p), C.CFURLRef(url)) +} + +func (p OpenPanel) AllowedFileTypes() Array { + return Array(C.openPanelAllowedFileTypes(C.NSOpenPanelRef(p))) +} + +func (p OpenPanel) SetAllowedFileTypes(types Array) { + C.openPanelSetAllowedFileTypes(C.NSOpenPanelRef(p), C.CFArrayRef(types)) +} + +func (p OpenPanel) CanChooseFiles() bool { + return bool(C.openPanelCanChooseFiles(C.NSOpenPanelRef(p))) +} + +func (p OpenPanel) SetCanChooseFiles(set bool) { + C.openPanelSetCanChooseFiles(C.NSOpenPanelRef(p), C.bool(set)) +} + +func (p OpenPanel) CanChooseDirectories() bool { + return bool(C.openPanelCanChooseDirectories(C.NSOpenPanelRef(p))) +} + +func (p OpenPanel) SetCanChooseDirectories(set bool) { + C.openPanelSetCanChooseDirectories(C.NSOpenPanelRef(p), C.bool(set)) +} + +func (p OpenPanel) ResolvesAliases() bool { + return bool(C.openPanelResolvesAliases(C.NSOpenPanelRef(p))) +} + +func (p OpenPanel) SetResolvesAliases(set bool) { + C.openPanelSetResolvesAliases(C.NSOpenPanelRef(p), C.bool(set)) +} + +func (p OpenPanel) AllowsMultipleSelection() bool { + return bool(C.openPanelAllowsMultipleSelection(C.NSOpenPanelRef(p))) +} + +func (p OpenPanel) SetAllowsMultipleSelection(set bool) { + C.openPanelSetAllowsMultipleSelection(C.NSOpenPanelRef(p), C.bool(set)) +} + +func (p OpenPanel) URLs() Array { + return Array(C.openPanelURLs(C.NSOpenPanelRef(p))) +} + +func (p OpenPanel) RunModal() bool { + return bool(C.openPanelRunModal(C.NSOpenPanelRef(p))) +} + +func (p OpenPanel) Release() { + C.CFRelease(C.CFTypeRef(p)) +} + +type SavePanel C.NSSavePanelRef + +func NewSavePanel() SavePanel { + return SavePanel(C.newSavePanel()) +} + +func (p SavePanel) DirectoryURL() URL { + return URL(C.savePanelDirectoryURL(C.NSSavePanelRef(p))) +} + +func (p SavePanel) SetDirectoryURL(url URL) { + C.savePanelSetDirectoryURL(C.NSSavePanelRef(p), C.CFURLRef(url)) +} + +func (p SavePanel) AllowedFileTypes() Array { + return Array(C.savePanelAllowedFileTypes(C.NSSavePanelRef(p))) +} + +func (p SavePanel) SetAllowedFileTypes(types Array) { + C.savePanelSetAllowedFileTypes(C.NSSavePanelRef(p), C.CFArrayRef(types)) +} + +func (p SavePanel) URL() URL { + return URL(C.savePanelURL(C.NSSavePanelRef(p))) +} + +func (p SavePanel) RunModal() bool { + return bool(C.savePanelRunModal(C.NSSavePanelRef(p))) +} + +func (p SavePanel) Release() { + C.CFRelease(C.CFTypeRef(p)) +} + +type Window C.NSWindowRef + +func (w Window) ContentView() View { + return View(C.windowContentView(C.NSWindowRef(w))) +} + +type View C.NSViewRef + +func (v View) Frame() geom32.Rect { + var frame C.NSRect + C.viewFrame(C.NSViewRef(v), &frame) + return geom32.Rect{ + Point: geom32.Point{ + X: float32(frame.origin.x), + Y: float32(frame.origin.y), + }, + Size: geom32.Size{ + Width: float32(frame.size.width), + Height: float32(frame.size.height), + }, + } +} + +func IsDarkModeEnabled() bool { + if style := C.CFPreferencesCopyAppValue(C.CFStringRef(NewString("AppleInterfaceStyle")), + C.kCFPreferencesCurrentApplication); style != 0 { + s := String(style) + str := s.String() + s.Release() + return strings.Contains(strings.ToLower(str), "dark") + } + return false +} + +type Menu C.NSMenuRef + +func NewMenu(title string, updater func(Menu)) Menu { + s := NewString(title) + m := Menu(C.newMenu(C.CFStringRef(s))) + s.Release() + if updater != nil { + menuUpdaters[m] = updater + } + return m +} + +func (m Menu) NumberOfItems() int { + return int(C.menuNumberOfItems(C.NSMenuRef(m))) +} + +func (m Menu) ItemAtIndex(index int) MenuItem { + return MenuItem(C.menuItemAtIndex(C.NSMenuRef(m), C.int(index))) +} + +func (m Menu) InsertItemAtIndex(item MenuItem, index int) { + C.menuInsertItemAtIndex(C.NSMenuRef(m), C.NSMenuItemRef(item), C.int(index)) +} + +func (m Menu) RemoveItemAtIndex(index int) { + C.menuRemoveItemAtIndex(C.NSMenuRef(m), C.int(index)) +} + +func (m Menu) Title() string { + return String(C.menuTitle(C.NSMenuRef(m))).String() +} + +func (m Menu) Popup(wnd Window, menu Menu, item MenuItem, bounds geom32.Rect) { + C.menuPopup(C.NSWindowRef(wnd), C.NSMenuRef(menu), C.NSMenuItemRef(item), C.CGRect{ + origin: C.CGPoint{ + x: C.double(bounds.X), + y: C.double(bounds.Y), + }, + size: C.CGSize{ + width: C.double(bounds.Width), + height: C.double(bounds.Height), + }, + }) +} + +func (m Menu) Release() { + delete(menuUpdaters, m) + for i := m.NumberOfItems() - 1; i >= 0; i-- { + item := m.ItemAtIndex(i) + delete(menuItemValidators, item) + delete(menuItemHandlers, item) + } + C.CFRelease(C.CFTypeRef(m)) +} + +type MenuItem C.NSMenuItemRef + +func NewMenuItem(tag int, title string, keyEquivalent string, modifiers EventModifierFlags, validator func(MenuItem) bool, handler func(MenuItem)) MenuItem { + titleStr := NewString(title) + keyStr := NewString(keyEquivalent) + item := MenuItem(C.newMenuItem(C.int(tag), C.CFStringRef(titleStr), C.CFStringRef(keyStr), C.NSEventModifierFlags(modifiers))) + titleStr.Release() + keyStr.Release() + if validator != nil { + menuItemValidators[item] = validator + } + if handler != nil { + menuItemHandlers[item] = handler + } + return item +} + +func NewSeparatorMenuItem() MenuItem { + return MenuItem(C.newMenuSeparatorItem()) +} + +func (m MenuItem) Tag() int { + return int(C.menuItemTag(C.NSMenuItemRef(m))) +} + +func (m MenuItem) IsSeparatorItem() bool { + return bool(C.menuItemIsSeparator(C.NSMenuItemRef(m))) +} + +func (m MenuItem) Title() string { + return String(C.menuItemTitle(C.NSMenuItemRef(m))).String() +} + +func (m MenuItem) SetTitle(title string) { + titleStr := NewString(title) + C.menuItemSetTitle(C.NSMenuItemRef(m), C.CFStringRef(titleStr)) + titleStr.Release() +} + +func (m MenuItem) Menu() Menu { + return Menu(C.menuItemMenu(C.NSMenuItemRef(m))) +} + +func (m MenuItem) SubMenu() Menu { + return Menu(C.menuItemSubMenu(C.NSMenuItemRef(m))) +} + +func (m MenuItem) SetSubMenu(menu Menu) { + C.menuItemSetSubMenu(C.NSMenuItemRef(m), C.NSMenuRef(menu)) +} + +func (m MenuItem) State() ControlStateValue { + return ControlStateValue(C.menuItemState(C.NSMenuItemRef(m))) +} + +func (m MenuItem) SetState(state ControlStateValue) { + C.menuItemSetState(C.NSMenuItemRef(m), C.NSControlStateValue(state)) +} + +type ActivationPolicy uint + +const ( + ActivationPolicyRegular ActivationPolicy = iota + ActivationPolicyAccessory + ActivationPolicyProhibited +) + +func HideApplication() { + C.hideRunningApplication() +} + +func HideOtherApplications() { + C.hideOtherApplications() +} + +func UnhideAllApplications() { + C.unhideAllApplications() +} + +func SetActivationPolicy(policy ActivationPolicy) { + C.setActivationPolicy(C.NSApplicationActivationPolicy(policy)) +} + +func SetMainMenu(menu Menu) { + C.setMainMenu(C.NSMenuRef(menu)) +} + +func SetServicesMenu(menu Menu) { + C.setServicesMenu(C.NSMenuRef(menu)) +} + +func SetWindowsMenu(menu Menu) { + C.setWindowsMenu(C.NSMenuRef(menu)) +} + +func SetHelpMenu(menu Menu) { + C.setHelpMenu(C.NSMenuRef(menu)) +} diff --git a/internal/ns/open_panel_darwin.go b/internal/ns/open_panel_darwin.go deleted file mode 100644 index e63ae95..0000000 --- a/internal/ns/open_panel_darwin.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright ©2021 by Richard A. Wilkes. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with -// this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// This Source Code Form is "Incompatible With Secondary Licenses", as -// defined by the Mozilla Public License, version 2.0. - -package ns - -import "github.com/progrium/macdriver/objc" - -var openPanelClass = objc.Get("NSOpenPanel") - -// OpenPanel https://developer.apple.com/documentation/appkit/nsopenpanel?language=objc -type OpenPanel struct { - SavePanel -} - -// NewOpenPanel https://developer.apple.com/documentation/appkit/nsopenpanel/1584365-openpanel?language=objc -func NewOpenPanel() OpenPanel { - return OpenPanel{SavePanel: SavePanel{Object: openPanelClass.Send("openPanel")}} -} - -// CanChooseFiles https://developer.apple.com/documentation/appkit/nsopenpanel/1527060-canchoosefiles?language=objc -func (p OpenPanel) CanChooseFiles() bool { - return p.Send("canChooseFiles").Bool() -} - -// SetCanChooseFiles https://developer.apple.com/documentation/appkit/nsopenpanel/1527060-canchoosefiles?language=objc -func (p OpenPanel) SetCanChooseFiles(set bool) { - p.Send("setCanChooseFiles:", set) -} - -// CanChooseDirectories https://developer.apple.com/documentation/appkit/nsopenpanel/1532668-canchoosedirectories?language=objc -func (p OpenPanel) CanChooseDirectories() bool { - return p.Send("canChooseDirectories").Bool() -} - -// SetCanChooseDirectories https://developer.apple.com/documentation/appkit/nsopenpanel/1532668-canchoosedirectories?language=objc -func (p OpenPanel) SetCanChooseDirectories(set bool) { - p.Send("setCanChooseDirectories:", set) -} - -// ResolvesAliases https://developer.apple.com/documentation/appkit/nsopenpanel/1533625-resolvesaliases?language=objc -func (p OpenPanel) ResolvesAliases() bool { - return p.Send("resolvesAliases").Bool() -} - -// SetResolvesAliases https://developer.apple.com/documentation/appkit/nsopenpanel/1533625-resolvesaliases?language=objc -func (p OpenPanel) SetResolvesAliases(set bool) { - p.Send("setResolvesAliases:", set) -} - -// AllowsMultipleSelection https://developer.apple.com/documentation/appkit/nsopenpanel/1530786-allowsmultipleselection?language=objc -func (p OpenPanel) AllowsMultipleSelection() bool { - return p.Send("allowsMultipleSelection").Bool() -} - -// SetAllowsMultipleSelection https://developer.apple.com/documentation/appkit/nsopenpanel/1530786-allowsmultipleselection?language=objc -func (p OpenPanel) SetAllowsMultipleSelection(set bool) { - p.Send("setAllowsMultipleSelection:", set) -} - -// URLs https://developer.apple.com/documentation/appkit/nsopenpanel/1529845-urls?language=objc -func (p OpenPanel) URLs() Array { - return Array{Object: p.Send("URLs")} -} diff --git a/internal/ns/popup_button_cell_darwin.go b/internal/ns/popup_button_cell_darwin.go deleted file mode 100644 index 1c56d71..0000000 --- a/internal/ns/popup_button_cell_darwin.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright ©2021 by Richard A. Wilkes. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with -// this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// This Source Code Form is "Incompatible With Secondary Licenses", as -// defined by the Mozilla Public License, version 2.0. - -package ns - -import ( - "github.com/progrium/macdriver/objc" -) - -var popupButtonCellClass = objc.Get("NSPopUpButtonCell") - -// PopupButtonCell https://developer.apple.com/documentation/appkit/nspopupbuttoncell?language=objc -type PopupButtonCell struct { - objc.Object -} - -// NewPopupButtonCell https://developer.apple.com/documentation/appkit/nspopupbuttoncell/1528591-inittextcell?language=objc -func NewPopupButtonCell(text string, pullsDown bool) PopupButtonCell { - textStr := StringFromString(text) - defer textStr.Release() - return PopupButtonCell{Object: popupButtonCellClass.Alloc().Send("initTextCell:pullsDown:", textStr, pullsDown)} -} - -// SetAutoEnablesItems https://developer.apple.com/documentation/appkit/nspopupbuttoncell/1530889-autoenablesitems?language=objc -func (p PopupButtonCell) SetAutoEnablesItems(enabled bool) { - p.Send("setAutoenablesItems:", enabled) -} - -// SetAltersStateOfSelectedItem https://developer.apple.com/documentation/appkit/nspopupbuttoncell/1528446-altersstateofselecteditem?language=objc -func (p PopupButtonCell) SetAltersStateOfSelectedItem(enabled bool) { - p.Send("setAltersStateOfSelectedItem:", enabled) -} - -// SetMenu https://developer.apple.com/documentation/appkit/nspopupbuttoncell/1529059-menu?language=objc -func (p PopupButtonCell) SetMenu(menu Menu) { - p.Send("setMenu:", menu) -} - -// SelectItem https://developer.apple.com/documentation/appkit/nspopupbuttoncell/1525225-selectitem?language=objc -func (p PopupButtonCell) SelectItem(menuItem MenuItem) { - p.Send("selectItem:", menuItem) -} - -// PerformClickWithFrameInView https://developer.apple.com/documentation/appkit/nspopupbuttoncell/1530205-performclickwithframe?language=objc -func (p PopupButtonCell) PerformClickWithFrameInView(frame Rect, view View) { - p.Send("performClickWithFrame:inView:", frame, view) -} diff --git a/internal/ns/rect_darwin.go b/internal/ns/rect_darwin.go deleted file mode 100644 index 583322e..0000000 --- a/internal/ns/rect_darwin.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright ©2021 by Richard A. Wilkes. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with -// this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// This Source Code Form is "Incompatible With Secondary Licenses", as -// defined by the Mozilla Public License, version 2.0. - -package ns - -// Point https://developer.apple.com/documentation/foundation/nspoint?language=objc -type Point struct { - X float64 - Y float64 -} - -// MakePoint https://developer.apple.com/documentation/foundation/1391309-nsmakepoint?language=objc -func MakePoint(x, y float64) Point { - return Point{X: x, Y: y} -} - -// Size https://developer.apple.com/documentation/foundation/nssize?language=objc -type Size struct { - Width float64 - Height float64 -} - -// MakeSize https://developer.apple.com/documentation/foundation/1391295-nsmakesize?language=objc -func MakeSize(w, h float64) Size { - return Size{Width: w, Height: h} -} - -// Rect https://developer.apple.com/documentation/foundation/nsrect?language=objc -type Rect struct { - Origin Point - Size Size -} - -// MakeRect https://developer.apple.com/documentation/foundation/1391329-nsmakerect?language=objc -func MakeRect(x, y, w, h float64) Rect { - return Rect{Origin: MakePoint(x, y), Size: MakeSize(w, h)} -} diff --git a/internal/ns/running_application_darwin.go b/internal/ns/running_application_darwin.go deleted file mode 100644 index 8df623c..0000000 --- a/internal/ns/running_application_darwin.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright ©2021 by Richard A. Wilkes. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with -// this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// This Source Code Form is "Incompatible With Secondary Licenses", as -// defined by the Mozilla Public License, version 2.0. - -package ns - -import "github.com/progrium/macdriver/objc" - -var runningApplicationClass = objc.Get("NSRunningApplication") - -// RunningApplication https://developer.apple.com/documentation/appkit/nsrunningapplication?language=objc -type RunningApplication struct { - objc.Object -} - -// CurrentApplication https://developer.apple.com/documentation/appkit/nsrunningapplication/1533604-currentapplication?language=objc -func CurrentApplication() RunningApplication { - return RunningApplication{Object: runningApplicationClass.Send("currentApplication")} -} - -// Hide https://developer.apple.com/documentation/appkit/nsrunningapplication/1526608-hide?language=objc -func (a RunningApplication) Hide() { - a.Send("hide") -} diff --git a/internal/ns/save_panel_darwin.go b/internal/ns/save_panel_darwin.go deleted file mode 100644 index 22a076a..0000000 --- a/internal/ns/save_panel_darwin.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright ©2021 by Richard A. Wilkes. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with -// this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// This Source Code Form is "Incompatible With Secondary Licenses", as -// defined by the Mozilla Public License, version 2.0. - -package ns - -import "github.com/progrium/macdriver/objc" - -var savePanelClass = objc.Get("NSSavePanel") - -// SavePanel https://developer.apple.com/documentation/appkit/nssavepanel?language=objc -type SavePanel struct { - objc.Object -} - -// NewSavePanel https://developer.apple.com/documentation/appkit/nssavepanel/1539016-savepanel?language=objc -func NewSavePanel() SavePanel { - return SavePanel{Object: savePanelClass.Send("savePanel")} -} - -// DirectoryURL https://developer.apple.com/documentation/appkit/nssavepanel/1531279-directoryurl?language=objc -func (p SavePanel) DirectoryURL() URL { - return URL{Object: p.Send("directoryURL")} -} - -// SetDirectoryURL https://developer.apple.com/documentation/appkit/nssavepanel/1531279-directoryurl?language=objc -func (p SavePanel) SetDirectoryURL(url URL) { - p.Send("setDirectoryURL:", url) -} - -// AllowedFileTypes https://developer.apple.com/documentation/appkit/nssavepanel/1534419-allowedfiletypes?language=objc -func (p SavePanel) AllowedFileTypes() Array { - return Array{Object: p.Send("allowedFiledTypes")} -} - -// SetAllowedFileTypes https://developer.apple.com/documentation/appkit/nssavepanel/1534419-allowedfiletypes?language=objc -func (p SavePanel) SetAllowedFileTypes(types Array) { - p.Send("setAllowedFileTypes:", types) -} - -// URL https://developer.apple.com/documentation/appkit/nssavepanel/1534384-url?language=objc -func (p SavePanel) URL() URL { - return URL{Object: p.Send("URL")} -} - -// RunModal https://developer.apple.com/documentation/appkit/nssavepanel/1525357-runmodal?language=objc -func (p SavePanel) RunModal() int { - return int(p.Send("runModal").Int()) -} diff --git a/internal/ns/string_darwin.go b/internal/ns/string_darwin.go deleted file mode 100644 index c7cd786..0000000 --- a/internal/ns/string_darwin.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright ©2021 by Richard A. Wilkes. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with -// this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// This Source Code Form is "Incompatible With Secondary Licenses", as -// defined by the Mozilla Public License, version 2.0. - -package ns - -import ( - "reflect" - "unsafe" - - "github.com/progrium/macdriver/objc" -) - -// utf8StringEncoding https://developer.apple.com/documentation/foundation/1497293-string_encodings/nsutf8stringencoding?language=occ -const utf8StringEncoding = 4 - -var stringClass = objc.Get("NSString") - -// String https://developer.apple.com/documentation/foundation/nsstring?language=occ -type String struct { - objc.Object -} - -// StringFromString returns a String created by copying the data from the given string. -func StringFromString(str string) String { - hdr := (*reflect.StringHeader)(unsafe.Pointer(&str)) - return String{Object: stringClass.Alloc().Send("initWithBytes:length:encoding:", hdr.Data, hdr.Len, - utf8StringEncoding)} -} diff --git a/internal/ns/url_darwin.go b/internal/ns/url_darwin.go deleted file mode 100644 index 4ef4cf8..0000000 --- a/internal/ns/url_darwin.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright ©2021 by Richard A. Wilkes. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with -// this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// This Source Code Form is "Incompatible With Secondary Licenses", as -// defined by the Mozilla Public License, version 2.0. - -package ns - -import "github.com/progrium/macdriver/objc" - -var urlClass = objc.Get("NSURL") - -// URL https://developer.apple.com/documentation/foundation/nsurl?language=objc -type URL struct { - objc.Object -} - -// NewFileURL https://developer.apple.com/documentation/foundation/nsurl/1414650-fileurlwithpath?language=objc -func NewFileURL(str string) URL { - s := StringFromString(str) - defer s.Release() - return URL{Object: urlClass.Send("fileURLWithPath:", s)} -} - -// AbsoluteString https://developer.apple.com/documentation/foundation/nsurl/1409868-absolutestring?language=objc -func (u URL) AbsoluteString() string { - return u.Send("absoluteURL").String() -} diff --git a/internal/ns/user_defaults_darwin.go b/internal/ns/user_defaults_darwin.go deleted file mode 100644 index 5554420..0000000 --- a/internal/ns/user_defaults_darwin.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright ©2021 by Richard A. Wilkes. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with -// this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// This Source Code Form is "Incompatible With Secondary Licenses", as -// defined by the Mozilla Public License, version 2.0. - -package ns - -import "github.com/progrium/macdriver/objc" - -var userDefaultsClass = objc.Get("NSUserDefaults") - -// UserDefaults https://developer.apple.com/documentation/foundation/nsuserdefaults/ -type UserDefaults struct { - objc.Object -} - -// StandardUserDefaults https://developer.apple.com/documentation/foundation/nsuserdefaults/1416603-standarduserdefaults -func StandardUserDefaults() UserDefaults { - return UserDefaults{Object: userDefaultsClass.Send("standardUserDefaults")} -} - -// StringForKey https://developer.apple.com/documentation/foundation/nsuserdefaults/1416700-stringforkey -func (u UserDefaults) StringForKey(key string) string { - keyString := StringFromString(key) - defer keyString.Release() - return u.Send("stringForKey:", keyString).String() -} diff --git a/internal/ns/util_darwin.go b/internal/ns/util_darwin.go deleted file mode 100644 index 5543ad1..0000000 --- a/internal/ns/util_darwin.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright ©2021 by Richard A. Wilkes. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with -// this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// This Source Code Form is "Incompatible With Secondary Licenses", as -// defined by the Mozilla Public License, version 2.0. - -package ns - -import ( - "net/url" - - "github.com/richardwilkes/toolbox/errs" - "github.com/richardwilkes/toolbox/log/jot" -) - -// StringSliceToArray converts a slice of Go strings into an NSArray of NSString. -func StringSliceToArray(slice []string) Array { - a := MutableArrayWithCapacity(len(slice)) - for _, s := range slice { - str := StringFromString(s) - a.AddObject(str) - str.Release() - } - return a.Array -} - -// StringArrayToSlice converts an NSArray of NSString into a slice of Go strings. -func StringArrayToSlice(array Array) []string { - count := array.Count() - result := make([]string, 0, count) - for i := 0; i < count; i++ { - result = append(result, array.StringAtIndex(i).String()) - } - return result -} - -// URLArrayToStringSlice converts an NSArray of NSURL into a slice of Go strings. -func URLArrayToStringSlice(array Array) []string { - count := array.Count() - result := make([]string, 0, count) - for i := 0; i < count; i++ { - u, err := url.Parse(URL{Object: array.ObjectAtIndex(i)}.AbsoluteString()) - if err != nil { - jot.Warn(errs.NewWithCause("unable to parse URL", err)) - continue - } - result = append(result, u.Path) - } - return result -} diff --git a/internal/ns/view_darwin.go b/internal/ns/view_darwin.go deleted file mode 100644 index 7155f2f..0000000 --- a/internal/ns/view_darwin.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright ©2021 by Richard A. Wilkes. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with -// this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// This Source Code Form is "Incompatible With Secondary Licenses", as -// defined by the Mozilla Public License, version 2.0. - -package ns - -import "github.com/progrium/macdriver/objc" - -// View https://developer.apple.com/documentation/appkit/nsview?language=objc -type View struct { - objc.Object -} - -// Frame https://developer.apple.com/documentation/appkit/nsview/1483713-frame?language=objc -func (v View) Frame() Rect { - var frame Rect - v.Send("frame", &frame) - return frame -} diff --git a/internal/ns/window_darwin.go b/internal/ns/window_darwin.go deleted file mode 100644 index 4f1a9b1..0000000 --- a/internal/ns/window_darwin.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright ©2021 by Richard A. Wilkes. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with -// this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// This Source Code Form is "Incompatible With Secondary Licenses", as -// defined by the Mozilla Public License, version 2.0. - -package ns - -import "github.com/progrium/macdriver/objc" - -// Window https://developer.apple.com/documentation/appkit/nswindow?language=objc -type Window struct { - objc.Object -} - -// ContentView https://developer.apple.com/documentation/appkit/nswindow/1419160-contentview?language=objc -func (w Window) ContentView() View { - return View{Object: w.Send("contentView")} -} diff --git a/internal/skia/libskia_darwin.a b/internal/skia/libskia_darwin_amd64.a similarity index 62% rename from internal/skia/libskia_darwin.a rename to internal/skia/libskia_darwin_amd64.a index 4996995..74fa18a 100644 Binary files a/internal/skia/libskia_darwin.a and b/internal/skia/libskia_darwin_amd64.a differ diff --git a/internal/skia/libskia_darwin_arm64.a b/internal/skia/libskia_darwin_arm64.a new file mode 100644 index 0000000..72979b6 Binary files /dev/null and b/internal/skia/libskia_darwin_arm64.a differ diff --git a/internal/skia/sk_capi.h b/internal/skia/sk_capi.h index df656ec..58ec07e 100644 --- a/internal/skia/sk_capi.h +++ b/internal/skia/sk_capi.h @@ -346,7 +346,8 @@ typedef enum { SK_COLOR_TYPE_R16G16_UNORM, // pixel with a little endian uint16_t for red and green SK_COLOR_TYPE_R16G16B16A16_UNORM, // pixel with a little endian uint16_t for red, green, blue and alpha - SK_COLOR_TYPE_LAST = SK_COLOR_TYPE_R16G16B16A16_UNORM, + SK_COLOR_TYPE_SRGBA_8888, // pixel with 8 bits for red, green, blue, alpha; in 32-bit word with conversion between sRGB and linear space + SK_COLOR_TYPE_LAST = SK_COLOR_TYPE_SRGBA_8888, } sk_color_type_t; typedef enum { @@ -430,16 +431,6 @@ typedef struct { sk_mipmap_mode_t mipmap; } sk_sampling_options_t; -// ===== Types from include/core/SkFilterQuality.h ===== - -typedef enum { - SK_FILTER_QUALITY_NONE, // nearest-neighbor; fastest but lowest quality - SK_FILTER_QUALITY_LOW, // bilerp - SK_FILTER_QUALITY_MEDIUM, // bilerp + mipmaps; good for down-scaling - SK_FILTER_QUALITY_HIGH, // bicubic resampling; slowest but good quality - SK_FILTER_QUALITY_LAST = SK_FILTER_QUALITY_HIGH -} sk_filter_quality_t; - // ===== Types from include/core/SkTypeface.h ===== typedef struct sk_typeface_t sk_typeface_t; diff --git a/internal/skia/skia_other.go b/internal/skia/skia_other.go index d3f1efb..921df2b 100644 --- a/internal/skia/skia_other.go +++ b/internal/skia/skia_other.go @@ -13,7 +13,9 @@ package skia /* #cgo CFLAGS: -I${SRCDIR} -#cgo darwin LDFLAGS: -L${SRCDIR} -lskia_darwin -lc++ -framework Cocoa -framework Metal +#cgo darwin LDFLAGS: -L${SRCDIR} -lc++ -framework Cocoa -framework Metal +#cgo darwin,amd64 LDFLAGS: -lskia_darwin_amd64 +#cgo darwin,arm64 LDFLAGS: -lskia_darwin_arm64 #cgo linux LDFLAGS: -L${SRCDIR} -lskia_linux -lfontconfig -lfreetype -lGL -ldl -lm -lstdc++ #include diff --git a/menu_bar_darwin.go b/menu_bar_darwin.go index f320aad..4425db4 100644 --- a/menu_bar_darwin.go +++ b/menu_bar_darwin.go @@ -22,9 +22,9 @@ func platformAddAppMenuEntries(m Menu) { m.InsertMenu(-1, m.Factory().NewMenu(ServicesMenuID, i18n.Text("Services"), nil)) m.InsertSeparator(-1, false) m.InsertItem(-1, m.Factory().NewItem(HideItemID, fmt.Sprintf(i18n.Text("Hide %s"), cmdline.AppName), KeyH, - OSMenuCmdModifier(), nil, func(MenuItem) { ns.CurrentApplication().Hide() })) + OSMenuCmdModifier(), nil, func(MenuItem) { ns.HideApplication() })) m.InsertItem(-1, m.Factory().NewItem(HideOthersItemID, i18n.Text("Hide Others"), KeyH, - OptionModifier|OSMenuCmdModifier(), nil, func(MenuItem) { ns.App().HideOtherApplications() })) + OptionModifier|OSMenuCmdModifier(), nil, func(MenuItem) { ns.HideOtherApplications() })) m.InsertItem(-1, m.Factory().NewItem(ShowAllItemID, i18n.Text("Show All"), KeyNone, NoModifiers, nil, - func(MenuItem) { ns.App().UnhideAllApplications() })) + func(MenuItem) { ns.UnhideAllApplications() })) } diff --git a/menu_darwin.go b/menu_darwin.go index 5260414..e10826c 100644 --- a/menu_darwin.go +++ b/menu_darwin.go @@ -10,7 +10,6 @@ package unison import ( - "github.com/progrium/macdriver/objc" "github.com/richardwilkes/toolbox/xmath/geom32" "github.com/richardwilkes/unison/internal/ns" ) @@ -29,7 +28,7 @@ func (m *macMenu) Factory() MenuFactory { func (m *macMenu) IsSame(other Menu) bool { if m2, ok := other.(*macMenu); ok { - return m.menu.Equals(m2.menu) + return m.menu == m2.menu } return false } @@ -112,13 +111,13 @@ func (m *macMenu) insertMenu(atIndex int, subMenu *macMenu) { case AppMenuID: if servicesItem := m.Item(ServicesMenuID); servicesItem != nil { if servicesMenu := servicesItem.SubMenu(); servicesMenu != nil { - ns.App().SetServicesMenu(servicesMenu.(*macMenu).menu) + ns.SetServicesMenu(servicesMenu.(*macMenu).menu) } } case WindowMenuID: - ns.App().SetWindowsMenu(subMenu.menu) + ns.SetWindowsMenu(subMenu.menu) case HelpMenuID: - ns.App().SetHelpMenu(subMenu.menu) + ns.SetHelpMenu(subMenu.menu) } } @@ -144,18 +143,12 @@ func (m *macMenu) Popup(where geom32.Rect, itemIndex int) { w := ActiveWindow() if w.IsValid() { if mi := m.ItemAtIndex(itemIndex); mi != nil { - view := ns.Window{Object: objc.ObjectPtr(uintptr(w.wnd.GetCocoaWindow()))}.ContentView() + wnd := ns.Window(w.wnd.GetCocoaWindow()) + view := wnd.ContentView() frame := view.Frame() where.X += 8 - where.Y = float32(frame.Size.Height) - where.Bottom() - cell := ns.NewPopupButtonCell("", false) - cell.SetAutoEnablesItems(false) - cell.SetAltersStateOfSelectedItem(false) - cell.SetMenu(m.menu) - cell.SelectItem(mi.(*macMenuItem).item) - cell.PerformClickWithFrameInView(ns.MakeRect(float64(where.X), float64(where.Y), float64(where.Width), - float64(where.Height)), view) - cell.Release() + where.Y = frame.Height - where.Bottom() + m.menu.Popup(wnd, m.menu, m.menu.ItemAtIndex(itemIndex), where) } } } diff --git a/menu_factory_darwin.go b/menu_factory_darwin.go index f53fe8b..dabedeb 100644 --- a/menu_factory_darwin.go +++ b/menu_factory_darwin.go @@ -10,58 +10,22 @@ package unison import ( - "github.com/progrium/macdriver/objc" "github.com/richardwilkes/unison/internal/ns" ) type macMenuFactory struct { - bar *macMenu - menuDelegate objc.Object - menuUpdaterMap map[uintptr]func(Menu) - menuItemDelegate objc.Object - menuItemValidatorMap map[int]func(MenuItem) bool - menuItemHandlerMap map[int]func(MenuItem) - handleMenuItemSelector objc.Selector + bar *macMenu } func platformNewDefaultMenuFactory() MenuFactory { - f := &macMenuFactory{ - menuUpdaterMap: make(map[uintptr]func(Menu)), - menuItemValidatorMap: make(map[int]func(MenuItem) bool), - menuItemHandlerMap: make(map[int]func(MenuItem)), - handleMenuItemSelector: objc.Sel("handleMenuItem:"), - } - cls := objc.NewClass("MenuDelegate", "NSObject") - cls.AddMethod("menuNeedsUpdate:", func(_, obj objc.Object) { - m := ns.Menu{Object: obj} - if updater, ok := f.menuUpdaterMap[m.Pointer()]; ok { - updater(&macMenu{factory: f, menu: m}) - } - }) - f.menuDelegate = cls.Alloc().Init() - cls = objc.NewClass("MenuItemDelegate", "NSObject") - cls.AddMethod("validateMenuItem:", func(_, obj objc.Object) bool { - mi := ns.MenuItem{Object: obj} - if validator, ok := f.menuItemValidatorMap[mi.Tag()]; ok { - return validator(&macMenuItem{factory: f, item: mi}) - } - return true - }) - cls.AddMethod("handleMenuItem:", func(_, obj objc.Object) { - mi := ns.MenuItem{Object: obj} - if handler, ok := f.menuItemHandlerMap[mi.Tag()]; ok { - handler(&macMenuItem{factory: f, item: mi}) - } - }) - f.menuItemDelegate = cls.Alloc().Init() - return f + return &macMenuFactory{} } func (f *macMenuFactory) BarForWindow(window *Window, initializer func(Menu)) Menu { if f.bar == nil { f.bar = f.newMenu(RootMenuID, "", nil) initializer(f.bar) - InvokeTask(func() { ns.App().SetMainMenu(f.bar.menu) }) + InvokeTask(func() { ns.SetMainMenu(f.bar.menu) }) } return f.bar } @@ -75,11 +39,13 @@ func (f *macMenuFactory) NewMenu(id int, title string, updater func(Menu)) Menu } func (f *macMenuFactory) newMenu(id int, title string, updater func(Menu)) *macMenu { - m := ns.NewMenu(title) - m.SetDelegate(f.menuDelegate) + var u func(ns.Menu) if updater != nil { - f.menuUpdaterMap[m.Pointer()] = updater + u = func(m ns.Menu) { + updater(&macMenu{factory: f, menu: m}) + } } + m := ns.NewMenu(title, u) return &macMenu{ factory: f, id: id, @@ -88,8 +54,6 @@ func (f *macMenuFactory) newMenu(id int, title string, updater func(Menu)) *macM } func (f *macMenuFactory) NewItem(id int, title string, keyCode KeyCode, keyModifiers Modifiers, validator func(MenuItem) bool, handler func(MenuItem)) MenuItem { - mi := ns.NewMenuItem(title, f.handleMenuItemSelector, macKeyCodeToMenuEquivalentMap[keyCode]) - mi.SetTag(id) var mods ns.EventModifierFlags if keyModifiers.ShiftDown() { mods |= ns.EventModifierFlagShift @@ -106,18 +70,19 @@ func (f *macMenuFactory) NewItem(id int, title string, keyCode KeyCode, keyModif if keyModifiers.CapsLockDown() { mods |= ns.EventModifierFlagCapsLock } - mi.SetKeyEquivalentModifierMask(mods) - mi.SetTarget(f.menuItemDelegate) + var v func(ns.MenuItem) bool if validator != nil { - f.menuItemValidatorMap[id] = validator - } else { - delete(f.menuItemValidatorMap, id) + v = func(mi ns.MenuItem) bool { + return validator(&macMenuItem{factory: f, item: mi}) + } } + var h func(ns.MenuItem) if handler != nil { - f.menuItemHandlerMap[id] = handler - } else { - delete(f.menuItemHandlerMap, id) + h = func(mi ns.MenuItem) { + handler(&macMenuItem{factory: f, item: mi}) + } } + mi := ns.NewMenuItem(id, title, macKeyCodeToMenuEquivalentMap[keyCode], mods, v, h) return &macMenuItem{ factory: f, item: mi, diff --git a/menu_item_darwin.go b/menu_item_darwin.go index f325e84..f54a7ac 100644 --- a/menu_item_darwin.go +++ b/menu_item_darwin.go @@ -21,9 +21,7 @@ type macMenuItem struct { } func newMacMenuItemForSubMenu(f *macMenuFactory, subMenu *macMenu) ns.MenuItem { - mi := ns.NewMenuItem(subMenu.Title(), f.handleMenuItemSelector, "") - mi.SetTag(subMenu.id) - mi.SetTarget(f.menuItemDelegate) + mi := ns.NewMenuItem(subMenu.id, subMenu.Title(), "", 0, nil, nil) mi.SetSubMenu(subMenu.menu) return mi } @@ -38,14 +36,14 @@ func (mi *macMenuItem) ID() int { func (mi *macMenuItem) IsSame(other MenuItem) bool { if mi2, ok := other.(*macMenuItem); ok { - return mi.item.Equals(mi2.item) + return mi.item == mi2.item } return false } func (mi *macMenuItem) Menu() Menu { m := mi.item.Menu() - if m.Pointer() == 0 { + if m == 0 { return nil } return &macMenu{ @@ -81,7 +79,7 @@ func (mi *macMenuItem) SetTitle(title string) { func (mi *macMenuItem) SubMenu() Menu { subMenu := mi.item.SubMenu() - if subMenu.Pointer() == 0 { + if subMenu == 0 { return nil } return &macMenu{ diff --git a/open_dialog_darwin.go b/open_dialog_darwin.go index b9fdb99..9462814 100644 --- a/open_dialog_darwin.go +++ b/open_dialog_darwin.go @@ -10,7 +10,9 @@ package unison import ( + "fmt" "net/url" + "runtime" "github.com/richardwilkes/toolbox/errs" "github.com/richardwilkes/toolbox/log/jot" @@ -22,7 +24,14 @@ type macOpenDialog struct { } func platformNewOpenDialog() OpenDialog { - return &macOpenDialog{dialog: ns.NewOpenPanel()} + d := &macOpenDialog{dialog: ns.NewOpenPanel()} + runtime.SetFinalizer(d, func(obj *macOpenDialog) { + ReleaseOnUIThread(func() { + fmt.Println("release") + obj.dialog.Release() + }) + }) + return d } func (d *macOpenDialog) InitialDirectory() string { @@ -43,15 +52,15 @@ func (d *macOpenDialog) SetInitialDirectory(dir string) { func (d *macOpenDialog) AllowedExtensions() []string { allowed := d.dialog.AllowedFileTypes() defer allowed.Release() - return ns.StringArrayToSlice(allowed) + return allowed.ArrayOfStringToStringSlice() } func (d *macOpenDialog) SetAllowedExtensions(types ...string) { types = SanitizeExtensionList(types) if len(types) != 0 { - d.dialog.SetAllowedFileTypes(ns.StringSliceToArray(types)) + d.dialog.SetAllowedFileTypes(ns.NewArrayFromStringSlice(types)) } else { - d.dialog.SetAllowedFileTypes(ns.Array{}) + d.dialog.SetAllowedFileTypes(0) } } @@ -96,7 +105,7 @@ func (d *macOpenDialog) Path() string { } func (d *macOpenDialog) Paths() []string { - return ns.URLArrayToStringSlice(d.dialog.URLs()) + return d.dialog.URLs().ArrayOfURLToStringSlice() } func (d *macOpenDialog) RunModal() bool { @@ -105,5 +114,5 @@ func (d *macOpenDialog) RunModal() bool { if active != nil && active.IsVisible() { active.ToFront() } - return result == 1 + return result } diff --git a/save_dialog_darwin.go b/save_dialog_darwin.go index bda7d78..aca66dd 100644 --- a/save_dialog_darwin.go +++ b/save_dialog_darwin.go @@ -11,6 +11,7 @@ package unison import ( "net/url" + "runtime" "github.com/richardwilkes/toolbox/errs" "github.com/richardwilkes/toolbox/log/jot" @@ -22,7 +23,13 @@ type macSaveDialog struct { } func platformNewSaveDialog() SaveDialog { - return &macSaveDialog{dialog: ns.NewSavePanel()} + d := &macSaveDialog{dialog: ns.NewSavePanel()} + runtime.SetFinalizer(d, func(obj *macSaveDialog) { + ReleaseOnUIThread(func() { + obj.dialog.Release() + }) + }) + return d } func (d *macSaveDialog) InitialDirectory() string { @@ -43,15 +50,15 @@ func (d *macSaveDialog) SetInitialDirectory(dir string) { func (d *macSaveDialog) AllowedExtensions() []string { allowed := d.dialog.AllowedFileTypes() defer allowed.Release() - return ns.StringArrayToSlice(allowed) + return allowed.ArrayOfStringToStringSlice() } func (d *macSaveDialog) SetAllowedExtensions(types ...string) { types = SanitizeExtensionList(types) if len(types) != 0 { - d.dialog.SetAllowedFileTypes(ns.StringSliceToArray(types)) + d.dialog.SetAllowedFileTypes(ns.NewArrayFromStringSlice(types)) } else { - d.dialog.SetAllowedFileTypes(ns.Array{}) + d.dialog.SetAllowedFileTypes(0) } } @@ -70,5 +77,5 @@ func (d *macSaveDialog) RunModal() bool { if active != nil && active.IsVisible() { active.ToFront() } - return result == 1 + return result }