From 0ed609590b75fa9fc2e236c3f91fbb39af20503d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Fl=C3=B6ser?= Date: Sat, 16 Sep 2017 19:25:33 +0200 Subject: [PATCH] Add a dedicated X11EventFilter for forwarding property events to the effect system Summary: So far both Workspace and Toplevel emitted signals for every property notify event on the root window and the respective Toplevel windows. The signals were only used in EffectsHandlerImpl to forward to the effect system in case the property which changed is registered by an effect. This change introduces a dedicated event filter for this which is only created in EffectsHandlerImpl in case an X11 connection is available. It supports a restart of the X11 system. The signals used so far are removed from Workspace and Toplevel. Reviewers: #kwin, #plasma Subscribers: plasma-devel, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D7853 --- CMakeLists.txt | 1 + effects.cpp | 26 ++++++-------- effects.h | 7 +++- events.cpp | 9 ----- toplevel.h | 1 - window_property_notify_x11_filter.cpp | 50 +++++++++++++++++++++++++++ window_property_notify_x11_filter.h | 42 ++++++++++++++++++++++ workspace.h | 1 - 8 files changed, 109 insertions(+), 28 deletions(-) create mode 100644 window_property_notify_x11_filter.cpp create mode 100644 window_property_notify_x11_filter.h 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);