system.go RawHistoryFolder
1package theme
2
3import (
4 "os"
5 "os/exec"
6 "strings"
7
8 "github.com/jwijenbergh/puregotk/v4/gtk"
9)
10
11// DetectSystemDarkMode checks if the system prefers dark mode.
12// It checks multiple sources in order of preference:
13// 1. GTK_THEME environment variable (contains "dark")
14// 2. GNOME gsettings color-scheme (prefer-dark/prefer-light)
15// 3. GTK Settings gtk-application-prefer-dark-theme property
16// Returns true if dark mode is preferred.
17func DetectSystemDarkMode() bool {
18 // Check GTK_THEME environment variable first
19 gtkTheme := os.Getenv("GTK_THEME")
20 if gtkTheme != "" {
21 if strings.Contains(strings.ToLower(gtkTheme), "dark") {
22 return true
23 }
24 // If GTK_THEME is set but doesn't contain "dark", it's likely light
25 return false
26 }
27
28 // Check GNOME gsettings color-scheme (modern GNOME/GTK4 method)
29 if colorScheme := getGsettingsColorScheme(); colorScheme != "" {
30 switch colorScheme {
31 case "prefer-dark":
32 return true
33 case "prefer-light":
34 return false
35 // "default" falls through to next check
36 }
37 }
38
39 // Try GTK Settings
40 settings := gtk.SettingsGetDefault()
41 if settings != nil {
42 // gtk-application-prefer-dark-theme is a boolean property
43 preferDark := settings.GetPropertyGtkApplicationPreferDarkTheme()
44 return preferDark
45 }
46
47 // Default to dark mode if detection fails (better for eyes)
48 return true
49}
50
51// getGsettingsColorScheme queries GNOME gsettings for the color-scheme preference.
52// Returns "prefer-dark", "prefer-light", "default", or empty string on error.
53func getGsettingsColorScheme() string {
54 cmd := exec.Command("gsettings", "get", "org.gnome.desktop.interface", "color-scheme")
55 output, err := cmd.Output()
56 if err != nil {
57 return ""
58 }
59 // Output is like "'prefer-dark'\n", strip quotes and whitespace
60 result := strings.TrimSpace(string(output))
61 result = strings.Trim(result, "'\"")
62 return result
63}
64
65// ResolveColorScheme determines the effective dark mode preference.
66// It takes the config value ("prefer-dark", "prefer-light", "default")
67// and resolves "default" to the system preference.
68func ResolveColorScheme(configScheme string) bool {
69 switch strings.ToLower(configScheme) {
70 case "prefer-dark", "dark":
71 return true
72 case "prefer-light", "light":
73 return false
74 default:
75 // "default" or empty - follow system
76 return DetectSystemDarkMode()
77 }
78}