@@ -2,6 +2,7 @@ package ui
22
33import (
44 "image/color"
5+ "runtime"
56 "sync/atomic"
67
78 "fyne.io/fyne/v2"
@@ -16,6 +17,14 @@ var transparencyKey = color.NRGBA{R: 1, G: 1, B: 1, A: 255}
1617// transparencyActive is 1 when a color-key background should be used.
1718var transparencyActive atomic.Int32
1819
20+ // linuxBgShade stores the background RGB value for Linux (0=black, 255=white).
21+ // Controlled by the opacity setting: 100% = fully dark (30), 25% = lighter (90).
22+ var linuxBgShade atomic.Int32
23+
24+ func init () {
25+ linuxBgShade .Store (30 ) // default: dark background
26+ }
27+
1928// SetTransparencyActive switches the background color key on or off.
2029func SetTransparencyActive (active bool ) {
2130 if active {
@@ -25,8 +34,32 @@ func SetTransparencyActive(active bool) {
2534 }
2635}
2736
28- // widgetTheme is a Fyne theme that replaces the window background with the
29- // color key when transparency is active, leaving all other colors unchanged.
37+ // SetLinuxBackgroundShade sets the Linux background darkness level.
38+ // opacityPercent maps to background shade:
39+ //
40+ // 100% → RGB(30,30,30) — fully dark, content most visible
41+ // 75% → RGB(50,50,50) — slightly lighter
42+ // 50% → RGB(70,70,70) — medium grey
43+ // 25% → RGB(90,90,90) — lighter grey
44+ func SetLinuxBackgroundShade (opacityPercent int ) {
45+ var shade int
46+ switch {
47+ case opacityPercent >= 100 :
48+ shade = 30
49+ case opacityPercent >= 75 :
50+ shade = 50
51+ case opacityPercent >= 50 :
52+ shade = 70
53+ default :
54+ shade = 90
55+ }
56+ linuxBgShade .Store (int32 (shade ))
57+ }
58+
59+ // widgetTheme is a Fyne theme that:
60+ // - On Windows: replaces the background with a color-key when transparency is active
61+ // - On Linux: always uses a dark background (ignoring system light/dark preference)
62+ // to ensure the widget looks consistent and native
3063type widgetTheme struct {
3164 base fyne.Theme
3265}
@@ -37,12 +70,33 @@ func NewWidgetTheme(base fyne.Theme) fyne.Theme {
3770}
3871
3972func (t * widgetTheme ) Color (name fyne.ThemeColorName , variant fyne.ThemeVariant ) color.Color {
73+ // Windows: color-key transparency when active.
4074 if transparencyActive .Load () == 1 {
4175 switch name {
4276 case theme .ColorNameBackground , theme .ColorNameOverlayBackground :
4377 return transparencyKey
4478 }
4579 }
80+
81+ // Linux: always use dark variant colors for a consistent widget appearance,
82+ // regardless of the system theme (light/dark). The background shade is
83+ // controlled by the opacity setting.
84+ if runtime .GOOS == "linux" {
85+ switch name {
86+ case theme .ColorNameBackground , theme .ColorNameOverlayBackground :
87+ shade := uint8 (linuxBgShade .Load ())
88+ return color.NRGBA {R : shade , G : shade , B : shade , A : 255 }
89+ case theme .ColorNameForeground :
90+ return color.NRGBA {R : 255 , G : 255 , B : 255 , A : 255 }
91+ case theme .ColorNameDisabled :
92+ return color.NRGBA {R : 180 , G : 180 , B : 180 , A : 255 }
93+ case theme .ColorNameSeparator :
94+ return color.NRGBA {R : 80 , G : 80 , B : 80 , A : 255 }
95+ }
96+ // For all other colors, force dark variant.
97+ return t .base .Color (name , theme .VariantDark )
98+ }
99+
46100 return t .base .Color (name , variant )
47101}
48102
0 commit comments