diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -457,6 +457,7 @@ 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.h b/effects.h --- a/effects.h +++ b/effects.h @@ -60,6 +60,7 @@ class EffectLoader; class EffectsMouseInterceptionX11Filter; class Unmanaged; +class WindowPropertyNotifyX11Filter; class KWIN_EXPORT EffectsHandlerImpl : public EffectsHandler { @@ -255,6 +256,10 @@ 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 @@ 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 @@ EffectLoader *m_effectLoader; int m_trackingCursorChanges; std::unique_ptr m_x11MouseInterception; + std::unique_ptr m_x11WindowPropertyNotify; }; class EffectWindowImpl : public EffectWindow diff --git a/effects.cpp b/effects.cpp --- a/effects.cpp +++ b/effects.cpp @@ -43,6 +43,7 @@ #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 @@ ); 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 @@ 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 @@ { 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 @@ 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 @@ 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/events.cpp b/events.cpp --- a/events.cpp +++ b/events.cpp @@ -282,14 +282,6 @@ } 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 @@ getSkipCloseAnimation(); break; } - emit propertyNotify(this, e->atom); } void Toplevel::clientMessageEvent(xcb_client_message_event_t *e) diff --git a/toplevel.h b/toplevel.h --- a/toplevel.h +++ b/toplevel.h @@ -440,7 +440,6 @@ 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.h b/window_property_notify_x11_filter.h new file mode 100644 --- /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/window_property_notify_x11_filter.cpp b/window_property_notify_x11_filter.cpp new file mode 100644 --- /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/workspace.h b/workspace.h --- a/workspace.h +++ b/workspace.h @@ -483,7 +483,6 @@ void unmanagedAdded(KWin::Unmanaged*); void unmanagedRemoved(KWin::Unmanaged*); void deletedRemoved(KWin::Deleted*); - void propertyNotify(long a); void configChanged(); void reinitializeCompositing(); void showingDesktopChanged(bool showing);