diff --git a/effects.cpp b/effects.cpp --- a/effects.cpp +++ b/effects.cpp @@ -231,6 +231,7 @@ m_managedProperties.insert(*it, atom); registerPropertyType(atom, true); } + emit xcbConnectionChanged(); } ); diff --git a/effects/backgroundcontrast/contrast.cpp b/effects/backgroundcontrast/contrast.cpp --- a/effects/backgroundcontrast/contrast.cpp +++ b/effects/backgroundcontrast/contrast.cpp @@ -58,6 +58,13 @@ connect(effects, SIGNAL(windowDeleted(KWin::EffectWindow*)), this, SLOT(slotWindowDeleted(KWin::EffectWindow*))); connect(effects, SIGNAL(propertyNotify(KWin::EffectWindow*,long)), this, SLOT(slotPropertyNotify(KWin::EffectWindow*,long))); connect(effects, SIGNAL(screenGeometryChanged(QSize)), this, SLOT(slotScreenGeometryChanged())); + connect(effects, &EffectsHandler::xcbConnectionChanged, this, + [this] { + if (shader && shader->isValid()) { + net_wm_contrast_region = effects->announceSupportProperty(s_contrastAtomName, this); + } + } + ); // Fetch the contrast regions for all windows foreach (EffectWindow *window, effects->stackingOrder()) @@ -92,27 +99,30 @@ { QRegion region; float colorTransform[16]; + QByteArray value; + + if (net_wm_contrast_region != XCB_ATOM_NONE) { + value = w->readProperty(net_wm_contrast_region, net_wm_contrast_region, 32); + + if (value.size() > 0 && !((value.size() - (16 * sizeof(uint32_t))) % ((4 * sizeof(uint32_t))))) { + const uint32_t *cardinals = reinterpret_cast(value.constData()); + const float *floatCardinals = reinterpret_cast(value.constData()); + unsigned int i = 0; + for (; i < ((value.size() - (16 * sizeof(uint32_t)))) / sizeof(uint32_t);) { + int x = cardinals[i++]; + int y = cardinals[i++]; + int w = cardinals[i++]; + int h = cardinals[i++]; + region += QRect(x, y, w, h); + } - const QByteArray value = w->readProperty(net_wm_contrast_region, net_wm_contrast_region, 32); - - if (value.size() > 0 && !((value.size() - (16 * sizeof(uint32_t))) % ((4 * sizeof(uint32_t))))) { - const uint32_t *cardinals = reinterpret_cast(value.constData()); - const float *floatCardinals = reinterpret_cast(value.constData()); - unsigned int i = 0; - for (; i < ((value.size() - (16 * sizeof(uint32_t)))) / sizeof(uint32_t);) { - int x = cardinals[i++]; - int y = cardinals[i++]; - int w = cardinals[i++]; - int h = cardinals[i++]; - region += QRect(x, y, w, h); - } + for (unsigned int j = 0; j < 16; ++j) { + colorTransform[j] = floatCardinals[i + j]; + } - for (unsigned int j = 0; j < 16; ++j) { - colorTransform[j] = floatCardinals[i + j]; + QMatrix4x4 colorMatrix(colorTransform); + m_colorMatrices[w] = colorMatrix; } - - QMatrix4x4 colorMatrix(colorTransform); - m_colorMatrices[w] = colorMatrix; } KWayland::Server::SurfaceInterface *surf = w->surface(); @@ -159,7 +169,7 @@ void ContrastEffect::slotPropertyNotify(EffectWindow *w, long atom) { - if (w && atom == net_wm_contrast_region) { + if (w && atom == net_wm_contrast_region && net_wm_contrast_region != XCB_ATOM_NONE) { updateContrastRegion(w); } } diff --git a/effects/blur/blur.cpp b/effects/blur/blur.cpp --- a/effects/blur/blur.cpp +++ b/effects/blur/blur.cpp @@ -73,6 +73,13 @@ connect(effects, SIGNAL(windowDeleted(KWin::EffectWindow*)), this, SLOT(slotWindowDeleted(KWin::EffectWindow*))); connect(effects, SIGNAL(propertyNotify(KWin::EffectWindow*,long)), this, SLOT(slotPropertyNotify(KWin::EffectWindow*,long))); connect(effects, SIGNAL(screenGeometryChanged(QSize)), this, SLOT(slotScreenGeometryChanged())); + connect(effects, &EffectsHandler::xcbConnectionChanged, this, + [this] { + if (shader && shader->isValid() && target->valid()) { + net_wm_blur_region = effects->announceSupportProperty(s_blurAtomName, this); + } + } + ); // Fetch the blur regions for all windows foreach (EffectWindow *window, effects->stackingOrder()) @@ -116,16 +123,19 @@ void BlurEffect::updateBlurRegion(EffectWindow *w) const { QRegion region; - - const QByteArray value = w->readProperty(net_wm_blur_region, XCB_ATOM_CARDINAL, 32); - if (value.size() > 0 && !(value.size() % (4 * sizeof(uint32_t)))) { - const uint32_t *cardinals = reinterpret_cast(value.constData()); - for (unsigned int i = 0; i < value.size() / sizeof(uint32_t);) { - int x = cardinals[i++]; - int y = cardinals[i++]; - int w = cardinals[i++]; - int h = cardinals[i++]; - region += QRect(x, y, w, h); + QByteArray value; + + if (net_wm_blur_region != XCB_ATOM_NONE) { + value = w->readProperty(net_wm_blur_region, XCB_ATOM_CARDINAL, 32); + if (value.size() > 0 && !(value.size() % (4 * sizeof(uint32_t)))) { + const uint32_t *cardinals = reinterpret_cast(value.constData()); + for (unsigned int i = 0; i < value.size() / sizeof(uint32_t);) { + int x = cardinals[i++]; + int y = cardinals[i++]; + int w = cardinals[i++]; + int h = cardinals[i++]; + region += QRect(x, y, w, h); + } } } @@ -171,7 +181,7 @@ void BlurEffect::slotPropertyNotify(EffectWindow *w, long atom) { - if (w && atom == net_wm_blur_region) { + if (w && atom == net_wm_blur_region && net_wm_blur_region != XCB_ATOM_NONE) { updateBlurRegion(w); CacheEntry it = windows.find(w); if (it != windows.end()) { diff --git a/effects/highlightwindow/highlightwindow.cpp b/effects/highlightwindow/highlightwindow.cpp --- a/effects/highlightwindow/highlightwindow.cpp +++ b/effects/highlightwindow/highlightwindow.cpp @@ -33,6 +33,11 @@ connect(effects, SIGNAL(windowClosed(KWin::EffectWindow*)), this, SLOT(slotWindowClosed(KWin::EffectWindow*))); connect(effects, SIGNAL(windowDeleted(KWin::EffectWindow*)), this, SLOT(slotWindowDeleted(KWin::EffectWindow*))); connect(effects, SIGNAL(propertyNotify(KWin::EffectWindow*,long)), this, SLOT(slotPropertyNotify(KWin::EffectWindow*,long))); + connect(effects, &EffectsHandler::xcbConnectionChanged, this, + [this] { + m_atom = effects->announceSupportProperty("_KDE_WINDOW_HIGHLIGHT", this); + } + ); } HighlightWindowEffect::~HighlightWindowEffect() @@ -131,7 +136,7 @@ void HighlightWindowEffect::slotPropertyNotify(EffectWindow* w, long a, EffectWindow *addedWindow) { - if (a != m_atom) + if (a != m_atom || m_atom == XCB_ATOM_NONE) return; // Not our atom // if the window is null, the property was set on the root window - see events.cpp diff --git a/effects/kscreen/kscreen.cpp b/effects/kscreen/kscreen.cpp --- a/effects/kscreen/kscreen.cpp +++ b/effects/kscreen/kscreen.cpp @@ -57,6 +57,11 @@ { initConfig(); connect(effects, SIGNAL(propertyNotify(KWin::EffectWindow*,long)), SLOT(propertyNotify(KWin::EffectWindow*,long))); + connect(effects, &EffectsHandler::xcbConnectionChanged, this, + [this] { + m_atom = effects->announceSupportProperty(QByteArrayLiteral("_KDE_KWIN_KSCREEN_SUPPORT"), this); + } + ); reconfigure(ReconfigureAll); } @@ -119,7 +124,7 @@ void KscreenEffect::propertyNotify(EffectWindow *window, long int atom) { - if (window || atom != m_atom) { + if (window || atom != m_atom || m_atom == XCB_ATOM_NONE) { return; } QByteArray byteData = effects->readRootProperty(m_atom, XCB_ATOM_CARDINAL, 32); @@ -169,7 +174,7 @@ m_state = StateNormal; value = 0l; } - if (value != -1l) { + if (value != -1l && m_atom != XCB_ATOM_NONE) { xcb_change_property(xcbConnection(), XCB_PROP_MODE_REPLACE, x11RootWindow(), m_atom, XCB_ATOM_CARDINAL, 32, 1, &value); } } diff --git a/effects/presentwindows/presentwindows.cpp b/effects/presentwindows/presentwindows.cpp --- a/effects/presentwindows/presentwindows.cpp +++ b/effects/presentwindows/presentwindows.cpp @@ -66,8 +66,12 @@ , m_exposeClassAction(new QAction(this)) { initConfig(); - m_atomDesktop = effects->announceSupportProperty("_KDE_PRESENT_WINDOWS_DESKTOP", this); - m_atomWindows = effects->announceSupportProperty("_KDE_PRESENT_WINDOWS_GROUP", this); + auto announceSupportProperties = [this] { + m_atomDesktop = effects->announceSupportProperty("_KDE_PRESENT_WINDOWS_DESKTOP", this); + m_atomWindows = effects->announceSupportProperty("_KDE_PRESENT_WINDOWS_GROUP", this); + }; + announceSupportProperties(); + connect(effects, &EffectsHandler::xcbConnectionChanged, this, announceSupportProperties); QAction* exposeAction = m_exposeAction; exposeAction->setObjectName(QStringLiteral("Expose")); @@ -829,6 +833,9 @@ // Atom handling void PresentWindowsEffect::slotPropertyNotify(EffectWindow* w, long a) { + if (m_atomDesktop == XCB_ATOM_NONE && m_atomWindows == XCB_ATOM_NONE) { + return; + } if (!w || (a != m_atomDesktop && a != m_atomWindows)) return; // Not our atom @@ -1617,9 +1624,9 @@ // destroy atom on manager window if (m_managerWindow) { - if (m_mode == ModeSelectedDesktop) + if (m_mode == ModeSelectedDesktop && m_atomDesktop != XCB_ATOM_NONE) m_managerWindow->deleteProperty(m_atomDesktop); - else if (m_mode == ModeWindowGroup) + else if (m_mode == ModeWindowGroup && m_atomWindows != XCB_ATOM_NONE) m_managerWindow->deleteProperty(m_atomWindows); m_managerWindow = NULL; } diff --git a/effects/slidingpopups/slidingpopups.cpp b/effects/slidingpopups/slidingpopups.cpp --- a/effects/slidingpopups/slidingpopups.cpp +++ b/effects/slidingpopups/slidingpopups.cpp @@ -48,6 +48,11 @@ connect(effects, SIGNAL(propertyNotify(KWin::EffectWindow*,long)), this, SLOT(slotPropertyNotify(KWin::EffectWindow*,long))); connect(effects, &EffectsHandler::windowShown, this, &SlidingPopupsEffect::startForShow); connect(effects, &EffectsHandler::windowHidden, this, &SlidingPopupsEffect::slotWindowClosed); + connect(effects, &EffectsHandler::xcbConnectionChanged, this, + [this] { + mAtom = effects->announceSupportProperty(QByteArrayLiteral("_KDE_SLIDE"), this); + } + ); reconfigure(ReconfigureAll); } @@ -273,7 +278,9 @@ void SlidingPopupsEffect::slotWindowAdded(EffectWindow *w) { //X11 - slotPropertyNotify(w, mAtom); + if (mAtom != XCB_ATOM_NONE) { + slotPropertyNotify(w, mAtom); + } //Wayland if (auto surf = w->surface()) { @@ -354,7 +361,7 @@ void SlidingPopupsEffect::slotPropertyNotify(EffectWindow* w, long a) { - if (!w || a != mAtom) + if (!w || a != mAtom || mAtom == XCB_ATOM_NONE) return; QByteArray data = w->readProperty(mAtom, mAtom, 32); diff --git a/libkwineffects/kwineffects.h b/libkwineffects/kwineffects.h --- a/libkwineffects/kwineffects.h +++ b/libkwineffects/kwineffects.h @@ -1682,6 +1682,18 @@ **/ void windowDataChanged(KWin::EffectWindow *w, int role); + /** + * The xcb connection changed, either a new xcbConnection got created or the existing one + * got destroyed. + * Effects can use this to refetch the properties they want to set. + * + * When the xcbConnection changes also the @link{x11RootWindow} becomes invalid. + * @see xcbConnection + * @see x11RootWindow + * @since 5.11 + **/ + void xcbConnectionChanged(); + protected: QVector< EffectPair > loaded_effects; //QHash< QString, EffectFactory* > effect_factories;