diff --git a/ui/app_delegate_darwin.go b/ui/app_delegate_darwin.go new file mode 100644 index 0000000..7b430a8 --- /dev/null +++ b/ui/app_delegate_darwin.go @@ -0,0 +1,40 @@ +//go:build darwin + +package ui + +/* +void installReopenDelegate(); +*/ +import "C" + +import "fyne.io/fyne/v2" + +var darwinAppDelegateReopenWindow fyne.Window + +// darwinQuitting is set to true when applicationShouldTerminate: fires so +// the close intercept knows to actually close instead of hide. +var darwinQuitting bool + +func isRealQuit() bool { + return darwinQuitting +} + +func installReopenHandler(w fyne.Window) { + darwinAppDelegateReopenWindow = w + C.installReopenDelegate() +} + +//export appReopened +func appReopened() { + if darwinAppDelegateReopenWindow == nil { + return + } + go func() { + fyne.Do(darwinAppDelegateReopenWindow.Show) + }() +} + +//export appShouldTerminate +func appShouldTerminate() { + darwinQuitting = true +} diff --git a/ui/app_delegate_darwin.m b/ui/app_delegate_darwin.m new file mode 100644 index 0000000..67621ce --- /dev/null +++ b/ui/app_delegate_darwin.m @@ -0,0 +1,52 @@ +//go:build darwin + +#import + +extern void appReopened(void); +extern void appShouldTerminate(void); + +@interface ReopenDelegate : NSObject +@property (nonatomic, strong) id wrapped; +@end + + +@implementation ReopenDelegate + +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { + // Set the quitting flag before GLFW's delegate fires close requests for + // each window, so our close intercept knows to close rather than hide. + appShouldTerminate(); + if ([self.wrapped respondsToSelector:_cmd]) { + return [self.wrapped applicationShouldTerminate:sender]; + } + return NSTerminateNow; +} + +- (BOOL)applicationShouldHandleReopen:(NSApplication *)app + hasVisibleWindows:(BOOL)hasVisible { + if (!hasVisible) { + appReopened(); + } + if ([self.wrapped respondsToSelector:_cmd]) { + return [self.wrapped applicationShouldHandleReopen:app + hasVisibleWindows:hasVisible]; + } + return YES; +} + +- (BOOL)respondsToSelector:(SEL)sel { + return [super respondsToSelector:sel] || + [self.wrapped respondsToSelector:sel]; +} + +- (id)forwardingTargetForSelector:(SEL)sel { + return [self.wrapped respondsToSelector:sel] ? self.wrapped : nil; +} + +@end + +void installReopenDelegate(void) { + ReopenDelegate *d = [ReopenDelegate new]; + d.wrapped = [NSApp delegate]; + [NSApp setDelegate:d]; +} diff --git a/ui/app_delegate_other.go b/ui/app_delegate_other.go new file mode 100644 index 0000000..c48ba75 --- /dev/null +++ b/ui/app_delegate_other.go @@ -0,0 +1,12 @@ +//go:build !darwin + +package ui + +import "fyne.io/fyne/v2" + +func installReopenHandler(w fyne.Window) { +} + +func isRealQuit() bool { + return false +} diff --git a/ui/mainwindow.go b/ui/mainwindow.go index ba7e2e3..e32f006 100644 --- a/ui/mainwindow.go +++ b/ui/mainwindow.go @@ -61,6 +61,7 @@ func NewMainWindow(fyneApp fyne.App, appName, displayAppName, appVersion string, Window: fyneApp.NewWindow(displayAppName), theme: myTheme.NewMyTheme(&app.Config.Theme, app.ThemesDir()), } + installReopenHandler(m.Window) fynetooltip.SetToolTipTextSizeName(myTheme.SizeNameSubText) m.theme.NormalFont = app.Config.Application.FontNormalTTF @@ -184,7 +185,7 @@ func NewMainWindow(fyneApp fyne.App, appName, displayAppName, appVersion string, m.Window.SetCloseIntercept(func() { m.SaveWindowSettings() - if app.Config.Application.CloseToSystemTray && m.HaveSystemTray() { + if (runtime.GOOS == "darwin" && !isRealQuit()) || (app.Config.Application.CloseToSystemTray && m.HaveSystemTray()) { m.Window.Hide() } else { m.Window.Close() @@ -514,7 +515,7 @@ func (m *MainWindow) addShortcuts() { m.Controller.SelectAll() }) m.Canvas().AddShortcut(&shortcuts.ShortcutCloseWindow, func(_ fyne.Shortcut) { - if m.App.Config.Application.CloseToSystemTray && m.HaveSystemTray() { + if runtime.GOOS == "darwin" || (m.App.Config.Application.CloseToSystemTray && m.HaveSystemTray()) { m.Window.Hide() } })