Skip to content

Commit

Permalink
implement theme variant auto-switching for Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
dweymouth committed Jul 27, 2024
1 parent 49ad989 commit 6f1b271
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 2 deletions.
3 changes: 2 additions & 1 deletion app/app_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"syscall"

"fyne.io/fyne/v2"
internalapp "fyne.io/fyne/v2/internal/app"
)

const notificationTemplate = `$title = "%s"
Expand Down Expand Up @@ -95,5 +96,5 @@ func runScript(name, script string) {
}
}
func watchTheme() {
// TODO monitor the Windows theme
go internalapp.WatchTheme(fyne.CurrentApp().Settings().(*settings).setupTheme)
}
27 changes: 26 additions & 1 deletion internal/app/theme_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@
package app

import (
"syscall"

"golang.org/x/sys/windows/registry"

"fyne.io/fyne/v2"
"fyne.io/fyne/v2/theme"
)

const themeRegKey = `SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize`

// DefaultVariant returns the systems default fyne.ThemeVariant.
// Normally, you should not need this. It is extracted out of the root app package to give the
// settings app access to it.
Expand All @@ -20,7 +24,7 @@ func DefaultVariant() fyne.ThemeVariant {
}

func isDark() bool {
k, err := registry.OpenKey(registry.CURRENT_USER, `SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize`, registry.QUERY_VALUE)
k, err := registry.OpenKey(registry.CURRENT_USER, themeRegKey, registry.QUERY_VALUE)
if err != nil { // older version of Windows will not have this key
return false
}
Expand All @@ -33,3 +37,24 @@ func isDark() bool {

return useLight == 0
}

func WatchTheme(onChanged func()) {
var regNotifyChangeKeyValue *syscall.Proc
if advapi32, err := syscall.LoadDLL("Advapi32.dll"); err == nil {
if p, err := advapi32.FindProc("RegNotifyChangeKeyValue"); err == nil {
regNotifyChangeKeyValue = p
}
}
if regNotifyChangeKeyValue == nil {
return
}
k, err := registry.OpenKey(registry.CURRENT_USER, themeRegKey, syscall.KEY_NOTIFY|registry.QUERY_VALUE)
if err != nil {
return // on older versions of windows the key may not exist
}
for {
// blocks until the reigstry key has been changed
regNotifyChangeKeyValue.Call(uintptr(k), 0, 0x00000001|0x00000004, 0, 0)
onChanged()
}
}

0 comments on commit 6f1b271

Please sign in to comment.