Initial MacOS implementation.

This commit is contained in:
Greg 2020-06-26 21:29:29 -04:00
parent 32d429da19
commit 8adb6873d1
10 changed files with 304 additions and 4 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.apk
example/example
example/example.app/Contents/MacOS/example

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleGetInfoString</key>
<string>Example</string>
<key>CFBundleExecutable</key>
<string>example</string>
<key>CFBundleIdentifier</key>
<string>org.gioui</string>
<key>CFBundleName</key>
<string>example</string>
<key>CFBundleIconFile</key>
<string>example.icns</string>
<key>CFBundleShortVersionString</key>
<string>0.01</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>IFMajorVersion</key>
<integer>0</integer>
<key>IFMinorVersion</key>
<integer>1</integer>
</dict>
</plist>

Binary file not shown.

View File

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>files</key>
<dict>
<key>Resources/example.icns</key>
<data>
QIAQ35jRL6fJLHFE72K0wYzeHUU=
</data>
</dict>
<key>files2</key>
<dict>
<key>Resources/example.icns</key>
<dict>
<key>hash2</key>
<data>
DoBwPExI5vZ+IT6hEeHy5hJpWiVq8+4auEoGFwnbmX8=
</data>
</dict>
</dict>
<key>rules</key>
<dict>
<key>^Resources/</key>
<true/>
<key>^Resources/.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^Resources/.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Resources/Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^version.plist$</key>
<true/>
</dict>
<key>rules2</key>
<dict>
<key>.*\.dSYM($|/)</key>
<dict>
<key>weight</key>
<real>11</real>
</dict>
<key>^(.*/)?\.DS_Store$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>2000</real>
</dict>
<key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
<dict>
<key>nested</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^.*</key>
<true/>
<key>^Info\.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^PkgInfo$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^Resources/</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^Resources/.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^Resources/.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Resources/Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^[^/]+$</key>
<dict>
<key>nested</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^embedded\.provisionprofile$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^version\.plist$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
</dict>
</dict>
</plist>

6
example/hello_macos.go Normal file
View File

@ -0,0 +1,6 @@
//go:generate go build
//go:generate cp -f example example.app/Contents/MacOS
//go:generate codesign -s - example.app
package main

4
go.mod
View File

@ -4,9 +4,7 @@ go 1.14
require (
gioui.org v0.0.0-20200619180744-e2f3bbdfc367
git.wow.st/gmp/jni v0.0.0-20200619201040-d0d3f316ae09
git.wow.st/gmp/jni v0.0.0-20200626194017-b74a17279b1f
github.com/esiqveland/notify v0.9.1
github.com/godbus/dbus/v5 v5.0.3
)
replace git.wow.st/gmp/jni => git.wow.st/whereswaldon/jni v0.0.0-20200620152723-b380472956a0

6
go.sum
View File

@ -1,6 +1,12 @@
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
gioui.org v0.0.0-20200619180744-e2f3bbdfc367 h1:uLmvlsenFUA5XkLheXgdQnX3T/oeYzO9aokBrbSsi/w=
gioui.org v0.0.0-20200619180744-e2f3bbdfc367/go.mod h1:jiUwifN9cRl/zmco43aAqh0aV+s9GbhG13KcD+gEpkU=
git.wow.st/gmp/jni v0.0.0-20200619201040-d0d3f316ae09 h1:7RCYJp8PlMO5mPt1yzDriJmAE+QnDfgpJXgoKkp7xxE=
git.wow.st/gmp/jni v0.0.0-20200619201040-d0d3f316ae09/go.mod h1:lfKZKu2afBKJODTFgDNIaBfhq6qmQS0xsS/phLO5Urk=
git.wow.st/gmp/jni v0.0.0-20200623180511-2e7d20a1b472 h1:YlBjj/ZrWg1Vs/h7ibZSXBpX9GUtvZ1ATNUVs+jhcXg=
git.wow.st/gmp/jni v0.0.0-20200623180511-2e7d20a1b472/go.mod h1:+axXBRUTIDlCeE73IKeD/os7LoEnTKdkp8/gQOFjqyo=
git.wow.st/gmp/jni v0.0.0-20200626194017-b74a17279b1f h1:YTUB3a7eS51OBVh2aoEUM4emxDu3Zwee098AJ12t2KU=
git.wow.st/gmp/jni v0.0.0-20200626194017-b74a17279b1f/go.mod h1:+axXBRUTIDlCeE73IKeD/os7LoEnTKdkp8/gQOFjqyo=
git.wow.st/whereswaldon/jni v0.0.0-20200620152723-b380472956a0 h1:+S/LqMv8h+w4LE/3XtAq1roX8OAZ/E6rqsl/EQ1eaK8=
git.wow.st/whereswaldon/jni v0.0.0-20200620152723-b380472956a0/go.mod h1:ro8WfqxHdXc4wFC+3uP98fVT5uZqrq3yQPMV+LjP6MA=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=

