From 809863d61a0f2c684aab49d58b2c07ddfea87f5a Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Tue, 6 Feb 2024 05:50:36 +1100 Subject: [PATCH] Refactor Linux application handling in webview This update introduces a LinuxOptions struct for Linux-specific application configurations and refines webview for Linux. The 'windows' map has been renamed to 'windowMap' to avoid confusion. Moreover, a method to unregister Windows has been added to ensure the Linux application automatically quits when the last window closes, unless explicitly disabled in the new LinuxOptions structure. Reset Window position after hiding. Some debug output has been removed. --- v3/pkg/application/application_linux.go | 25 +++++++++---- v3/pkg/application/options_application.go | 3 ++ .../application/options_application_linux.go | 7 ++++ v3/pkg/application/webview_window_linux.go | 36 ++++++++++--------- 4 files changed, 47 insertions(+), 24 deletions(-) create mode 100644 v3/pkg/application/options_application_linux.go diff --git a/v3/pkg/application/application_linux.go b/v3/pkg/application/application_linux.go index c3b54673d..a72775f0b 100644 --- a/v3/pkg/application/application_linux.go +++ b/v3/pkg/application/application_linux.go @@ -29,8 +29,8 @@ type linuxApp struct { startupActions []func() // Native -> uint - windows map[windowPointer]uint - windowsLock sync.Mutex + windowMap map[windowPointer]uint + windowMapLock sync.Mutex theme string } @@ -69,7 +69,7 @@ func (l *linuxApp) name() string { } func (l *linuxApp) getCurrentWindowID() uint { - return getCurrentWindowID(l.application, l.windows) + return getCurrentWindowID(l.application, l.windowMap) } type rnr struct { @@ -114,6 +114,17 @@ func (l *linuxApp) run() error { return appRun(l.application) } +func (l *linuxApp) unregisterWindow(w windowPointer) { + l.windowMapLock.Lock() + delete(l.windowMap, w) + l.windowMapLock.Unlock() + + // If this was the last window... + if len(l.windowMap) == 0 && !l.parent.options.Linux.DisableQuitOnLastWindowClosed { + l.destroy() + } +} + func (l *linuxApp) destroy() { if !globalApplication.shouldQuit() { return @@ -128,9 +139,9 @@ func (l *linuxApp) isOnMainThread() bool { // register our window to our parent mapping func (l *linuxApp) registerWindow(window pointer, id uint) { - l.windowsLock.Lock() - l.windows[windowPointer(window)] = id - l.windowsLock.Unlock() + l.windowMapLock.Lock() + l.windowMap[windowPointer(window)] = id + l.windowMapLock.Unlock() } func (l *linuxApp) isDarkMode() bool { @@ -193,7 +204,7 @@ func newPlatformApp(parent *App) *linuxApp { app := &linuxApp{ parent: parent, application: appNew(name), - windows: map[windowPointer]uint{}, + windowMap: map[windowPointer]uint{}, } return app } diff --git a/v3/pkg/application/options_application.go b/v3/pkg/application/options_application.go index 10bf75188..b60dfd85f 100644 --- a/v3/pkg/application/options_application.go +++ b/v3/pkg/application/options_application.go @@ -24,6 +24,9 @@ type Options struct { // Windows is the Windows specific configuration for Windows builds Windows WindowsOptions + // Linux is the Linux specific configuration for Linux builds + Linux LinuxOptions + // Bind allows you to bind Go methods to the frontend. Bind []any diff --git a/v3/pkg/application/options_application_linux.go b/v3/pkg/application/options_application_linux.go new file mode 100644 index 000000000..8c3741ca6 --- /dev/null +++ b/v3/pkg/application/options_application_linux.go @@ -0,0 +1,7 @@ +package application + +// LinuxOptions contains options for Linux applications. +type LinuxOptions struct { + // DisableQuitOnLastWindowClosed disables the auto quit of the application if the last window has been closed. + DisableQuitOnLastWindowClosed bool +} diff --git a/v3/pkg/application/webview_window_linux.go b/v3/pkg/application/webview_window_linux.go index 3df64706d..75055ddf5 100644 --- a/v3/pkg/application/webview_window_linux.go +++ b/v3/pkg/application/webview_window_linux.go @@ -21,18 +21,19 @@ type dragInfo struct { } type linuxWebviewWindow struct { - id uint - application pointer - window pointer - webview pointer - parent *WebviewWindow - menubar pointer - vbox pointer - menu *Menu - accels pointer - lastWidth int - lastHeight int - drag dragInfo + id uint + application pointer + window pointer + webview pointer + parent *WebviewWindow + menubar pointer + vbox pointer + menu *Menu + accels pointer + lastWidth int + lastHeight int + drag dragInfo + lastX, lastY int } var ( @@ -109,9 +110,12 @@ func (w *linuxWebviewWindow) focus() { func (w *linuxWebviewWindow) show() { windowShow(w.window) + w.setAbsolutePosition(w.lastX, w.lastY) } func (w *linuxWebviewWindow) hide() { + // save position + w.lastX, w.lastY = windowGetAbsolutePosition(w.window) windowHide(w.window) } @@ -140,7 +144,7 @@ func (w *linuxWebviewWindow) unfullscreen() { func (w *linuxWebviewWindow) fullscreen() { w.maximise() - w.lastWidth, w.lastHeight = w.size() + //w.lastWidth, w.lastHeight = w.size() x, y, width, height, scale := windowGetCurrentMonitorGeometry(w.window) if x == -1 && y == -1 && width == -1 && height == -1 { return @@ -172,9 +176,7 @@ func (w *linuxWebviewWindow) flash(enabled bool) { } func (w *linuxWebviewWindow) on(eventID uint) { - // Don't think this is correct! - // GTK Events are strings - fmt.Println("on()", eventID) + // TODO: Test register/unregister listener for linux events //C.registerListener(C.uint(eventID)) } @@ -188,6 +190,7 @@ func (w *linuxWebviewWindow) windowZoom() { func (w *linuxWebviewWindow) close() { windowClose(w.window) + getNativeApplication().unregisterWindow(windowPointer(w.window)) } func (w *linuxWebviewWindow) zoomIn() { @@ -388,7 +391,6 @@ func (w *linuxWebviewWindow) run() { if w.parent.options.X != 0 || w.parent.options.Y != 0 { w.setRelativePosition(w.parent.options.X, w.parent.options.Y) } else { - fmt.Println("attempting to set in the center") w.center() } switch w.parent.options.StartState {