diff --git a/v2/internal/frontend/desktop/windows/frontend.go b/v2/internal/frontend/desktop/windows/frontend.go index f8ebe5d74..2db1328cb 100644 --- a/v2/internal/frontend/desktop/windows/frontend.go +++ b/v2/internal/frontend/desktop/windows/frontend.go @@ -106,28 +106,15 @@ func (f *Frontend) WindowReload() { } func (f *Frontend) WindowSetSystemDefaultTheme() { - f.mainWindow.frontendOptions.Windows.Theme = windows.SystemDefault - f.mainWindow.Invoke(func() { - f.mainWindow.updateTheme() - }) + f.mainWindow.SetTheme(windows.SystemDefault) } func (f *Frontend) WindowSetLightTheme() { - if f.mainWindow.frontendOptions != nil && f.mainWindow.frontendOptions.Windows != nil { - f.mainWindow.frontendOptions.Windows.Theme = windows.Light - f.mainWindow.Invoke(func() { - f.mainWindow.updateTheme() - }) - } + f.mainWindow.SetTheme(windows.Light) } func (f *Frontend) WindowSetDarkTheme() { - if f.mainWindow.frontendOptions != nil && f.mainWindow.frontendOptions.Windows != nil { - f.mainWindow.frontendOptions.Windows.Theme = windows.Dark - f.mainWindow.Invoke(func() { - f.mainWindow.updateTheme() - }) - } + f.mainWindow.SetTheme(windows.Dark) } func (f *Frontend) Run(ctx context.Context) error { diff --git a/v2/internal/frontend/desktop/windows/theme.go b/v2/internal/frontend/desktop/windows/theme.go index 842d7480d..897133026 100644 --- a/v2/internal/frontend/desktop/windows/theme.go +++ b/v2/internal/frontend/desktop/windows/theme.go @@ -7,6 +7,12 @@ import ( func (w *Window) updateTheme() { + // Don't redraw theme if nothing has changed + if !w.themeChanged { + return + } + w.themeChanged = false + if win32.IsCurrentlyHighContrastMode() { return } @@ -14,25 +20,24 @@ func (w *Window) updateTheme() { if !win32.SupportsThemes() { return } - // Only process if there's a theme change - isDarkMode := win32.IsCurrentlyDarkMode() - w.isDarkMode = isDarkMode - // Default use system theme + var isDarkMode bool + switch w.theme { + case windows.SystemDefault: + isDarkMode = win32.IsCurrentlyDarkMode() + case windows.Dark: + isDarkMode = true + case windows.Light: + isDarkMode = false + } + win32.SetTheme(w.Handle(), isDarkMode) + + // Custom theme processing winOptions := w.frontendOptions.Windows var customTheme *windows.ThemeSettings if winOptions != nil { customTheme = winOptions.CustomTheme - if winOptions.Theme == windows.Dark { - isDarkMode = true - } - if winOptions.Theme == windows.Light { - isDarkMode = false - } } - - win32.SetTheme(w.Handle(), isDarkMode) - // Custom theme if win32.SupportsCustomThemes() && customTheme != nil { if w.isActive { diff --git a/v2/internal/frontend/desktop/windows/window.go b/v2/internal/frontend/desktop/windows/window.go index 3d530a96c..dce79438d 100644 --- a/v2/internal/frontend/desktop/windows/window.go +++ b/v2/internal/frontend/desktop/windows/window.go @@ -12,6 +12,7 @@ import ( "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc/w32" "github.com/wailsapp/wails/v2/pkg/menu" "github.com/wailsapp/wails/v2/pkg/options" + winoptions "github.com/wailsapp/wails/v2/pkg/options/windows" ) type Window struct { @@ -24,6 +25,11 @@ type Window struct { isDarkMode bool isActive bool hasBeenShown bool + + // Theme + theme winoptions.Theme + themeChanged bool + OnSuspend func() OnResume func() } @@ -37,6 +43,7 @@ func NewWindow(parent winc.Controller, appoptions *options.App, versionInfo *ope maxWidth: appoptions.MaxWidth, versionInfo: versionInfo, isActive: true, + themeChanged: true, } result.SetIsForm(true) @@ -73,6 +80,16 @@ func NewWindow(parent winc.Controller, appoptions *options.App, versionInfo *ope win32.SetBackgroundColour(result.Handle(), appoptions.BackgroundColour.R, appoptions.BackgroundColour.G, appoptions.BackgroundColour.B) } + if appoptions.Windows != nil { + result.theme = appoptions.Windows.Theme + } else { + result.theme = winoptions.SystemDefault + } + + if appoptions.BackgroundColour != nil { + win32.SetBackgroundColour(result.Handle(), appoptions.BackgroundColour.R, appoptions.BackgroundColour.G, appoptions.BackgroundColour.B) + } + result.SetSize(appoptions.Width, appoptions.Height) result.SetText(appoptions.Title) result.EnableSizable(!appoptions.DisableResize) @@ -163,6 +180,7 @@ func (w *Window) WndProc(msg uint32, wparam, lparam uintptr) uintptr { case w32.WM_SETTINGCHANGE: settingChanged := w32.UTF16PtrToString((*uint16)(unsafe.Pointer(lparam))) if settingChanged == "ImmersiveColorSet" { + w.themeChanged = true w.updateTheme() } return 0 @@ -174,6 +192,7 @@ func (w *Window) WndProc(msg uint32, wparam, lparam uintptr) uintptr { } case w32.WM_ACTIVATE: //if !w.frontendOptions.Frameless { + w.themeChanged = true if int(wparam) == w32.WA_INACTIVE { w.isActive = false w.updateTheme() @@ -262,3 +281,11 @@ func (w *Window) IsMaximised() bool { func (w *Window) IsMinimised() bool { return win32.IsWindowMinimised(w.Handle()) } + +func (w *Window) SetTheme(theme winoptions.Theme) { + w.theme = theme + w.themeChanged = true + w.Invoke(func() { + w.updateTheme() + }) +}