From c3e06aeb83867984fdb689c027ae08b41809751b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Hamil?= Date: Sat, 14 Feb 2026 16:05:31 +0300 Subject: [PATCH] Refactor radio item management in handleMenuItemClick to prevent unnecessary state updates during radio group changes --- v2/internal/frontend/desktop/linux/gtk.go | 8 +++++- v2/internal/frontend/desktop/linux/window.c | 4 +++ .../frontend/desktop/windows/window.go | 5 ++-- v2/pkg/options/options.go | 28 +++++++++++-------- 4 files changed, 31 insertions(+), 14 deletions(-) diff --git a/v2/internal/frontend/desktop/linux/gtk.go b/v2/internal/frontend/desktop/linux/gtk.go index b58bb261d..689313e86 100644 --- a/v2/internal/frontend/desktop/linux/gtk.go +++ b/v2/internal/frontend/desktop/linux/gtk.go @@ -22,6 +22,8 @@ import ( "github.com/wailsapp/wails/v2/pkg/menu" ) +var radioUpdating bool + func GtkMenuItemWithLabel(label string) *C.GtkWidget { cLabel := C.CString(label) result := C.gtk_menu_item_new_with_label(cLabel) @@ -90,12 +92,16 @@ func handleMenuItemClick(gtkWidget unsafe.Pointer) { C.unblockClick(gtkRadioItem, handler) } } + radioUpdating = true updateRadio(appMenuCache) updateRadio(trayMenuCache) + radioUpdating = false item.Checked = true go item.Click(&menu.CallbackData{MenuItem: item}) } else { - item.Checked = false + if !radioUpdating { + item.Checked = false + } } default: go item.Click(&menu.CallbackData{MenuItem: item}) diff --git a/v2/internal/frontend/desktop/linux/window.c b/v2/internal/frontend/desktop/linux/window.c index 415159a3c..abd122c2e 100644 --- a/v2/internal/frontend/desktop/linux/window.c +++ b/v2/internal/frontend/desktop/linux/window.c @@ -968,6 +968,10 @@ void TraySetSystemTray(GtkWindow *window, const char *label, const guchar *image else { unlink(filename); + if (indicator_temp_icon_path == filename) + { + indicator_temp_icon_path = NULL; + } g_free(filename); } } diff --git a/v2/internal/frontend/desktop/windows/window.go b/v2/internal/frontend/desktop/windows/window.go index 933b7098a..efcb97bfe 100644 --- a/v2/internal/frontend/desktop/windows/window.go +++ b/v2/internal/frontend/desktop/windows/window.go @@ -433,9 +433,10 @@ func (w *Window) TraySetSystemTray(trayMenu *menu.TrayMenu) { func (w *Window) loadTrayIcon(image string) (w32.HICON, error) { if _, err := os.Stat(image); err == nil { ico, err := winc.NewIconFromFile(image) - if err == nil { - return w32.HICON(ico.Handle()), nil + if err != nil { + return 0, fmt.Errorf("failed to load icon from file %q: %w", image, err) } + return w32.HICON(ico.Handle()), nil } data, err := base64.StdEncoding.DecodeString(image) diff --git a/v2/pkg/options/options.go b/v2/pkg/options/options.go index 94cc2871f..c66a797ea 100644 --- a/v2/pkg/options/options.go +++ b/v2/pkg/options/options.go @@ -40,17 +40,19 @@ type Experimental struct{} // App contains options for creating the App type App struct { - Title string - Width int - Height int - DisableResize bool - Fullscreen bool - Frameless bool - MinWidth int - MinHeight int - MaxWidth int - MaxHeight int - StartHidden bool + Title string + Width int + Height int + DisableResize bool + Fullscreen bool + Frameless bool + MinWidth int + MinHeight int + MaxWidth int + MaxHeight int + StartHidden bool + // HideWindowOnClose is deprecated. Use WindowCloseBehaviour instead. + // If set to true, WindowCloseBehaviour will be set to HideWindow if it is currently CloseWindow. HideWindowOnClose bool WindowCloseBehaviour WindowCloseBehaviour AlwaysOnTop bool @@ -187,6 +189,10 @@ func MergeDefaults(appoptions *App) { } } + if appoptions.HideWindowOnClose && appoptions.WindowCloseBehaviour == CloseWindow { + appoptions.WindowCloseBehaviour = HideWindow + } + // Ensure max and min are valid processMinMaxConstraints(appoptions)