From 04b43be9b261f36edc4b0300a9784ec5dcbe1c52 Mon Sep 17 00:00:00 2001 From: Alexander Golubev Date: Thu, 8 Jan 2026 16:33:18 +0300 Subject: [PATCH] twin: better rules when to set custom_opacity flag This patch implements next peaces of logic: - If opacity is not completely opaque by default, changing it to opaque won't result it resetting the flag anymore. - Also in such a case the X11 property will be set for completely opaque windows as well. That way we can restore it in case of WM restart. - On WM initialization we check if the X11 opacity property has value we would expectto be left behind by previous WM instance and if it does we won't set the custom_opacity flag. Signed-off-by: Alexander Golubev --- twin/client.cpp | 21 +++++++++++++++++---- twin/client.h | 2 ++ twin/useractions.cpp | 9 +++++---- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/twin/client.cpp b/twin/client.cpp index e9e74e139..7cdf00a77 100644 --- a/twin/client.cpp +++ b/twin/client.cpp @@ -2801,8 +2801,8 @@ void Client::setOpacity(bool translucent, uint opacity) return; // xcompmgr does not like non solid desktops and the user could set it accidently by mouse scrolling // tqWarning("setting opacity for %d",tqt_xdisplay()); //rule out activated translulcency with 100% opacity - if (!translucent || opacity == Opacity::Opaque) - { + if ((!translucent || opacity == Opacity::Opaque) && !custom_opacity) + { // Note: if it is custom_opacity we want to keep the properties in case of WM restart opacity_ = Opacity::Opaque; XDeleteProperty (tqt_xdisplay(), frameId(), atoms->net_wm_window_opacity); XDeleteProperty (tqt_xdisplay(), window(), atoms->net_wm_window_opacity); // ??? frameId() is necessary for visible changes, window() is the winId() that would be set by apps - we set both to be sure the app knows what's currently displayd @@ -2827,7 +2827,12 @@ void Client::setShadowSize(uint shadowSize) uint Client::defaultOpacity() { - if (isActive() || (keepAbove() && options->keepAboveAsActive)) + return defaultOpacity(isActive() || (keepAbove() && options->keepAboveAsActive)); + } + +uint Client::defaultOpacity(bool active) + { + if (active) { if( ruleOpacityActive() ) return rule_opacity_active; @@ -2941,7 +2946,15 @@ bool Client::getWindowOpacity() //query translucency settings from X, returns tr if (result == Success && data && format == 32 ) { opacity_ = *reinterpret_cast< long* >( data ); - custom_opacity = true; + // Don't set custom_opacity flag during initialization if the opacity looks like what it + // supposed to be for the given type of window. As in a such case it is likely set by us + // and the WM is just restarting + if ( !(Workspace::self()->initializing() + && ( opacity_ == defaultOpacity(/*active*/ false) + || opacity_ == defaultOpacity(/*active*/ true) ) ) ) + { + custom_opacity = true; + } // setOpacity(opacity_ < 0xFFFFFFFF, opacity_); XFree ((char*)data); return true; diff --git a/twin/client.h b/twin/client.h index 4629dfb37..6ed72fcc8 100644 --- a/twin/client.h +++ b/twin/client.h @@ -332,6 +332,8 @@ class Client : public TQObject, public KDecorationDefines void setOpacity(bool translucent, uint opacity = 0); void setShadowSize(uint shadowSize); uint defaultOpacity(); + /// Returns default opacity for an active or inactive window depending on the argument + uint defaultOpacity(bool active); void updateOpacity(); void updateShadowSize(); bool hasCustomOpacity(){return custom_opacity;} diff --git a/twin/useractions.cpp b/twin/useractions.cpp index c573e8214..8051c9574 100644 --- a/twin/useractions.cpp +++ b/twin/useractions.cpp @@ -652,21 +652,22 @@ bool Client::performMouseCommand( Options::MouseCommand command, TQPoint globalP { if (opacity_ < Opacity::Opaque - Opacity::MouseStep) { - setOpacity(true, opacity_ + Opacity::MouseStep); custom_opacity = true; + setOpacity(true, opacity_ + Opacity::MouseStep); } else { - setOpacity(false, Opacity::Opaque); - custom_opacity = false; + if (defaultOpacity() == Opacity::Opaque) + custom_opacity = false; + setOpacity(true, Opacity::Opaque); } } break; case Options::MouseOpacityLess: if (opacity_ > 0) { - setOpacity(true, (opacity_ > Opacity::MouseStep) ? opacity_ - Opacity::MouseStep : Opacity::Transparent); custom_opacity = true; + setOpacity(true, (opacity_ > Opacity::MouseStep) ? opacity_ - Opacity::MouseStep : Opacity::Transparent); } break; case Options::MouseNothing: