From 869ebdd4c062d9ac1b606ed48a959176d6fe273d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=B6glund?= Date: Tue, 2 Sep 2014 18:46:07 +0200 Subject: [PATCH] Add an X11EventFilter class This class provides an event filter, specific to an event type, that can be registered with Workspace to filter events. --- CMakeLists.txt | 1 + events.cpp | 37 ++++++++++++++++++++++ workspace.h | 7 +++++ x11eventfilter.cpp | 38 +++++++++++++++++++++++ x11eventfilter.h | 76 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 159 insertions(+) create mode 100644 x11eventfilter.cpp create mode 100644 x11eventfilter.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 7cd0b9244c..b05e106030 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -373,6 +373,7 @@ set(kwin_KDEINIT_SRCS paintredirector.cpp virtualdesktops.cpp xcbutils.cpp + x11eventfilter.cpp scripting/scripting.cpp scripting/workspace_wrapper.cpp scripting/meta.cpp diff --git a/events.cpp b/events.cpp index 1192d3e67b..82c44050e7 100644 --- a/events.cpp +++ b/events.cpp @@ -60,6 +60,7 @@ along with this program. If not, see . #include "composite.h" #include "killwindow.h" +#include "x11eventfilter.h" namespace KWin { @@ -157,6 +158,25 @@ QVector s_xcbEerrors({ QByteArrayLiteral("BadLength"), QByteArrayLiteral("BadImplementation"), QByteArrayLiteral("Unknown")}); + + +void Workspace::registerEventFilter(X11EventFilter *filter) +{ + if (filter->eventType() == XCB_GE_GENERIC) + m_genericEventFilters.append(filter); + else + m_eventFilters.append(filter); +} + +void Workspace::unregisterEventFilter(X11EventFilter *filter) +{ + if (filter->eventType() == XCB_GE_GENERIC) + m_genericEventFilters.removeOne(filter); + else + m_eventFilters.removeOne(filter); +} + + /*! Handles workspace specific XCB event */ @@ -192,6 +212,23 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e) } return false; } + + if (eventType == XCB_GE_GENERIC) { + xcb_ge_generic_event_t *ge = reinterpret_cast(e); + + foreach (X11EventFilter *filter, m_genericEventFilters) { + if (filter->extension() == ge->extension && filter->genericEventType() == ge->event_type && filter->event(e)) { + return true; + } + } + } else { + foreach (X11EventFilter *filter, m_eventFilters) { + if (filter->eventType() == eventType && filter->event(e)) { + return true; + } + } + } + if (effects && static_cast< EffectsHandlerImpl* >(effects)->hasKeyboardGrab() && (eventType == XCB_KEY_PRESS || eventType == XCB_KEY_RELEASE)) return false; // let Qt process it, it'll be intercepted again in eventFilter() diff --git a/workspace.h b/workspace.h index 500e800342..6a53b25f71 100644 --- a/workspace.h +++ b/workspace.h @@ -55,6 +55,7 @@ class KillWindow; class ShortcutDialog; class UserActionsMenu; class Compositor; +class X11EventFilter; enum class Predicate; class Workspace : public QObject, public KDecorationDefines @@ -327,6 +328,9 @@ public: **/ bool compositing() const; + void registerEventFilter(X11EventFilter *filter); + void unregisterEventFilter(X11EventFilter *filter); + public Q_SLOTS: void performWindowOperation(KWin::Client* c, KDecorationDefines::WindowOperation op); // Keybindings @@ -574,6 +578,9 @@ private: QScopedPointer m_windowKiller; + QList m_eventFilters; + QList m_genericEventFilters; + private: friend bool performTransiencyCheck(); friend Workspace *workspace(); diff --git a/x11eventfilter.cpp b/x11eventfilter.cpp new file mode 100644 index 0000000000..0521e23a11 --- /dev/null +++ b/x11eventfilter.cpp @@ -0,0 +1,38 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2014 Fredrik Höglund + +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 "x11eventfilter.h" +#include "workspace.h" + +namespace KWin +{ + +X11EventFilter::X11EventFilter(int eventType, int opcode, int genericEventType) + : m_eventType(eventType), m_extension(opcode), m_genericEventType(genericEventType) +{ + Workspace::self()->registerEventFilter(this); +} + +X11EventFilter::~X11EventFilter() +{ + Workspace::self()->unregisterEventFilter(this); +} + +} diff --git a/x11eventfilter.h b/x11eventfilter.h new file mode 100644 index 0000000000..88d225d0d7 --- /dev/null +++ b/x11eventfilter.h @@ -0,0 +1,76 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2014 Fredrik Höglund + +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 X11EVENTFILTER_H +#define X11EVENTFILTER_H + +#include + +namespace KWin +{ + +class X11EventFilter +{ +public: + /** + * Creates an event filter for the given event type. + */ + X11EventFilter(int eventType, int opcode = 0, int genericEventType = 0); + + /** + * Destroys the event filter. + */ + virtual ~X11EventFilter(); + + /** + * Returns the type of events to filter. + */ + int eventType() const { return m_eventType; } + + /** + * Returns the major opcode of the extension. + * + * Only used when the event type is XCB_GE_GENERIC. + */ + int extension() const { return m_extension; } + + /** + * Returns the type of generic events to filter. + * + * Only used when the event type is XCB_GE_GENERIC. + */ + int genericEventType() const { return m_genericEventType; } + + /** + * This method is called for every event of the filtered type. + * + * Return true to accept the event and stop further processing, and false otherwise. + */ + virtual bool event(xcb_generic_event_t *event) = 0; + +private: + int m_eventType; + int m_extension; + int m_genericEventType; +}; + +} // namespace KWin + +#endif