From bd5f5e0915b3178b753dc90f7cc893b46f13bef6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Fl=C3=B6ser?= Date: Thu, 17 Aug 2017 21:12:28 +0200 Subject: [PATCH] Move X11 movingClient handling into a dedicated X11EventFilter Summary: Splits out the X11 specific window movement handling so that it's not used in the Wayland case at runtime. As a nice side effect it un-spaghetties the X11 event handler. Test Plan: Run nested KWin on Xephyr and nested KWin/Wayland to verify that move/resize of X11 windows is still working Reviewers: #kwin, #plasma Subscribers: plasma-devel, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D7374 --- CMakeLists.txt | 1 + events.cpp | 11 ------- moving_client_x11_filter.cpp | 62 ++++++++++++++++++++++++++++++++++++ moving_client_x11_filter.h | 38 ++++++++++++++++++++++ workspace.cpp | 2 ++ workspace.h | 1 + 6 files changed, 104 insertions(+), 11 deletions(-) create mode 100644 moving_client_x11_filter.cpp create mode 100644 moving_client_x11_filter.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 97313160d8..9c6b680344 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -455,6 +455,7 @@ set(kwin_KDEINIT_SRCS abstract_opengl_context_attribute_builder.cpp egl_context_attribute_builder.cpp was_user_interaction_x11_filter.cpp + moving_client_x11_filter.cpp ) if(KWIN_BUILD_TABBOX) diff --git a/events.cpp b/events.cpp index 74c0d155db..933dc38b31 100644 --- a/events.cpp +++ b/events.cpp @@ -304,10 +304,6 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e) xcb_key_press_event_t *event = reinterpret_cast(e); KKeyServer::xcbKeyPressEventToQt(event, &keyQt); // qDebug() << "Workspace::keyPress( " << keyQt << " )"; - if (Client *c = dynamic_cast(movingClient)) { - c->keyPressEvent(keyQt, event->time); - return true; - } #ifdef KWIN_BUILD_TABBOX if (TabBox::TabBox::self()->isGrabbed()) { TabBox::TabBox::self()->keyPress(keyQt); @@ -357,13 +353,6 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e) } } } - if (Client *c = dynamic_cast(movingClient)) { - if (eventType == XCB_BUTTON_PRESS || eventType == XCB_BUTTON_RELEASE || eventType == XCB_MOTION_NOTIFY) { - if (c->moveResizeGrabWindow() == reinterpret_cast(e)->event && c->windowEvent(e)) { - return true; - } - } - } switch (eventType) { case XCB_CREATE_NOTIFY: { diff --git a/moving_client_x11_filter.cpp b/moving_client_x11_filter.cpp new file mode 100644 index 0000000000..1df4088303 --- /dev/null +++ b/moving_client_x11_filter.cpp @@ -0,0 +1,62 @@ +/******************************************************************** + 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 "moving_client_x11_filter.h" +#include "client.h" +#include "workspace.h" +#include +#include + +namespace KWin +{ + +MovingClientX11Filter::MovingClientX11Filter() + : X11EventFilter(QVector{XCB_KEY_PRESS, XCB_MOTION_NOTIFY, XCB_BUTTON_PRESS, XCB_BUTTON_RELEASE}) +{ +} + +bool MovingClientX11Filter::event(xcb_generic_event_t *event) +{ + auto client = dynamic_cast(workspace()->getMovingClient()); + if (!client) { + return false; + } + auto testWindow = [client, event] (xcb_window_t window) { + return client->moveResizeGrabWindow() == window && client->windowEvent(event); + }; + + const uint8_t eventType = event->response_type & ~0x80; + switch (eventType) { + case XCB_KEY_PRESS: { + int keyQt; + xcb_key_press_event_t *keyEvent = reinterpret_cast(event); + KKeyServer::xcbKeyPressEventToQt(keyEvent, &keyQt); + client->keyPressEvent(keyQt, keyEvent->time); + return true; + } + case XCB_BUTTON_PRESS: + case XCB_BUTTON_RELEASE: + return testWindow(reinterpret_cast(event)->event); + case XCB_MOTION_NOTIFY: + return testWindow(reinterpret_cast(event)->event); + } + return false; +} + +} diff --git a/moving_client_x11_filter.h b/moving_client_x11_filter.h new file mode 100644 index 0000000000..617760fa40 --- /dev/null +++ b/moving_client_x11_filter.h @@ -0,0 +1,38 @@ +/******************************************************************** + 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_MOVING_CLIENT_X11_FILTER_H +#define KWIN_MOVING_CLIENT_X11_FILTER_H +#include "x11eventfilter.h" + +namespace KWin +{ + +class MovingClientX11Filter : public X11EventFilter +{ +public: + explicit MovingClientX11Filter(); + + bool event(xcb_generic_event_t *event) override; +}; + +} + +#endif + diff --git a/workspace.cpp b/workspace.cpp index 61f2147687..d62c2a71c9 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -39,6 +39,7 @@ along with this program. If not, see . #include "group.h" #include "input.h" #include "logind.h" +#include "moving_client_x11_filter.h" #include "killwindow.h" #include "netinfo.h" #include "outline.h" @@ -217,6 +218,7 @@ void Workspace::init() { if (kwinApp()->operationMode() == Application::OperationModeX11) { m_wasUserInteractionFilter.reset(new WasUserInteractionX11Filter); + m_movingClientFilter.reset(new MovingClientX11Filter); } updateXTime(); // Needed for proper initialization of user_time in Client ctor KSharedConfigPtr config = kwinApp()->config(); diff --git a/workspace.h b/workspace.h index 995cd83330..9b60724b28 100644 --- a/workspace.h +++ b/workspace.h @@ -624,6 +624,7 @@ private: QList m_eventFilters; QList m_genericEventFilters; + QScopedPointer m_movingClientFilter; private: friend bool performTransiencyCheck();