From 651ea26f3c6393ebaf86d099eb9ae3fc04ef95b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Fl=C3=B6ser?= Date: Wed, 23 Aug 2017 11:41:26 +0200 Subject: [PATCH] Make EffectsHandlerImpl::announceSupportProperty work without X11 Summary: announceSupportProperty is called from the effects on startup. It registers the property on the X11 root window. If we would start kwin_wayland without XWayland support this would result in a crash. This change refactors the code so that it still registers the property, but does not try to interact with X11. Once X11 support is available it does the actual registering. But this means that the effects get an incorrect atom returned. This needs additional changes. E.g. they could also react to the x11ConnectionChanged and register again, then they would get the proper atom. This would also support restart of XWayland. Reviewers: #kwin, #plasma Subscribers: plasma-devel, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D7475 --- effects.cpp | 61 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/effects.cpp b/effects.cpp index caa1c73374..d33ecf471e 100644 --- a/effects.cpp +++ b/effects.cpp @@ -93,6 +93,26 @@ static void deleteWindowProperty(Window win, long int atom) xcb_delete_property(connection(), win, atom); } +static xcb_atom_t registerSupportProperty(const QByteArray &propertyName) +{ + auto c = kwinApp()->x11Connection(); + if (!c) { + return XCB_ATOM_NONE; + } + // get the atom for the propertyName + ScopedCPointer atomReply(xcb_intern_atom_reply(c, + xcb_intern_atom_unchecked(c, false, propertyName.size(), propertyName.constData()), + NULL)); + if (atomReply.isNull()) { + return XCB_ATOM_NONE; + } + // announce property on root window + unsigned char dummy = 0; + xcb_change_property(c, XCB_PROP_MODE_REPLACE, kwinApp()->x11RootWindow(), atomReply->atom, atomReply->atom, 8, 1, &dummy); + // TODO: add to _NET_SUPPORTED + return atomReply->atom; +} + //--------------------- EffectsHandlerImpl::EffectsHandlerImpl(Compositor *compositor, Scene *scene) @@ -198,6 +218,22 @@ EffectsHandlerImpl::EffectsHandlerImpl(Compositor *compositor, Scene *scene) #endif connect(ScreenEdges::self(), &ScreenEdges::approaching, this, &EffectsHandler::screenEdgeApproaching); connect(ScreenLockerWatcher::self(), &ScreenLockerWatcher::locked, this, &EffectsHandler::screenLockingChanged); + + connect(kwinApp(), &Application::x11ConnectionChanged, this, + [this] { + registered_atoms.clear(); + for (auto it = m_propertiesForEffects.keyBegin(); it != m_propertiesForEffects.keyEnd(); it++) { + const auto atom = registerSupportProperty(*it); + if (atom == XCB_ATOM_NONE) { + continue; + } + m_compositor->keepSupportProperty(atom); + m_managedProperties.insert(*it, atom); + registerPropertyType(atom, true); + } + } + ); + // connect all clients for (Client *c : ws->clientList()) { setupClientConnections(c); @@ -794,24 +830,17 @@ xcb_atom_t EffectsHandlerImpl::announceSupportProperty(const QByteArray &propert if (!it.value().contains(effect)) { it.value().append(effect); } - return m_managedProperties.value(propertyName); + return m_managedProperties.value(propertyName, XCB_ATOM_NONE); } - // get the atom for the propertyName - ScopedCPointer atomReply(xcb_intern_atom_reply(connection(), - xcb_intern_atom_unchecked(connection(), false, propertyName.size(), propertyName.constData()), - NULL)); - if (atomReply.isNull()) { - return XCB_ATOM_NONE; - } - m_compositor->keepSupportProperty(atomReply->atom); - // announce property on root window - unsigned char dummy = 0; - xcb_change_property(connection(), XCB_PROP_MODE_REPLACE, rootWindow(), atomReply->atom, atomReply->atom, 8, 1, &dummy); - // TODO: add to _NET_SUPPORTED - m_managedProperties.insert(propertyName, atomReply->atom); m_propertiesForEffects.insert(propertyName, QList() << effect); - registerPropertyType(atomReply->atom, true); - return atomReply->atom; + const auto atom = registerSupportProperty(propertyName); + if (atom == XCB_ATOM_NONE) { + return atom; + } + m_compositor->keepSupportProperty(atom); + m_managedProperties.insert(propertyName, atom); + registerPropertyType(atom, true); + return atom; } void EffectsHandlerImpl::removeSupportProperty(const QByteArray &propertyName, Effect *effect)