Initial MacOS implementation.
This commit is contained in:
parent
32d429da19
commit
8adb6873d1
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
*.apk
|
||||||
|
example/example
|
||||||
|
example/example.app/Contents/MacOS/example
|
26
example/example.app/Contents/Info.plist
Normal file
26
example/example.app/Contents/Info.plist
Normal 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>
|
BIN
example/example.app/Contents/Resources/example.icns
Normal file
BIN
example/example.app/Contents/Resources/example.icns
Normal file
Binary file not shown.
128
example/example.app/Contents/_CodeSignature/CodeResources
Normal file
128
example/example.app/Contents/_CodeSignature/CodeResources
Normal 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
6
example/hello_macos.go
Normal 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
4
go.mod
|
@ -4,9 +4,7 @@ go 1.14
|
||||||
|
|
||||||
require (
|
require (
|
||||||
gioui.org v0.0.0-20200619180744-e2f3bbdfc367
|
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/esiqveland/notify v0.9.1
|
||||||
github.com/godbus/dbus/v5 v5.0.3
|
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
6
go.sum
|
@ -1,6 +1,12 @@
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
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 h1:uLmvlsenFUA5XkLheXgdQnX3T/oeYzO9aokBrbSsi/w=
|
||||||
gioui.org v0.0.0-20200619180744-e2f3bbdfc367/go.mod h1:jiUwifN9cRl/zmco43aAqh0aV+s9GbhG13KcD+gEpkU=
|
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 h1:+S/LqMv8h+w4LE/3XtAq1roX8OAZ/E6rqsl/EQ1eaK8=
|
||||||
git.wow.st/whereswaldon/jni v0.0.0-20200620152723-b380472956a0/go.mod h1:ro8WfqxHdXc4wFC+3uP98fVT5uZqrq3yQPMV+LjP6MA=
|
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=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
|
|
107
macos/notify_macos.go
Normal file
107
macos/notify_macos.go
Normal 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
26
niotify_macos.go
Normal 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
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
//+build !linux,!android
|
//+build !linux,!android,!darwin
|
||||||
|
|
||||||
package niotify
|
package niotify
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user