Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix settings app system theme preview #4931

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 9 additions & 18 deletions app/app_desktop_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ package app
#include <AppKit/AppKit.h>

bool isBundled();
bool isDarkMode();
void watchTheme();
*/
import "C"
Expand All @@ -20,15 +19,12 @@ import (
"path/filepath"

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

// SetSystemTrayMenu creates a system tray item and attaches the specified menu.
// By default this will use the application icon.
func (a *fyneApp) SetSystemTrayMenu(menu *fyne.Menu) {
if desk, ok := a.Driver().(systrayDriver); ok {
desk.SetSystemTrayMenu(menu)
}
func (a *fyneApp) OpenURL(url *url.URL) error {
cmd := exec.Command("open", url.String())
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
return cmd.Run()
}

// SetSystemTrayIcon sets a custom image for the system tray icon.
Expand All @@ -37,11 +33,12 @@ func (a *fyneApp) SetSystemTrayIcon(icon fyne.Resource) {
a.Driver().(systrayDriver).SetSystemTrayIcon(icon)
}

func defaultVariant() fyne.ThemeVariant {
if C.isDarkMode() {
return theme.VariantDark
// SetSystemTrayMenu creates a system tray item and attaches the specified menu.
// By default this will use the application icon.
func (a *fyneApp) SetSystemTrayMenu(menu *fyne.Menu) {
if desk, ok := a.Driver().(systrayDriver); ok {
desk.SetSystemTrayMenu(menu)
}
return theme.VariantLight
}

func rootConfigDir() string {
Expand All @@ -51,12 +48,6 @@ func rootConfigDir() string {
return filepath.Join(desktopConfig, "fyne")
}

func (a *fyneApp) OpenURL(url *url.URL) error {
cmd := exec.Command("open", url.String())
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
return cmd.Run()
}

//export themeChanged
func themeChanged() {
fyne.CurrentApp().Settings().(*settings).setupTheme()
Expand Down
5 changes: 0 additions & 5 deletions app/app_desktop_darwin.m
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@

#import <Foundation/Foundation.h>

bool isDarkMode() {
NSString *style = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];
return [@"Dark" isEqualToString:style];
}

void watchTheme() {
[[NSDistributedNotificationCenter defaultCenter] addObserverForName:@"AppleInterfaceThemeChangedNotification" object:nil queue:nil
usingBlock:^(NSNotification *note) {
Expand Down
5 changes: 2 additions & 3 deletions app/app_mobile.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,17 @@ package app

import (
"fyne.io/fyne/v2"
internalapp "fyne.io/fyne/v2/internal/app"
"fyne.io/fyne/v2/internal/driver/mobile"
)

var systemTheme fyne.ThemeVariant

// NewWithID returns a new app instance using the appropriate runtime driver.
// The ID string should be globally unique to this app.
func NewWithID(id string) fyne.App {
d := mobile.NewGoMobileDriver()
a := newAppWithDriver(d, id)
d.(mobile.ConfiguredDriver).SetOnConfigurationChanged(func(c *mobile.Configuration) {
systemTheme = c.SystemTheme
internalapp.SystemTheme = c.SystemTheme

a.Settings().(*settings).setupTheme()
})
Expand Down
4 changes: 0 additions & 4 deletions app/app_mobile_and.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,6 @@ func (a *fyneApp) SendNotification(n *fyne.Notification) {
})
}

func defaultVariant() fyne.ThemeVariant {
return systemTheme
}

func rootConfigDir() string {
filesDir := os.Getenv("FILESDIR")
if filesDir == "" {
Expand Down
6 changes: 0 additions & 6 deletions app/app_mobile_ios.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ import (
"net/url"
"path/filepath"
"unsafe"

"fyne.io/fyne/v2"
)

func rootConfigDir() string {
Expand All @@ -33,7 +31,3 @@ func (a *fyneApp) OpenURL(url *url.URL) error {

return nil
}

func defaultVariant() fyne.ThemeVariant {
return systemTheme
}
7 changes: 1 addition & 6 deletions app/app_other.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build ci || (!linux && !darwin && !windows && !freebsd && !openbsd && !netbsd && !wasm && !test_web_driver)
//go:build ci || (mobile && !android && !ios) || (!linux && !darwin && !windows && !freebsd && !openbsd && !netbsd && !wasm && !test_web_driver)

package app

Expand All @@ -9,13 +9,8 @@ import (
"path/filepath"

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

func defaultVariant() fyne.ThemeVariant {
return theme.VariantDark
}

func rootConfigDir() string {
return filepath.Join(os.TempDir(), "fyne-test")
}
Expand Down
12 changes: 0 additions & 12 deletions app/app_theme_web.go

This file was deleted.

25 changes: 0 additions & 25 deletions app/app_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ import (
"strings"
"syscall"

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

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

const notificationTemplate = `$title = "%s"
Expand All @@ -31,28 +28,6 @@ $xml.LoadXml($toastXml.OuterXml)
$toast = [Windows.UI.Notifications.ToastNotification]::new($xml)
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier("%s").Show($toast);`

func isDark() bool {
k, err := registry.OpenKey(registry.CURRENT_USER, `SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize`, registry.QUERY_VALUE)
if err != nil { // older version of Windows will not have this key
return false
}
defer k.Close()

useLight, _, err := k.GetIntegerValue("AppsUseLightTheme")
if err != nil { // older version of Windows will not have this value
return false
}

return useLight == 0
}

func defaultVariant() fyne.ThemeVariant {
if isDark() {
return theme.VariantDark
}
return theme.VariantLight
}

func rootConfigDir() string {
homeDir, _ := os.UserHomeDir()

Expand Down
13 changes: 4 additions & 9 deletions app/app_xdg.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build !ci && !wasm && !test_web_driver && (linux || openbsd || freebsd || netbsd) && !android
//go:build !ci && !wasm && !test_web_driver && !android && !ios && !mobile && (linux || openbsd || freebsd || netbsd)

package app

Expand All @@ -16,16 +16,11 @@ import (
"github.com/rymdport/portal/settings/appearance"

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

var currentVariant atomic.Uint64

func defaultVariant() fyne.ThemeVariant {
return fyne.ThemeVariant(currentVariant.Load())
}

func (a *fyneApp) OpenURL(url *url.URL) error {
if build.IsFlatpak {
err := openuri.OpenURI("", url.String(), nil)
Expand Down Expand Up @@ -123,11 +118,11 @@ func rootConfigDir() string {
func watchTheme() {
go func() {
// with portal this may not be immediate, so we update a cache instead
currentVariant.Store(uint64(findFreedesktopColorScheme()))
internalapp.CurrentVariant.Store(uint64(findFreedesktopColorScheme()))

portalSettings.OnSignalSettingChanged(func(changed portalSettings.Changed) {
if changed.Namespace == "org.freedesktop.appearance" && changed.Key == "color-scheme" {
currentVariant.Store(uint64(findFreedesktopColorScheme()))
internalapp.CurrentVariant.Store(uint64(findFreedesktopColorScheme()))
fyne.CurrentApp().Settings().(*settings).setupTheme()
}
})
Expand Down
3 changes: 2 additions & 1 deletion app/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"sync"

"fyne.io/fyne/v2"
internalapp "fyne.io/fyne/v2/internal/app"
"fyne.io/fyne/v2/internal/build"
"fyne.io/fyne/v2/theme"
)
Expand Down Expand Up @@ -152,7 +153,7 @@ func (s *settings) setupTheme() {
name = env
}

variant := defaultVariant()
variant := internalapp.DefaultVariant()
effectiveTheme := s.theme
if !s.themeSpecified {
effectiveTheme = s.loadSystemTheme()
Expand Down
7 changes: 4 additions & 3 deletions app/settings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"testing"

"fyne.io/fyne/v2"
internalapp "fyne.io/fyne/v2/internal/app"
"fyne.io/fyne/v2/internal/build"
internalTest "fyne.io/fyne/v2/internal/test"
"fyne.io/fyne/v2/test"
Expand Down Expand Up @@ -43,7 +44,7 @@ func TestSettingsLoad(t *testing.T) {
func TestOverrideTheme(t *testing.T) {
set := &settings{}
set.setupTheme()
assert.Equal(t, defaultVariant(), set.ThemeVariant())
assert.Equal(t, internalapp.DefaultVariant(), set.ThemeVariant())

set.schema.ThemeName = "light"
set.setupTheme()
Expand All @@ -57,7 +58,7 @@ func TestOverrideTheme(t *testing.T) {

set = &settings{}
set.setupTheme()
assert.Equal(t, defaultVariant(), set.ThemeVariant())
assert.Equal(t, internalapp.DefaultVariant(), set.ThemeVariant())

err := os.Setenv("FYNE_THEME", "light")
if err != nil {
Expand Down Expand Up @@ -106,7 +107,7 @@ func TestCustomTheme(t *testing.T) {

set.setupTheme()
assert.True(t, set.Theme() == ctheme)
assert.Equal(t, defaultVariant(), set.ThemeVariant())
assert.Equal(t, internalapp.DefaultVariant(), set.ThemeVariant())

err := set.loadFromFile(filepath.Join("testdata", "light-theme.json"))
if err != nil {
Expand Down
23 changes: 15 additions & 8 deletions cmd/fyne_settings/settings/appearance.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,18 @@ import (
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
internalapp "fyne.io/fyne/v2/internal/app"
intWidget "fyne.io/fyne/v2/internal/widget"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
)

const (
systemThemeName = "system default"
themeNameDark = "dark"
themeNameLight = "light"
themeNameSystem = ""
themeNameSystemLabel = "system default"
)

// Settings gives access to user interfaces to control Fyne settings
Expand Down Expand Up @@ -56,11 +60,11 @@ func (s *Settings) LoadAppearanceScreen(w fyne.Window) fyne.CanvasObject {
s.preview = s.createPreview()

def := s.fyneSettings.ThemeName
themeNames := []string{"dark", "light"}
themeNames := []string{themeNameDark, themeNameLight}
if runtime.GOOS == "darwin" || runtime.GOOS == "windows" {
themeNames = append(themeNames, systemThemeName)
if s.fyneSettings.ThemeName == "" {
def = systemThemeName
themeNames = append(themeNames, themeNameSystemLabel)
if s.fyneSettings.ThemeName == themeNameSystem {
def = themeNameSystemLabel
}
}
themes := widget.NewSelect(themeNames, s.chooseTheme)
Expand Down Expand Up @@ -102,8 +106,8 @@ func (s *Settings) LoadAppearanceScreen(w fyne.Window) fyne.CanvasObject {
}

func (s *Settings) chooseTheme(name string) {
if name == systemThemeName {
name = ""
if name == themeNameSystemLabel {
name = themeNameSystem
}
s.fyneSettings.ThemeName = name

Expand Down Expand Up @@ -242,8 +246,11 @@ type previewTheme struct {

func (p *previewTheme) Color(n fyne.ThemeColorName, _ fyne.ThemeVariant) color.Color {
variant := theme.VariantDark
if p.s.fyneSettings.ThemeName == "light" {
switch p.s.fyneSettings.ThemeName {
case themeNameLight:
variant = theme.VariantLight
case themeNameSystem:
variant = internalapp.DefaultVariant()
}

switch n {
Expand Down
27 changes: 27 additions & 0 deletions internal/app/theme_darwin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//go:build !ios && !wasm && !test_web_driver

package app

/*
#cgo CFLAGS: -x objective-c
#cgo LDFLAGS: -framework Foundation

#include <AppKit/AppKit.h>

bool isDarkMode();
*/
import "C"
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/theme"
)

// 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.
func DefaultVariant() fyne.ThemeVariant {
if C.isDarkMode() {
return theme.VariantDark
}
return theme.VariantLight
}
8 changes: 8 additions & 0 deletions internal/app/theme_darwin.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//go:build !ci && !ios

#import <Foundation/Foundation.h>

bool isDarkMode() {
NSString *style = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];
return [@"Dark" isEqualToString:style];
}
18 changes: 18 additions & 0 deletions internal/app/theme_mobile.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//go:build android || ios || mobile

package app

import (
"fyne.io/fyne/v2"
)

// SystemTheme contains the system’s theme variant.
// It is intended for internal use, only!
var SystemTheme fyne.ThemeVariant

// 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.
func DefaultVariant() fyne.ThemeVariant {
return SystemTheme
}
Loading