@@ -446,12 +446,13 @@ func getWindowPositionXdotool() (int, int) {
446446
447447// setWindowOpacity applies transparency to the widget window.
448448//
449- // On Wayland, Fyne renders via EGL/OpenGL and the compositor handles
450- // transparency through the alpha channel. We use the Fyne theme's
451- // background color alpha to achieve background-only transparency (similar
452- // to Windows color-key approach) rather than whole-window opacity .
449+ // On both Wayland and X11, transparency is achieved by setting the alpha
450+ // channel of the Fyne theme's background color. This provides background-only
451+ // transparency — the desktop shows through the background while text and
452+ // icons remain fully opaque .
453453//
454- // On X11 we fall back to _NET_WM_WINDOW_OPACITY via xprop.
454+ // On X11, any existing _NET_WM_WINDOW_OPACITY hint is removed to prevent
455+ // the compositor from double-applying whole-window transparency.
455456func setWindowOpacity (opacityPercent int ) {
456457 if isWayland () {
457458 setWindowOpacityWayland (opacityPercent )
@@ -460,75 +461,47 @@ func setWindowOpacity(opacityPercent int) {
460461 }
461462}
462463
463- // setWindowOpacityWayland uses Fyne's theme alpha channel for transparency.
464- // On Wayland, the compositor respects the alpha channel of the EGL/OpenGL
465- // surface. We set the background color's alpha value to achieve background-only
466- // transparency — text, icons, and other content remain fully opaque.
467- // This is equivalent to the Windows color-key approach in visual result.
464+ // setWindowOpacityWayland controls background transparency on Wayland.
465+ // The opacity setting controls the alpha channel of the dark background,
466+ // allowing the desktop to show through while keeping text/icons fully opaque.
467+ //
468+ // 100% → fully opaque dark background
469+ // 75% → slightly transparent
470+ // 50% → semi-transparent
471+ // 25% → mostly transparent (desktop visible through background)
468472func setWindowOpacityWayland (opacityPercent int ) {
469- if opacityPercent >= 100 {
470- SetTransparencyActive (false )
471- SetLinuxOpacityAlpha (100 )
472- log .Printf ("Linux/Wayland: transparency disabled (100%% opaque)" )
473- return
474- }
475-
476- // Set the alpha value for the background color.
477- SetLinuxOpacityAlpha (opacityPercent )
478- SetTransparencyActive (true )
479- log .Printf ("Linux/Wayland: background transparency set to %d%% alpha" , opacityPercent )
473+ SetLinuxBackgroundShade (opacityPercent )
474+ log .Printf ("Linux/Wayland: background alpha set for opacity %d%%" , opacityPercent )
480475}
481476
482- // setWindowOpacityX11 applies whole-window transparency on X11 via xprop.
477+ // setWindowOpacityX11 controls background transparency on X11.
478+ // Like Wayland, we use the Fyne theme's background alpha channel for
479+ // background-only transparency, keeping text and icons fully opaque.
480+ // The _NET_WM_WINDOW_OPACITY hint is removed so the compositor doesn't
481+ // double-apply whole-window transparency.
483482func setWindowOpacityX11 (opacityPercent int ) {
484- x11Percent := mapOpacityForDisplay (opacityPercent )
483+ SetLinuxBackgroundShade (opacityPercent )
485484
486485 go func () {
487486 time .Sleep (600 * time .Millisecond )
488487
489488 if _ , err := exec .LookPath ("xprop" ); err != nil {
490- log .Printf ("Linux/X11: xprop not found, cannot set opacity" )
491- return
492- }
493-
494- if x11Percent >= 100 {
495- cmd := exec .Command ("xprop" , "-name" , widgetTitle , "-remove" , "_NET_WM_WINDOW_OPACITY" )
496- if err := cmd .Run (); err != nil {
497- log .Printf ("Linux/X11: failed to remove _NET_WM_WINDOW_OPACITY: %v" , err )
498- }
489+ log .Printf ("Linux/X11: xprop not found, relying on theme alpha only" )
499490 return
500491 }
501492
502- opacity := uint64 (x11Percent ) * 0xFFFFFFFF / 100
503- val := strconv .FormatUint (opacity , 10 )
504-
505- cmd := exec .Command ("xprop" , "-name" , widgetTitle ,
506- "-f" , "_NET_WM_WINDOW_OPACITY" , "32c" ,
507- "-set" , "_NET_WM_WINDOW_OPACITY" , val )
493+ // Remove any whole-window opacity hint so only the background alpha
494+ // (set via the theme) controls transparency.
495+ cmd := exec .Command ("xprop" , "-name" , widgetTitle , "-remove" , "_NET_WM_WINDOW_OPACITY" )
508496 if err := cmd .Run (); err != nil {
509- log .Printf ("Linux/X11: xprop opacity failed: %v" , err )
510- return
497+ log .Printf ("Linux/X11: failed to remove _NET_WM_WINDOW_OPACITY: %v" , err )
511498 }
512- log .Printf ("Linux/X11: set window opacity to %d%% (user: %d%%)" , x11Percent , opacityPercent )
499+ log .Printf ("Linux/X11: background alpha set for opacity %d%%" , opacityPercent )
513500 }()
514501}
515502
516- // mapOpacityForDisplay maps user-facing opacity percentages to display
517- // values that keep content readable when using whole-window opacity.
518- func mapOpacityForDisplay (opacityPercent int ) int {
519- switch {
520- case opacityPercent >= 100 :
521- return 100
522- case opacityPercent >= 75 :
523- return 85
524- case opacityPercent >= 50 :
525- return 70
526- case opacityPercent >= 25 :
527- return 55
528- default :
529- return 55
530- }
531- }
503+ // (mapOpacityForDisplay removed — no longer needed; transparency is now
504+ // handled via the theme's background alpha channel on both X11 and Wayland.)
532505
533506// ---------------------------------------------------------------------------
534507// Monitor enumeration
0 commit comments