107
macos/notify_macos.go Normal file
View File

@ -0,0 +1,107 @@
package macos
//#cgo LDFLAGS: -framework Foundation -framework UserNotifications
/*
#cgo CFLAGS: -x objective-c -fno-objc-arc -fmodules
#pragma clang diagnostic ignored "-Wformat-security"
#import <stdlib.h>
@import Foundation;
@import UserNotifications;
UNUserNotificationCenter *nc;
BOOL enabled;
void setup() {
@autoreleasepool {
NSLog(@"Getting application bundle");
enabled = NO;
NSBundle *main = [NSBundle mainBundle];
if (main.bundleIdentifier == nil) {
NSLog(@"No app bundle.");
return;
}
NSLog(@"Bundle ID: %@", main.bundleIdentifier);
NSLog(@"Getting notification center");
nc = [UNUserNotificationCenter currentNotificationCenter];
NSLog(@"Requesting authorization");
[nc requestAuthorizationWithOptions: UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert completionHandler: ^(BOOL granted, NSError *error){
NSLog(@"Granted = %s", granted?"true":"false");
NSLog(@"Error = %@", error);
enabled = granted;
}];
}
}
NSString*
notify(char *id, char *title, char *content) {
if (enabled != YES) {
return nil;
}
NSString *ret;
@autoreleasepool {
NSLog(@"Creating notification");
UNMutableNotificationContent *note = [[UNMutableNotificationContent alloc] init];
note.title = [[NSString alloc] initWithUTF8String: title];
note.body = [[NSString alloc] initWithUTF8String: content];
NSLog(@"Creating request");
UNNotificationRequest *req = [UNNotificationRequest requestWithIdentifier:@"Gio" content: note trigger:nil];
ret = req.identifier; // FIXME: need to call retain?
NSLog(@"Adding notification request");
[nc addNotificationRequest:req withCompletionHandler: ^(NSError *error) {
NSLog(@"added notification. Error: %@", error);
}];
}
return ret;
}
void
cancel(void *nid) {
[nc removePendingNotificationRequestsWithIdentifiers: @[(NSString*)nid]];
[nc removeDeliveredNotificationsWithIdentifiers: @[(NSString*)nid]];
}
*/
import "C"
import (
"runtime"
"unsafe"
)
func init() {
runtime.LockOSThread()
C.setup()
}
type NotificationChannel struct {
id *C.char
}
func NewNotificationChannel(id string) NotificationChannel {
return NotificationChannel{ id: C.CString(id) }
}
func (c NotificationChannel) Send(title, text string) (*Notification, error) {
return notify(c.id, title, text), nil
}
type Notification C.NSString
func notify(cid *C.char, title, content string) *Notification {
ct := C.CString(title)
defer C.free(unsafe.Pointer(ct))
cc := C.CString(content)
defer C.free(unsafe.Pointer(cc))
id := C.notify(cid, ct, cc)
return (*Notification)(id)
}
func (n *Notification) Cancel() error {
C.cancel(unsafe.Pointer(n))
return nil
}

26
niotify_macos.go Normal file
View File

@ -0,0 +1,26 @@
package niotify
import (
"git.sr.ht/~whereswaldon/niotify/macos"
)
type macosManager struct {
channel macos.NotificationChannel
}
func newManager() (Manager, error) {
c := macos.NewNotificationChannel("Gio App")
return Manager{
&macosManager{ channel: c },
}, nil
}
func (a *macosManager) CreateNotification(title, text string) (*Notification, error) {
notification, err := a.channel.Send(title, text)
if err != nil {
return nil, err
}
return &Notification{notification}, nil
}

View File

@ -1,4 +1,4 @@
//+build !linux,!android
//+build !linux,!android,!darwin
package niotify