diff --git a/CMakeLists.txt b/CMakeLists.txt
index ed0ef631a3..360357890d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -457,6 +457,7 @@ set(kwin_KDEINIT_SRCS
was_user_interaction_x11_filter.cpp
moving_client_x11_filter.cpp
effects_mouse_interception_x11_filter.cpp
+ window_property_notify_x11_filter.cpp
)
if(KWIN_BUILD_TABBOX)
diff --git a/effects.cpp b/effects.cpp
index a3ec95c87e..4cc2c4e56e 100644
--- a/effects.cpp
+++ b/effects.cpp
@@ -43,6 +43,7 @@ along with this program. If not, see .
#include "screenlockerwatcher.h"
#include "thumbnailitem.h"
#include "virtualdesktops.h"
+#include "window_property_notify_x11_filter.h"
#include "workspace.h"
#include "kwinglutils.h"
@@ -192,13 +193,6 @@ EffectsHandlerImpl::EffectsHandlerImpl(Compositor *compositor, Scene *scene)
);
connect(vds, &VirtualDesktopManager::countChanged, this, &EffectsHandler::numberDesktopsChanged);
connect(Cursor::self(), &Cursor::mouseChanged, this, &EffectsHandler::mouseChanged);
- connect(ws, &Workspace::propertyNotify, this,
- [this](long int atom) {
- if (!registered_atoms.contains(atom))
- return;
- emit propertyNotify(nullptr, atom);
- }
- );
connect(screens(), &Screens::countChanged, this, &EffectsHandler::numberScreensChanged);
connect(screens(), &Screens::sizeChanged, this, &EffectsHandler::virtualScreenSizeChanged);
connect(screens(), &Screens::geometryChanged, this, &EffectsHandler::virtualScreenGeometryChanged);
@@ -232,10 +226,19 @@ EffectsHandlerImpl::EffectsHandlerImpl(Compositor *compositor, Scene *scene)
m_managedProperties.insert(*it, atom);
registerPropertyType(atom, true);
}
+ if (kwinApp()->x11Connection()) {
+ m_x11WindowPropertyNotify = std::make_unique(this);
+ } else {
+ m_x11WindowPropertyNotify.reset();
+ }
emit xcbConnectionChanged();
}
);
+ if (kwinApp()->x11Connection()) {
+ m_x11WindowPropertyNotify = std::make_unique(this);
+ }
+
// connect all clients
for (Client *c : ws->clientList()) {
setupClientConnections(c);
@@ -342,7 +345,6 @@ void EffectsHandlerImpl::setupClientConnections(Client* c)
{
setupAbstractClientConnections(c);
connect(c, &Client::paddingChanged, this, &EffectsHandlerImpl::slotPaddingChanged);
- connect(c, &Client::propertyNotify, this, &EffectsHandlerImpl::slotPropertyNotify);
}
void EffectsHandlerImpl::setupUnmanagedConnections(Unmanaged* u)
@@ -352,7 +354,6 @@ void EffectsHandlerImpl::setupUnmanagedConnections(Unmanaged* u)
connect(u, &Unmanaged::geometryShapeChanged, this, &EffectsHandlerImpl::slotGeometryShapeChanged);
connect(u, &Unmanaged::paddingChanged, this, &EffectsHandlerImpl::slotPaddingChanged);
connect(u, &Unmanaged::damaged, this, &EffectsHandlerImpl::slotWindowDamaged);
- connect(u, &Unmanaged::propertyNotify, this, &EffectsHandlerImpl::slotPropertyNotify);
}
void EffectsHandlerImpl::reconfigure()
@@ -808,13 +809,6 @@ void EffectsHandlerImpl::desktopResized(const QSize &size)
emit screenGeometryChanged(size);
}
-void EffectsHandlerImpl::slotPropertyNotify(Toplevel* t, long int atom)
-{
- if (!registered_atoms.contains(atom))
- return;
- emit propertyNotify(t->effectWindow(), atom);
-}
-
void EffectsHandlerImpl::registerPropertyType(long atom, bool reg)
{
if (reg)
diff --git a/effects.h b/effects.h
index 92c28c13cb..bf5b9bfa97 100644
--- a/effects.h
+++ b/effects.h
@@ -60,6 +60,7 @@ class Deleted;
class EffectLoader;
class EffectsMouseInterceptionX11Filter;
class Unmanaged;
+class WindowPropertyNotifyX11Filter;
class KWIN_EXPORT EffectsHandlerImpl : public EffectsHandler
{
@@ -255,6 +256,10 @@ public:
void highlightWindows(const QVector &windows);
+ bool isPropertyTypeRegistered(xcb_atom_t atom) const {
+ return registered_atoms.contains(atom);
+ }
+
public Q_SLOTS:
void slotCurrentTabAboutToChange(EffectWindow* from, EffectWindow* to);
void slotTabAdded(EffectWindow* from, EffectWindow* to);
@@ -282,7 +287,6 @@ protected Q_SLOTS:
void slotGeometryShapeChanged(KWin::Toplevel *t, const QRect &old);
void slotPaddingChanged(KWin::Toplevel *t, const QRect &old);
void slotWindowDamaged(KWin::Toplevel *t, const QRect& r);
- void slotPropertyNotify(KWin::Toplevel *t, long atom);
protected:
void connectNotify(const QMetaMethod &signal) override;
@@ -321,6 +325,7 @@ private:
EffectLoader *m_effectLoader;
int m_trackingCursorChanges;
std::unique_ptr m_x11MouseInterception;
+ std::unique_ptr m_x11WindowPropertyNotify;
};
class EffectWindowImpl : public EffectWindow
diff --git a/events.cpp b/events.cpp
index 50f390a1f0..599af666c5 100644
--- a/events.cpp
+++ b/events.cpp
@@ -282,14 +282,6 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e)
} else if (Unmanaged* c = findUnmanaged(eventWindow)) {
if (c->windowEvent(e))
return true;
- } else {
- // We want to pass root window property events to effects
- if (eventType == XCB_PROPERTY_NOTIFY) {
- auto *event = reinterpret_cast(e);
- if (event->window == rootWindow()) {
- emit propertyNotify(event->atom);
- }
- }
}
}
@@ -1370,7 +1362,6 @@ void Toplevel::propertyNotifyEvent(xcb_property_notify_event_t *e)
getSkipCloseAnimation();
break;
}
- emit propertyNotify(this, e->atom);
}
void Toplevel::clientMessageEvent(xcb_client_message_event_t *e)
diff --git a/toplevel.h b/toplevel.h
index f50314e6eb..18775470ad 100644
--- a/toplevel.h
+++ b/toplevel.h
@@ -440,7 +440,6 @@ public:
Q_SIGNALS:
void opacityChanged(KWin::Toplevel* toplevel, qreal oldOpacity);
void damaged(KWin::Toplevel* toplevel, const QRect& damage);
- void propertyNotify(KWin::Toplevel* toplevel, long a);
void geometryChanged();
void geometryShapeChanged(KWin::Toplevel* toplevel, const QRect& old);
void paddingChanged(KWin::Toplevel* toplevel, const QRect& old);
diff --git a/window_property_notify_x11_filter.cpp b/window_property_notify_x11_filter.cpp
new file mode 100644
index 0000000000..293a5026cf
--- /dev/null
+++ b/window_property_notify_x11_filter.cpp
@@ -0,0 +1,50 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2017 Martin Flöser
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*********************************************************************/
+#include "window_property_notify_x11_filter.h"
+#include "effects.h"
+#include "unmanaged.h"
+#include "workspace.h"
+
+namespace KWin
+{
+
+WindowPropertyNotifyX11Filter::WindowPropertyNotifyX11Filter(EffectsHandlerImpl *effects)
+ : X11EventFilter(QVector{XCB_PROPERTY_NOTIFY})
+ , m_effects(effects)
+{
+}
+
+bool WindowPropertyNotifyX11Filter::event(xcb_generic_event_t *event)
+{
+ const auto *pe = reinterpret_cast(event);
+ if (!m_effects->isPropertyTypeRegistered(pe->atom)) {
+ return false;
+ }
+ if (pe->window == kwinApp()->x11RootWindow()) {
+ emit m_effects->propertyNotify(nullptr, pe->atom);
+ } else if (const auto c = workspace()->findClient(Predicate::WindowMatch, pe->window)) {
+ emit m_effects->propertyNotify(c->effectWindow(), pe->atom);
+ } else if (const auto c = workspace()->findUnmanaged(pe->window)) {
+ emit m_effects->propertyNotify(c->effectWindow(), pe->atom);
+ }
+ return false;
+}
+
+}
diff --git a/window_property_notify_x11_filter.h b/window_property_notify_x11_filter.h
new file mode 100644
index 0000000000..68f075ce94
--- /dev/null
+++ b/window_property_notify_x11_filter.h
@@ -0,0 +1,42 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2017 Martin Flöser
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*********************************************************************/
+#ifndef KWIN_WINDOW_PROPERTY_NOTIFY_X11_FILTER_H
+#define KWIN_WINDOW_PROPERTY_NOTIFY_X11_FILTER_H
+
+#include "x11eventfilter.h"
+
+namespace KWin
+{
+class EffectsHandlerImpl;
+
+class WindowPropertyNotifyX11Filter : public X11EventFilter
+{
+public:
+ explicit WindowPropertyNotifyX11Filter(EffectsHandlerImpl *effects);
+
+ bool event(xcb_generic_event_t *event) override;
+
+private:
+ EffectsHandlerImpl *m_effects;
+};
+
+}
+
+#endif
diff --git a/workspace.h b/workspace.h
index 0e702453be..a50772b80b 100644
--- a/workspace.h
+++ b/workspace.h
@@ -483,7 +483,6 @@ Q_SIGNALS:
void unmanagedAdded(KWin::Unmanaged*);
void unmanagedRemoved(KWin::Unmanaged*);
void deletedRemoved(KWin::Deleted*);
- void propertyNotify(long a);
void configChanged();
void reinitializeCompositing();
void showingDesktopChanged(bool showing);