On Monday 18 July 2011, Aaron J. Seigo wrote: > On Saturday, July 16, 2011 15:36:19 Martin Gräßlin wrote: > > The bug is much simpler - Plasma just simply fails to recognize that a > > compositing manager is active. I can see this each time I restart kwin > > (which is considerable often). In order to get translucent panels back, I > > have to kquitapp plasma-desktop, plasma-desktop. > > Plasma::Theme uses a KSelectionWatcher which watches _NET_WM_CM_S# where # is > the number of the default screen. > > i can imagine a few things going wrong with this: > > * the default screen # changes or even goes away completely; that could > render > the selection manager useless. why is the CM atom per screen again? *sigh*
Screen here is about traditional multi-head where you can have different window managers / compositing managers managing each screen. > * a race condition as Alex outlined. if kwin is indeed responding to each > xrandr even with a change in the CM, that seems like a perfect candidate for > event compression if at all possible: don't tell the world outside that > things > have changed until the events have stopped coming in. the timeout for this > shouldn't need to be long at all, so the user shouldn't see a big change at > all > > * KSelectionWatcher itself and/or kwin's setting of the atom could be broken. > in times past we've had isses where the KSelectionWatcher object simply did > not emit any signals at all when kwin changed compositing. I thought this bug was fixed, because I haven't seen it in a long time. But I realized that I still have a patch applied that I created a couple of years ago. It adds a compositingChanged() signal to KWindowSystem and makes Plasma::Theme use it. It also uses Xfixes instead of KSelectionWatcher to monitor the selection. I never committed the patch because Lubos didn't like the idea. IIRC the reason was that the signal would be emitted before the compositing plugins are initialized in kwin. I have attached the diff in case it fixes the problem for those who are still seeing it. Regards, Fredrik
diff --git a/kdeui/windowmanagement/kwindowsystem.h b/kdeui/windowmanagement/kwindowsystem.h index dba1da4..6b79cb0 100644 --- a/kdeui/windowmanagement/kwindowsystem.h +++ b/kdeui/windowmanagement/kwindowsystem.h @@ -621,6 +621,12 @@ Q_SIGNALS: */ void showingDesktopChanged( bool showing ); + /** + * Compositing was enabled or disabled. + * @since 4.4 + */ + void compositingChanged( bool enabled ); + protected: virtual void connectNotify( const char* signal ); diff --git a/kdeui/windowmanagement/kwindowsystem_x11.cpp b/kdeui/windowmanagement/kwindowsystem_x11.cpp index 51b8e56..741393c 100644 --- a/kdeui/windowmanagement/kwindowsystem_x11.cpp +++ b/kdeui/windowmanagement/kwindowsystem_x11.cpp @@ -36,6 +36,12 @@ #include <QtGui/QX11Info> #include <X11/Xatom.h> +#include <config.h> + +#ifdef HAVE_XFIXES +#include <X11/extensions/Xfixes.h> +#endif + class KWindowSystemStaticContainer { public: KWindowSystemStaticContainer() : d(0) {} @@ -46,6 +52,8 @@ public: K_GLOBAL_STATIC(KWindowSystemStaticContainer, g_kwmInstanceContainer) +static Atom net_wm_cm; +static void create_atoms( Display* dpy = QX11Info::display() ); static unsigned long windows_properties[ 2 ] = { NET::ClientList | NET::ClientListStacking | NET::Supported | @@ -92,7 +100,10 @@ public: QList<StrutData> strutWindows; QList<WId> possibleStrutWindows; bool strutSignalConnected; + bool compositingEnabled; + bool haveXfixes; int what; + int xfixesEventBase; bool mapViewport(); void addClient(Window); @@ -110,10 +121,23 @@ KWindowSystemPrivate::KWindowSystemPrivate(int _what) _what >= KWindowSystem::INFO_WINDOWS ? windows_properties : desktop_properties, 2, -1, false ), strutSignalConnected( false ), + haveXfixes( false ), what( _what ) { KSystemEventFilter::installEventFilter(this); (void ) qApp->desktop(); //trigger desktop widget creation to select root window events + +#ifdef HAVE_XFIXES + int errorBase; + if ((haveXfixes = XFixesQueryExtension(QX11Info::display(), &xfixesEventBase, &errorBase))) { + create_atoms(); + XFixesSelectSelectionInput(QX11Info::display(), winId(), net_wm_cm, + XFixesSetSelectionOwnerNotifyMask | + XFixesSelectionWindowDestroyNotifyMask | + XFixesSelectionClientCloseNotifyMask); + compositingEnabled = XGetSelectionOwner(QX11Info::display(), net_wm_cm) != None; + } +#endif } // not virtual, but it's called directly only from init() @@ -127,6 +151,18 @@ bool KWindowSystemPrivate::x11Event( XEvent * ev ) { KWindowSystem* s_q = KWindowSystem::self(); +#ifdef HAVE_XFIXES + if ( ev->type == xfixesEventBase + XFixesSelectionNotify && ev->xany.window == winId() ) { + XFixesSelectionNotifyEvent *event = reinterpret_cast<XFixesSelectionNotifyEvent*>(ev); + bool haveOwner = event->owner != None; + if (compositingEnabled != haveOwner) { + compositingEnabled = haveOwner; + emit s_q->compositingChanged( compositingEnabled ); + } + return true; + } +#endif + if ( ev->xany.window == QX11Info::appRootWindow() ) { int old_current_desktop = currentDesktop(); WId old_active_window = activeWindow(); @@ -273,9 +309,8 @@ static bool atoms_created = false; static Atom kde_wm_change_state; static Atom _wm_protocols; static Atom kwm_utf8_string; -static Atom net_wm_cm; -static void create_atoms( Display* dpy = QX11Info::display()) { +static void create_atoms( Display* dpy ) { if (!atoms_created){ const int max = 20; Atom* atoms[max]; @@ -759,8 +794,13 @@ void KWindowSystem::lowerWindow( WId win ) bool KWindowSystem::compositingActive() { if( QX11Info::display()) { - create_atoms(); - return XGetSelectionOwner( QX11Info::display(), net_wm_cm ) != None; + init( INFO_BASIC ); + if (s_d_func()->haveXfixes) { + return s_d_func()->compositingEnabled; + } else { + create_atoms(); + return XGetSelectionOwner( QX11Info::display(), net_wm_cm ); + } } else { // work even without QApplication instance Display* dpy = XOpenDisplay( NULL ); create_atoms( dpy ); diff --git a/plasma/theme.cpp b/plasma/theme.cpp index c7cc7a3..e21e818 100644 --- a/plasma/theme.cpp +++ b/plasma/theme.cpp @@ -97,23 +97,13 @@ public: ThemeConfig config; cacheTheme = config.cacheTheme(); -#ifdef Q_WS_X11 - Display *dpy = QX11Info::display(); - int screen = DefaultScreen(dpy); - locolor = DefaultDepth(dpy, screen) < 16; - - if (!locolor) { - char net_wm_cm_name[100]; - sprintf(net_wm_cm_name, "_NET_WM_CM_S%d", screen); - compositeWatch = new KSelectionWatcher(net_wm_cm_name, -1, q); - QObject::connect(compositeWatch, SIGNAL(newOwner(Window)), q, SLOT(compositingChanged())); - QObject::connect(compositeWatch, SIGNAL(lostOwner()), q, SLOT(compositingChanged())); + if (QPixmap::defaultDepth() > 8) { + QObject::connect(KWindowSystem::self(), SIGNAL(compositingChanged(bool)), q, SLOT(compositingChanged(bool))); //watch for blur effect property changes as well effectWatcher = 0; effectWatcher = new EffectWatcher("_KDE_NET_WM_BLUR_BEHIND_REGION"); QObject::connect(effectWatcher, SIGNAL(blurBehindChanged(bool)), q, SLOT(blurBehindChanged(bool))); } -#endif saveTimer = new QTimer(q); saveTimer->setSingleShot(true); @@ -149,7 +139,7 @@ public: } QString findInTheme(const QString &image, const QString &theme) const; - void compositingChanged(); + void compositingChanged(bool active); void discardCache(CacheTypes caches); void scheduledCacheUpdate(); void colorsChanged(); @@ -266,12 +256,11 @@ QString ThemePrivate::findInTheme(const QString &image, const QString &theme) co return search; } -void ThemePrivate::compositingChanged() +void ThemePrivate::compositingChanged(bool active) { #ifdef Q_WS_X11 - bool nowCompositingActive = compositeWatch->owner() != None; - if (compositingActive != nowCompositingActive) { - compositingActive = nowCompositingActive; + if (compositingActive != active) { + compositingActive = active; discardCache(PixmapCache | SvgElementsCache); emit q->themeChanged(); } diff --git a/plasma/theme.h b/plasma/theme.h index e4618e2..b511827 100644 --- a/plasma/theme.h +++ b/plasma/theme.h @@ -397,7 +397,7 @@ class PLASMA_EXPORT Theme : public QObject friend class ThemePrivate; ThemePrivate *const d; - Q_PRIVATE_SLOT(d, void compositingChanged()) + Q_PRIVATE_SLOT(d, void compositingChanged(bool)) Q_PRIVATE_SLOT(d, void colorsChanged()) Q_PRIVATE_SLOT(d, void blurBehindChanged(bool blur)) Q_PRIVATE_SLOT(d, void settingsFileChanged(const QString &))
_______________________________________________ Plasma-devel mailing list Plasma-devel@kde.org https://mail.kde.org/mailman/listinfo/plasma-devel