From 84e1bb4d9bbb97933432ed342e9dc640f79b1878 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sun, 4 Feb 2024 18:16:59 +1100 Subject: [PATCH] Improve Linux application events and refactor app method receivers This commit includes the addition of common events for the Linux platform. Refactored and standardized the method receivers for the application from 'm' to 'l'. Also, the application startup events in the window example have been updated according to the new naming scheme. --- v3/pkg/application/application_linux.go | 91 ++++++++++++---------- v3/pkg/application/dialogs_linux.go | 4 +- v3/pkg/application/events_common_linux.go | 4 +- v3/pkg/application/mainthread_linux.go | 2 +- v3/pkg/application/screen_linux.go | 6 +- v3/pkg/application/webview_window_linux.go | 10 +++ 6 files changed, 67 insertions(+), 50 deletions(-) diff --git a/v3/pkg/application/application_linux.go b/v3/pkg/application/application_linux.go index 99981bd33..c96929458 100644 --- a/v3/pkg/application/application_linux.go +++ b/v3/pkg/application/application_linux.go @@ -34,7 +34,7 @@ type linuxApp struct { theme string } -func (a *linuxApp) GetFlags(options Options) map[string]any { +func (l *linuxApp) GetFlags(options Options) map[string]any { if options.Flags == nil { options.Flags = make(map[string]any) } @@ -45,28 +45,31 @@ func getNativeApplication() *linuxApp { return globalApplication.impl.(*linuxApp) } -func (a *linuxApp) hide() { - a.hideAllWindows() +func (l *linuxApp) hide() { + hideAllWindows(l.application) } -func (a *linuxApp) show() { - a.showAllWindows() +func (l *linuxApp) show() { + showAllWindows(l.application) } -func (a *linuxApp) on(eventID uint) { - // TODO: Test register/unregister events - //C.registerApplicationEvent(l.application, C.uint(eventID)) +func (l *linuxApp) on(eventID uint) { + // TODO: What do we need to do here? + log.Println("linuxApp.on()", eventID) } -func (a *linuxApp) setIcon(icon []byte) { - +func (l *linuxApp) setIcon(icon []byte) { log.Println("linuxApp.setIcon", "not implemented") } -func (a *linuxApp) name() string { +func (l *linuxApp) name() string { return appName() } +func (l *linuxApp) getCurrentWindowID() uint { + return getCurrentWindowID(l.application, l.windows) +} + type rnr struct { f func() } @@ -75,7 +78,22 @@ func (r rnr) run() { r.f() } -func (a *linuxApp) setApplicationMenu(menu *Menu) { +func (l *linuxApp) getApplicationMenu() pointer { + if l.applicationMenu != nilPointer { + return l.applicationMenu + } + + menu := globalApplication.ApplicationMenu + if menu != nil { + InvokeSync(func() { + menu.Update() + }) + l.applicationMenu = (menu.impl).(*linuxMenu).native + } + return l.applicationMenu +} + +func (l *linuxApp) setApplicationMenu(menu *Menu) { // FIXME: How do we avoid putting a menu? if menu == nil { // Create a default menu @@ -84,55 +102,44 @@ func (a *linuxApp) setApplicationMenu(menu *Menu) { } } -func (a *linuxApp) run() error { +func (l *linuxApp) run() error { - a.parent.On(events.Linux.ApplicationStartup, func(evt *Event) { + l.parent.On(events.Linux.ApplicationStartup, func(evt *Event) { fmt.Println("events.Linux.ApplicationStartup received!") }) - a.setupCommonEvents() - a.monitorThemeChanges() - return appRun(a.application) + l.setupCommonEvents() + l.monitorThemeChanges() + return appRun(l.application) } -func (a *linuxApp) unregisterWindow(w windowPointer) { - a.windowMapLock.Lock() - delete(a.windowMap, w) - a.windowMapLock.Unlock() - - // If this was the last window... - if len(a.windowMap) == 0 && !a.parent.options.Linux.DisableQuitOnLastWindowClosed { - a.destroy() - } -} - -func (a *linuxApp) destroy() { +func (l *linuxApp) destroy() { if !globalApplication.shouldQuit() { return } globalApplication.cleanup() - appDestroy(a.application) + appDestroy(l.application) } -func (a *linuxApp) isOnMainThread() bool { +func (l *linuxApp) isOnMainThread() bool { return isOnMainThread() } // register our window to our parent mapping -func (a *linuxApp) registerWindow(window pointer, id uint) { - a.windowMapLock.Lock() - a.windowMap[windowPointer(window)] = id - a.windowMapLock.Unlock() +func (l *linuxApp) registerWindow(window pointer, id uint) { + l.windowsLock.Lock() + l.windows[windowPointer(window)] = id + l.windowsLock.Unlock() } -func (a *linuxApp) isDarkMode() bool { - return strings.Contains(a.theme, "dark") +func (l *linuxApp) isDarkMode() bool { + return strings.Contains(l.theme, "dark") } -func (a *linuxApp) monitorThemeChanges() { +func (l *linuxApp) monitorThemeChanges() { go func() { conn, err := dbus.ConnectSessionBus() if err != nil { - a.parent.info("[WARNING] Failed to connect to session bus; monitoring for theme changes will not function:", err) + l.parent.info("[WARNING] Failed to connect to session bus; monitoring for theme changes will not function:", err) return } defer conn.Close() @@ -165,10 +172,10 @@ func (a *linuxApp) monitorThemeChanges() { continue } - if theme != a.theme { - a.theme = theme + if theme != l.theme { + l.theme = theme event := newApplicationEvent(events.Common.ThemeChanged) - event.Context().setIsDarkMode(a.isDarkMode()) + event.Context().setIsDarkMode(l.isDarkMode()) applicationEvents <- event } diff --git a/v3/pkg/application/dialogs_linux.go b/v3/pkg/application/dialogs_linux.go index be480d176..49499dda1 100644 --- a/v3/pkg/application/dialogs_linux.go +++ b/v3/pkg/application/dialogs_linux.go @@ -1,7 +1,7 @@ package application -func (a *linuxApp) showAboutDialog(title string, message string, icon []byte) { - window := globalApplication.getWindowForID(a.getCurrentWindowID()) +func (l *linuxApp) showAboutDialog(title string, message string, icon []byte) { + window := globalApplication.getWindowForID(l.getCurrentWindowID()) var parent uintptr if window != nil { parent, _ = window.(*WebviewWindow).NativeWindowHandle() diff --git a/v3/pkg/application/events_common_linux.go b/v3/pkg/application/events_common_linux.go index e06fb8cfe..530ac1563 100644 --- a/v3/pkg/application/events_common_linux.go +++ b/v3/pkg/application/events_common_linux.go @@ -9,11 +9,11 @@ var commonApplicationEventMap = map[events.ApplicationEventType]events.Applicati events.Linux.SystemThemeChanged: events.Common.ThemeChanged, } -func (a *linuxApp) setupCommonEvents() { +func (l *linuxApp) setupCommonEvents() { for sourceEvent, targetEvent := range commonApplicationEventMap { sourceEvent := sourceEvent targetEvent := targetEvent - a.parent.On(sourceEvent, func(event *Event) { + l.parent.On(sourceEvent, func(event *Event) { event.Id = uint(targetEvent) applicationEvents <- event }) diff --git a/v3/pkg/application/mainthread_linux.go b/v3/pkg/application/mainthread_linux.go index a718688bc..2a5ff3e2c 100644 --- a/v3/pkg/application/mainthread_linux.go +++ b/v3/pkg/application/mainthread_linux.go @@ -2,7 +2,7 @@ package application -func (a *linuxApp) dispatchOnMainThread(id uint) { +func (l *linuxApp) dispatchOnMainThread(id uint) { dispatchOnMainThread(id) } diff --git a/v3/pkg/application/screen_linux.go b/v3/pkg/application/screen_linux.go index d93cfbd92..526752ace 100644 --- a/v3/pkg/application/screen_linux.go +++ b/v3/pkg/application/screen_linux.go @@ -7,17 +7,17 @@ import ( "sync" ) -func (a *linuxApp) getPrimaryScreen() (*Screen, error) { +func (l *linuxApp) getPrimaryScreen() (*Screen, error) { return nil, fmt.Errorf("not implemented") } -func (a *linuxApp) getScreens() ([]*Screen, error) { +func (l *linuxApp) getScreens() ([]*Screen, error) { var wg sync.WaitGroup var screens []*Screen var err error wg.Add(1) InvokeSync(func() { - screens, err = getScreens(a.application) + screens, err = getScreens(l.application) wg.Done() }) wg.Wait() diff --git a/v3/pkg/application/webview_window_linux.go b/v3/pkg/application/webview_window_linux.go index e03471822..b9ba7d414 100644 --- a/v3/pkg/application/webview_window_linux.go +++ b/v3/pkg/application/webview_window_linux.go @@ -161,6 +161,16 @@ func newWindowImpl(parent *WebviewWindow) *linuxWebviewWindow { return result } +func (w *linuxWebviewWindow) setTitle(title string) { + if !w.parent.options.Frameless { + windowSetTitle(w.window, title) + } +} + +func (w *linuxWebviewWindow) setSize(width, height int) { + windowResize(w.window, width, height) +} + func (w *linuxWebviewWindow) setMinMaxSize(minWidth, minHeight, maxWidth, maxHeight int) { if minWidth == 0 { minWidth = -1