Skip to content

Commit

Permalink
dexc-desktop: Implement native notifications for MacOS (decred#2772)
Browse files Browse the repository at this point in the history
* dexc-desktop: Implement native notifications for MacOS

---------

Signed-off-by: Philemon Ukane <[email protected]>
  • Loading branch information
ukane-philemon authored May 23, 2024
1 parent 66f59b7 commit e8dc621
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 21 deletions.
9 changes: 9 additions & 0 deletions client/cmd/bisonw-desktop/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ import (
"decred.org/dcrdex/client/webserver"
"decred.org/dcrdex/dex"
"fyne.io/systray"
"github.com/gen2brain/beeep"
"github.com/pkg/browser"
"github.com/webview/webview"
)
Expand Down Expand Up @@ -550,3 +551,11 @@ func systrayOnReady(ctx context.Context, logDirectory string, openC chan<- struc
}
}()
}

func sendDesktopNotification(title, msg string) {
err := beeep.Notify(title, msg, tmpLogoPath)
if err != nil {
log.Errorf("error sending desktop notification: %v", err)
return
}
}
30 changes: 29 additions & 1 deletion client/cmd/bisonw-desktop/app_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ package main

/*
#cgo CFLAGS: -x objective-c
#cgo LDFLAGS: -lobjc -framework WebKit -framework AppKit
#cgo LDFLAGS: -lobjc -framework WebKit -framework AppKit -framework UserNotifications
#import <objc/runtime.h>
#import <WebKit/WebKit.h>
#import <AppKit/AppKit.h>
#import <UserNotifications/UserNotifications.h>
// NavigationActionPolicyCancel is an integer used in Go code to represent
// WKNavigationActionPolicyCancel
Expand All @@ -20,6 +21,7 @@ const int NavigationActionPolicyCancel = 1;
- (void)completionHandler:(void (^)(NSArray<NSURL *> * _Nullable URLs))completionHandler withURLs:(NSArray<NSURL *> * _Nullable)URLs;
- (void)decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler withPolicy:(int)policy;
- (void)authenticationCompletionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler withChallenge:(NSURLAuthenticationChallenge *)challenge;
- (void)deliverNotificationWithTitle:(NSString *)title message:(NSString *)message icon:(NSImage *)icon;
@end
@implementation CompletionHandlerDelegate
Expand All @@ -46,6 +48,25 @@ const int NavigationActionPolicyCancel = 1;
CFRelease(exceptions);
completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:serverTrust]);
}
// Implements "deliverNotificationWithTitle:message:icon:" handler with the NSUserNotification
// and NSUserNotificationCenter classes which have been marked deprecated
// but it is what works atm for macOS apps. The newer UNUserNotificationCenter has some
// implementation issues and very little information to aid debugging.
// See: https://developer.apple.com/documentation/foundation/nsusernotification?language=objc and
// https://github.com/progrium/macdriver/discussions/258
- (void)deliverNotificationWithTitle:(NSString *)title message:(NSString *)message icon:(NSImage *)icon{
NSUserNotification *notification = [NSUserNotification new];
notification.title = title;
notification.informativeText = message;
notification.actionButtonTitle = @"Ok";
notification.hasActionButton = 1;
notification.soundName = NSUserNotificationDefaultSoundName;
[notification setValue:icon forKey:@"_identityImage"];
[notification setValue:@(false) forKey:@"_identityImageHasBorder"];
[notification setValue:@YES forKey:@"_ignoresDoNotDisturb"];
[[NSUserNotificationCenter defaultUserNotificationCenter]deliverNotification:notification];
}
@end
void* createCompletionHandlerDelegate() {
Expand Down Expand Up @@ -98,6 +119,7 @@ var (
// completionHandler handles Objective-C callback functions for some
// delegate methods.
completionHandler = objc.Object_fromPointer(C.createCompletionHandlerDelegate())
dexcAppIcon = cocoa.NSImage_InitWithData(mdCore.NSData_WithBytes(SymbolBWIcon, uint64(len(SymbolBWIcon))))
)

const (
Expand Down Expand Up @@ -829,3 +851,9 @@ func (sc *shutdownCloser) Done() {
}
sc.closers = nil
}

func sendDesktopNotification(title, msg string) {
nsTitle := mdCore.NSString_FromString(title)
nsMessage := mdCore.NSString_FromString(msg)
completionHandler.Send("deliverNotificationWithTitle:message:icon:", nsTitle, nsMessage, dexcAppIcon)
}
1 change: 0 additions & 1 deletion client/cmd/bisonw-desktop/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,3 @@ package main

// After generating the rsrc_windows_amd64.syso file, it will be included in the
// binary when making an amd64 build for windows.

8 changes: 4 additions & 4 deletions client/cmd/bisonw-desktop/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ replace decred.org/dcrdex => ../../..
require (
decred.org/dcrdex v0.6.3
fyne.io/systray v1.10.1-0.20230403195833-7dc3c09283d6
github.com/gen2brain/beeep v0.0.0-20220909211152-5a9ec94374f6
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8
github.com/progrium/macdriver v0.4.0
github.com/webview/webview v0.0.0-20230415172654-8387ff8945fc
Expand All @@ -16,8 +15,11 @@ require (

require (
github.com/dcrlabs/ltcwallet v0.0.0-20240518141247-13553c8fce6a // indirect
github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4 // indirect
github.com/ltcsuite/lnd/tlv v0.0.0-20240222214433-454d35886119 // indirect
github.com/ltcsuite/ltcd/chaincfg/chainhash v1.0.2 // indirect
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect
github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af // indirect
)

require (
Expand Down Expand Up @@ -98,11 +100,11 @@ require (
github.com/gcash/bchd v0.19.0 // indirect
github.com/gcash/bchlog v0.0.0-20180913005452-b4f036f92fa6 // indirect
github.com/gcash/bchutil v0.0.0-20210113190856-6ea28dff4000 // indirect
github.com/gen2brain/beeep v0.0.0-20240112042604-c7bb2cd88fea
github.com/getsentry/sentry-go v0.18.0 // indirect
github.com/go-chi/chi/v5 v5.0.1 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-stack/stack v1.8.1 // indirect
github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
Expand Down Expand Up @@ -147,7 +149,6 @@ require (
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/pointerstructure v1.2.0 // indirect
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.14.0 // indirect
Expand All @@ -162,7 +163,6 @@ require (
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
github.com/status-im/keycard-go v0.2.0 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af // indirect
github.com/tevino/abool v1.2.0 // indirect
github.com/tklauser/go-sysconf v0.3.5 // indirect
github.com/tklauser/numcpus v0.2.2 // indirect
Expand Down
5 changes: 2 additions & 3 deletions client/cmd/bisonw-desktop/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -389,8 +389,8 @@ github.com/gcash/bchutil v0.0.0-20210113190856-6ea28dff4000/go.mod h1:H2USFGwtiu
github.com/gcash/bchwallet v0.8.3-0.20210524112536-14ca25bc6549 h1:hC4Qxxvq0SN/1Jhqzh6ETZoBOXBG5PMBTYkTQqBcPKQ=
github.com/gcash/bchwallet/walletdb v0.0.0-20210524044131-61bcca2ae6f9 h1:lryOGJ7VBv4zFpLtFEsH8ik68OnTwN3A71cisqXgN6w=
github.com/gcash/neutrino v0.0.0-20210524114821-3b1878290cf9 h1:V5UNzi/5pZxE5s6kfCe59VjJRmfkyI+npZizMcAvEdI=
github.com/gen2brain/beeep v0.0.0-20220909211152-5a9ec94374f6 h1:jFEK/SA/7E8lg9T33+y8D4Z0I782+bbiEjmyyklRzRQ=
github.com/gen2brain/beeep v0.0.0-20220909211152-5a9ec94374f6/go.mod h1:/WeFVhhxMOGypVKS0w8DUJxUBbHypnWkUVnW7p5c9Pw=
github.com/gen2brain/beeep v0.0.0-20240112042604-c7bb2cd88fea h1:oWUHxzaBvwkRWiINbBOY39XIF+n9b4RJEPHdQ8waJUo=
github.com/gen2brain/beeep v0.0.0-20240112042604-c7bb2cd88fea/go.mod h1:0W7dI87PvXJ1Sjs0QPvWXKcQmNERY77e8l7GFhZB/s4=
github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c=
github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0=
github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ=
Expand Down Expand Up @@ -1440,7 +1440,6 @@ golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down
3 changes: 1 addition & 2 deletions client/cmd/bisonw-desktop/icon_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,4 @@ var FavIcon []byte // darwin doesn't use these
//go:embed src/favicon-bw-32.png
var FavIconBW []byte // darwin doesn't use these

// On Darwin, we instead use macdriver (not webview) and
// obj.Button().SetImage(cocoa.NSImage_InitWithData.
// On Darwin, we instead use macdriver (not webview)
9 changes: 0 additions & 9 deletions client/cmd/bisonw-desktop/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ import (
// Ethereum loaded in client/app/importlgpl.go

"decred.org/dcrdex/dex"
"github.com/gen2brain/beeep"
)

const (
Expand Down Expand Up @@ -136,11 +135,3 @@ func limitedWindowWidthAndHeight(width int, height int) (int, int) {
}
return width, height
}

func sendDesktopNotification(title, msg string) {
err := beeep.Notify(title, msg, tmpLogoPath)
if err != nil {
log.Errorf("error sending desktop notification: %v", err)
return
}
}
3 changes: 2 additions & 1 deletion client/cmd/bisonw-desktop/pkg/pkg-darwin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ function prepare() {
<key>NSHighResolutionCapable</key><true/>
<key>NSRequiresAquaSystemAppearance</key><false/>
<key>NSSupportsAutomaticGraphicsSwitching</key><true/>
<key>NSUserNotificationAlertStyle</key><string>banner</string>
<key>CFBundlePackageType</key><string>APPL</string>
<key>NSUserNotificationAlertStyle</key><string>alert</string>
</dict></plist>" > "${CONTENTS_DIR}/Info.plist"
}

Expand Down

0 comments on commit e8dc621

Please sign in to comment.