package main import ( "image/color" "os/exec" "strings" "fyne.io/fyne/v2" "fyne.io/fyne/v2/theme" ) // CustomTheme structure type CustomTheme struct { background color.Color primary color.Color isDark bool } var _ fyne.Theme = (*CustomTheme)(nil) func (t *CustomTheme) Color(name fyne.ThemeColorName, variant fyne.ThemeVariant) color.Color { switch name { case theme.ColorNameBackground: return t.background case theme.ColorNamePrimary: return t.primary default: return theme.DefaultTheme().Color(name, variant) } } func (t *CustomTheme) Font(style fyne.TextStyle) fyne.Resource { return theme.DefaultTheme().Font(style) } func (t *CustomTheme) Icon(name fyne.ThemeIconName) fyne.Resource { return theme.DefaultTheme().Icon(name) } func (t *CustomTheme) Size(name fyne.ThemeSizeName) float32 { return theme.DefaultTheme().Size(name) } func applyThemeToApp(a fyne.App, background, primary [3]uint8, isDark bool) { customTheme := &CustomTheme{ background: color.NRGBA{R: background[0], G: background[1], B: background[2], A: 0xff}, primary: color.NRGBA{R: primary[0], G: primary[1], B: primary[2], A: 0xff}, isDark: isDark, } a.Settings().SetTheme(customTheme) } // ApplyTheme applies the detected GTK theme to the Fyne app func ApplyTheme(a fyne.App) { // Default light theme settings colBackground := [3]uint8{245, 245, 245} colTheme := [3]uint8{0, 120, 215} isDark := false // Detect GTK Theme isDarkGTK, err := getGTKTheme() if err == nil && isDarkGTK { colBackground = [3]uint8{10, 10, 10} isDark = true } applyThemeToApp(a, colBackground, colTheme, isDark) } // getGTKTheme detects if the current GTK theme is dark func getGTKTheme() (bool, error) { cmd := exec.Command("dconf", "read", "/org/gnome/desktop/interface/gtk-theme") output, err := cmd.Output() if err != nil { return false, err } themeName := strings.Trim(string(output), "'\n ") return strings.Contains(strings.ToLower(themeName), "dark"), nil }