diff --git a/src/plasma/CMakeLists.txt b/src/plasma/CMakeLists.txt index e34d888e0..aced599c4 100644 --- a/src/plasma/CMakeLists.txt +++ b/src/plasma/CMakeLists.txt @@ -115,7 +115,7 @@ add_library(KF5Plasma ${Plasma_LIB_SRCS}) add_library(KF5::Plasma ALIAS KF5Plasma) if(X11_FOUND) - set(PLASMA_EXTRA_LIBS ${PLASMA_EXTRA_LIBS} Qt5::X11Extras ${X11_LIBRARIES}) + set(PLASMA_EXTRA_LIBS ${PLASMA_EXTRA_LIBS} Qt5::X11Extras ${X11_LIBRARIES} ${XCB_XCB_LIBRARY}) endif() if(DL_LIBRARY) diff --git a/src/plasma/private/effectwatcher.cpp b/src/plasma/private/effectwatcher.cpp index 58ca9425e..495fa5986 100644 --- a/src/plasma/private/effectwatcher.cpp +++ b/src/plasma/private/effectwatcher.cpp @@ -21,8 +21,6 @@ #include -#include -#include #include namespace Plasma @@ -30,19 +28,26 @@ namespace Plasma EffectWatcher::EffectWatcher(const QString& property, QObject *parent) : QObject(parent), - m_property(property) + m_property(XCB_ATOM_NONE) { - m_effectActive = isEffectActive(); - QCoreApplication::instance()->installNativeEventFilter(this); - Display *dpy = QX11Info::display(); - Window root = DefaultRootWindow(dpy); - XWindowAttributes attrs; - //Don't reset eventual other masks already there - XGetWindowAttributes(dpy, root, &attrs); - attrs.your_event_mask |= PropertyChangeMask; - XSelectInput(dpy, root, attrs.your_event_mask); + xcb_connection_t *c = QX11Info::connection(); + const QByteArray propertyName = property.toLatin1(); + xcb_intern_atom_cookie_t atomCookie = xcb_intern_atom_unchecked(c, false, propertyName.length(), propertyName.constData()); + xcb_get_window_attributes_cookie_t winAttrCookie = xcb_get_window_attributes_unchecked(c, QX11Info::appRootWindow()); + + QScopedPointer atom(xcb_intern_atom_reply(c, atomCookie, nullptr)); + if (!atom.isNull()) { + m_property = atom->atom; + } + m_effectActive = isEffectActive(); + + QScopedPointer attrs(xcb_get_window_attributes_reply(c, winAttrCookie, nullptr)); + if (!attrs.isNull()) { + uint32_t events = attrs->your_event_mask | XCB_EVENT_MASK_PROPERTY_CHANGE; + xcb_change_window_attributes(c, QX11Info::appRootWindow(), XCB_CW_EVENT_MASK, &events); + } } bool EffectWatcher::nativeEventFilter(const QByteArray& eventType, void *message, long *result) @@ -52,13 +57,11 @@ bool EffectWatcher::nativeEventFilter(const QByteArray& eventType, void *message return false; xcb_generic_event_t* event = reinterpret_cast(message); uint response_type = event->response_type & ~0x80; - if (response_type != XCB_PROPERTY_NOTIFY) + if (response_type != XCB_PROPERTY_NOTIFY || m_property == XCB_ATOM_NONE) return false; xcb_property_notify_event_t* prop_event = reinterpret_cast(event); - Display *dpy = QX11Info::display(); - Atom testAtom = XInternAtom(dpy, m_property.toLatin1(), False); - if (prop_event->atom == testAtom) { + if (prop_event->atom == m_property) { bool nowEffectActive = isEffectActive(); if (m_effectActive != nowEffectActive) { m_effectActive = nowEffectActive; @@ -70,17 +73,22 @@ bool EffectWatcher::nativeEventFilter(const QByteArray& eventType, void *message bool EffectWatcher::isEffectActive() const { - Display *dpy = QX11Info::display(); - Atom testAtom = XInternAtom(dpy, m_property.toLatin1(), False); - - bool nowEffectActive = false; - int cnt; - Atom *list = XListProperties(dpy, DefaultRootWindow(dpy), &cnt); - if (list != NULL) { - nowEffectActive = (qFind(list, list + cnt, testAtom) != list + cnt); - XFree(list); + if (m_property == XCB_ATOM_NONE) { + return false; } - return nowEffectActive; + xcb_connection_t *c = QX11Info::connection(); + xcb_list_properties_cookie_t propsCookie = xcb_list_properties_unchecked(c, QX11Info::appRootWindow()); + QScopedPointer props(xcb_list_properties_reply(c, propsCookie, nullptr)); + if (props.isNull()) { + return false; + } + xcb_atom_t *atoms = xcb_list_properties_atoms(props.data()); + for (int i = 0; i < props->atoms_len; ++i) { + if (atoms[i] == m_property) { + return true; + } + } + return false; } } // namespace Plasma diff --git a/src/plasma/private/effectwatcher_p.h b/src/plasma/private/effectwatcher_p.h index 626b1e6eb..386a839bc 100644 --- a/src/plasma/private/effectwatcher_p.h +++ b/src/plasma/private/effectwatcher_p.h @@ -24,6 +24,8 @@ #include +#include + namespace Plasma { @@ -43,7 +45,7 @@ Q_SIGNALS: void effectChanged(bool on); private: - QString m_property; + xcb_atom_t m_property; bool m_effectActive; };