5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-02 19:50:15 +08:00

Improve theme change at runtime (#1473)

* Improve theme change at runtime

* Handle change to dark mode

* Refactor theme calculation

* Ensure theme is updated for WM_ACTIVATE and WM_SETTINGCHANGE events
This commit is contained in:
Lea Anthony 2022-06-22 08:34:41 +10:00 committed by GitHub
parent 381909696b
commit 1687906376
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 29 deletions

View File

@ -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 {

View File

@ -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 {

View File

@ -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()
})
}