[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [kwin] /: Move X11 specific event filtering for ScreenEdges into x11 standalone platform
From:       Martin_Flöser <null () kde ! org>
Date:       2017-09-01 15:11:26
Message-ID: E1dnnbS-0007Tn-MN () code ! kde ! org
[Download RAW message or body]

Git commit 833f933c5c6aa1bedfb57fa65bf7d9b6e2f9516a by Martin Flöser.
Committed on 01/09/2017 at 15:01.
Pushed by graesslin into branch 'master'.

Move X11 specific event filtering for ScreenEdges into x11 standalone platform

Summary:
This change splits out the X11 specific event filtering into a dedicated
X11EventFilter. It is created in the x11 standalone platform plugin when
the first Edge is being created.

Some of the X11 specific code is removed from ScreenEdges, though more
refactoring is possible in ScreenEdges to share more code between X11
specific and generic implementation.

Test Plan: Run KWin on Xephyr, screen edge approach effect still shows

Reviewers: #kwin, #plasma

Subscribers: plasma-devel, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D7406

M  +35   -20   autotests/test_screen_edges.cpp
M  +0    -16   events.cpp
M  +1    -0    plugins/platforms/x11/standalone/CMakeLists.txt
A  +65   -0    plugins/platforms/x11/standalone/screenedges_filter.cpp     [License: \
GPL (v2)] A  +37   -0    plugins/platforms/x11/standalone/screenedges_filter.h     \
[License: GPL (v2)] M  +4    -0    plugins/platforms/x11/standalone/x11_platform.cpp
M  +2    -0    plugins/platforms/x11/standalone/x11_platform.h
M  +0    -17   screenedge.cpp
M  +3    -10   screenedge.h

https://commits.kde.org/kwin/833f933c5c6aa1bedfb57fa65bf7d9b6e2f9516a

diff --git a/autotests/test_screen_edges.cpp b/autotests/test_screen_edges.cpp
index 841178104..ccb1f2129 100644
--- a/autotests/test_screen_edges.cpp
+++ b/autotests/test_screen_edges.cpp
@@ -466,7 +466,10 @@ void TestScreenEdges::testCallback()
     event.same_screen_focus = 1;
     event.time = QDateTime::currentMSecsSinceEpoch();
     setPos(QPoint(0, 50));
-    QVERIFY(s->isEntered(&event));
+    auto isEntered = [s] (xcb_enter_notify_event_t *event) {
+        return s->handleEnterNotifiy(event->event, QPoint(event->root_x, \
event->root_y), QDateTime::fromMSecsSinceEpoch(event->time)); +    };
+    QVERIFY(isEntered(&event));
     // doesn't trigger as the edge was not triggered yet
     QVERIFY(spy.isEmpty());
     QCOMPARE(Cursor::pos(), QPoint(1, 50));
@@ -475,7 +478,7 @@ void TestScreenEdges::testCallback()
     QTest::qWait(160);
     setPos(QPoint(0, 100));
     event.time = QDateTime::currentMSecsSinceEpoch();
-    QVERIFY(s->isEntered(&event));
+    QVERIFY(isEntered(&event));
     QVERIFY(spy.isEmpty());
     QCOMPARE(Cursor::pos(), QPoint(1, 100));
 
@@ -483,7 +486,7 @@ void TestScreenEdges::testCallback()
     QTest::qWait(200);
     setPos(QPoint(0, 101));
     event.time = QDateTime::currentMSecsSinceEpoch();
-    QVERIFY(s->isEntered(&event));
+    QVERIFY(isEntered(&event));
     QVERIFY(spy.isEmpty());
     QCOMPARE(Cursor::pos(), QPoint(1, 101));
 
@@ -491,7 +494,7 @@ void TestScreenEdges::testCallback()
     QTest::qWait(50);
     setPos(QPoint(0, 100));
     event.time = QDateTime::currentMSecsSinceEpoch();
-    QVERIFY(s->isEntered(&event));
+    QVERIFY(isEntered(&event));
     QVERIFY(spy.isEmpty());
     QCOMPARE(Cursor::pos(), QPoint(1, 100));
 
@@ -499,7 +502,7 @@ void TestScreenEdges::testCallback()
     QTest::qWait(110);
     setPos(QPoint(0, 101));
     event.time = QDateTime::currentMSecsSinceEpoch();
-    QVERIFY(s->isEntered(&event));
+    QVERIFY(isEntered(&event));
     QVERIFY(!spy.isEmpty());
     QCOMPARE(Cursor::pos(), QPoint(1, 101));
 
@@ -507,21 +510,21 @@ void TestScreenEdges::testCallback()
     QTest::qWait(351);
     setPos(QPoint(0, 100));
     event.time = QDateTime::currentMSecsSinceEpoch();
-    QVERIFY(s->isEntered(&event));
+    QVERIFY(isEntered(&event));
     QCOMPARE(spy.count(), 1);
     QCOMPARE(Cursor::pos(), QPoint(1, 100));
     // it's still under the reactivation
     QTest::qWait(50);
     setPos(QPoint(0, 100));
     event.time = QDateTime::currentMSecsSinceEpoch();
-    QVERIFY(s->isEntered(&event));
+    QVERIFY(isEntered(&event));
     QCOMPARE(spy.count(), 1);
     QCOMPARE(Cursor::pos(), QPoint(1, 100));
     // now it should trigger again
     QTest::qWait(250);
     setPos(QPoint(0, 100));
     event.time = QDateTime::currentMSecsSinceEpoch();
-    QVERIFY(s->isEntered(&event));
+    QVERIFY(isEntered(&event));
     QCOMPARE(spy.count(), 2);
     QCOMPARE(spy.first().first().value<ElectricBorder>(), ElectricLeft);
     QCOMPARE(spy.last().first().value<ElectricBorder>(), ElectricLeft);
@@ -536,7 +539,7 @@ void TestScreenEdges::testCallback()
     // it should trigger directly
     QTest::qWait(350);
     event.time = QDateTime::currentMSecsSinceEpoch();
-    QVERIFY(s->isEntered(&event));
+    QVERIFY(isEntered(&event));
     QCOMPARE(spy.count(), 3);
     QCOMPARE(spy.at(0).first().value<ElectricBorder>(), ElectricLeft);
     QCOMPARE(spy.at(1).first().value<ElectricBorder>(), ElectricLeft);
@@ -645,7 +648,10 @@ void TestScreenEdges::testPushBack()
     event.event = s->windows().first();
     event.same_screen_focus = 1;
     event.time = QDateTime::currentMSecsSinceEpoch();
-    QVERIFY(s->isEntered(&event));
+    auto isEntered = [s] (xcb_enter_notify_event_t *event) {
+        return s->handleEnterNotifiy(event->event, QPoint(event->root_x, \
event->root_y), QDateTime::fromMSecsSinceEpoch(event->time)); +    };
+    QVERIFY(isEntered(&event));
     QVERIFY(spy.isEmpty());
     QTEST(Cursor::pos(), "expected");
 
@@ -692,7 +698,10 @@ void TestScreenEdges::testFullScreenBlocking()
     event.event = s->windows().first();
     event.same_screen_focus = 1;
     event.time = QDateTime::currentMSecsSinceEpoch();
-    QVERIFY(s->isEntered(&event));
+    auto isEntered = [s] (xcb_enter_notify_event_t *event) {
+        return s->handleEnterNotifiy(event->event, QPoint(event->root_x, \
event->root_y), QDateTime::fromMSecsSinceEpoch(event->time)); +    };
+    QVERIFY(isEntered(&event));
     QVERIFY(spy.isEmpty());
     QCOMPARE(Cursor::pos(), QPoint(1, 50));
 
@@ -710,7 +719,7 @@ void TestScreenEdges::testFullScreenBlocking()
     QTest::qWait(160);
     Cursor::setPos(0, 50);
     event.time = QDateTime::currentMSecsSinceEpoch();
-    QVERIFY(s->isEntered(&event));
+    QVERIFY(isEntered(&event));
     QVERIFY(spy.isEmpty());
     // and no pushback
     QCOMPARE(Cursor::pos(), QPoint(0, 50));
@@ -722,7 +731,7 @@ void TestScreenEdges::testFullScreenBlocking()
         QCOMPARE(e->activatesForTouchGesture(), e->border() == KWin::ElectricRight);
     }
     event.time = QDateTime::currentMSecsSinceEpoch();
-    QVERIFY(s->isEntered(&event));
+    QVERIFY(isEntered(&event));
     QVERIFY(!spy.isEmpty());
     QCOMPARE(Cursor::pos(), QPoint(1, 50));
 
@@ -734,7 +743,7 @@ void TestScreenEdges::testFullScreenBlocking()
     spy.clear();
     Cursor::setPos(0, 50);
     event.time = QDateTime::currentMSecsSinceEpoch();
-    QVERIFY(s->isEntered(&event));
+    QVERIFY(isEntered(&event));
     QVERIFY(spy.isEmpty());
     // and a pushback
     QCOMPARE(Cursor::pos(), QPoint(1, 50));
@@ -743,7 +752,7 @@ void TestScreenEdges::testFullScreenBlocking()
     client.setGeometry(screens()->geometry());
     emit s->checkBlocking();
     Cursor::setPos(0, 50);
-    QVERIFY(s->isEntered(&event));
+    QVERIFY(isEntered(&event));
     QVERIFY(spy.isEmpty());
     // and no pushback
     QCOMPARE(Cursor::pos(), QPoint(0, 50));
@@ -757,14 +766,14 @@ void TestScreenEdges::testFullScreenBlocking()
     event.event = s->windows().first();
     event.time = QDateTime::currentMSecsSinceEpoch();
     Cursor::setPos(99, 99);
-    QVERIFY(s->isEntered(&event));
+    QVERIFY(isEntered(&event));
     QVERIFY(spy.isEmpty());
     // and pushback
     QCOMPARE(Cursor::pos(), QPoint(98, 98));
     QTest::qWait(160);
     event.time = QDateTime::currentMSecsSinceEpoch();
     Cursor::setPos(99, 99);
-    QVERIFY(s->isEntered(&event));
+    QVERIFY(isEntered(&event));
     QVERIFY(!spy.isEmpty());
 }
 
@@ -812,7 +821,10 @@ void TestScreenEdges::testClientEdge()
     event.event = s->windows().first();
     event.same_screen_focus = 1;
     event.time = QDateTime::currentMSecsSinceEpoch();
-    QVERIFY(s->isEntered(&event));
+    auto isEntered = [s] (xcb_enter_notify_event_t *event) {
+        return s->handleEnterNotifiy(event->event, QPoint(event->root_x, \
event->root_y), QDateTime::fromMSecsSinceEpoch(event->time)); +    };
+    QVERIFY(isEntered(&event));
     // autohiding panels shall activate instantly
     QCOMPARE(client.isHiddenInternal(), false);
     QCOMPARE(Cursor::pos(), QPoint(1, 50));
@@ -882,7 +894,7 @@ void TestScreenEdges::testClientEdge()
     event2.event = s->windows().first();
     event2.same_screen_focus = 1;
     event2.time = QDateTime::currentMSecsSinceEpoch();
-    QVERIFY(s->isEntered(&event2));
+    QVERIFY(isEntered(&event2));
     QCOMPARE(client.keepBelow(), false);
     QCOMPARE(client.isHiddenInternal(), false);
     QCOMPARE(Cursor::pos(), QPoint(1, 50));
@@ -946,7 +958,10 @@ void TestScreenEdges::testTouchEdge()
     event.same_screen_focus = 1;
     event.time = QDateTime::currentMSecsSinceEpoch();
     setPos(QPoint(0, 50));
-    QCOMPARE(s->isEntered(&event), false);
+    auto isEntered = [s] (xcb_enter_notify_event_t *event) {
+        return s->handleEnterNotifiy(event->event, QPoint(event->root_x, \
event->root_y), QDateTime::fromMSecsSinceEpoch(event->time)); +    };
+    QCOMPARE(isEntered(&event), false);
     QVERIFY(approachingSpy.isEmpty());
     // let's also verify the check
     s->check(QPoint(0, 50), QDateTime::currentDateTime(), false);
diff --git a/events.cpp b/events.cpp
index 462611ba2..241e6b3b4 100644
--- a/events.cpp
+++ b/events.cpp
@@ -39,7 +39,6 @@ along with this program.  If not, see \
<http://www.gnu.org/licenses/>.  #include "unmanaged.h"
 #include "useractions.h"
 #include "effects.h"
-#include "screenedge.h"
 #include "screens.h"
 #include "xcbutils.h"
 
@@ -276,15 +275,9 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e)
             return true;
         }
         auto *mouseEvent = reinterpret_cast<xcb_motion_notify_event_t*>(e);
-        const QPoint rootPos(mouseEvent->root_x, mouseEvent->root_y);
         if (effects && \
static_cast<EffectsHandlerImpl*>(effects)->checkInputWindowEvent(mouseEvent)) {  \
return true;  }
-        if (QWidget::mouseGrabber()) {
-            ScreenEdges::self()->check(rootPos, \
                QDateTime::fromMSecsSinceEpoch(xTime()), true);
-        } else {
-            ScreenEdges::self()->check(rootPos, \
                QDateTime::fromMSecsSinceEpoch(mouseEvent->time));
-        }
         break;
     }
     case XCB_CONFIGURE_NOTIFY:
@@ -383,11 +376,6 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e)
         return (event->event != event->window);   // hide wm typical event from Qt
     }
 
-    case XCB_ENTER_NOTIFY: {
-        if (ScreenEdges::self()->isEntered(reinterpret_cast<xcb_enter_notify_event_t*>(e)))
                
-            return true;
-        break;
-    }
     case XCB_CONFIGURE_REQUEST: {
         const auto *event = reinterpret_cast<xcb_configure_request_event_t*>(e);
         if (event->parent == rootWindow()) {
@@ -439,10 +427,6 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e)
         // fall through
     case XCB_FOCUS_OUT:
         return true; // always eat these, they would tell Qt that KWin is the active \
                app
-    case XCB_CLIENT_MESSAGE:
-        if (ScreenEdges::self()->isEntered(reinterpret_cast<xcb_client_message_event_t*>(e)))
                
-            return true;
-        break;
     default:
         if (eventType == Xcb::Extensions::self()->randrNotifyEvent() && \
                Xcb::Extensions::self()->isRandrAvailable()) {
             auto *event = \
                reinterpret_cast<xcb_randr_screen_change_notify_event_t*>(e);
diff --git a/plugins/platforms/x11/standalone/CMakeLists.txt \
b/plugins/platforms/x11/standalone/CMakeLists.txt index 811efdd76..582af8c04 100644
--- a/plugins/platforms/x11/standalone/CMakeLists.txt
+++ b/plugins/platforms/x11/standalone/CMakeLists.txt
@@ -6,6 +6,7 @@ set(X11PLATFORM_SOURCES
     screens_xrandr.cpp
     windowselector.cpp
     overlaywindow_x11.cpp
+    screenedges_filter.cpp
 )
 
 if(X11_Xinput_FOUND)
diff --git a/plugins/platforms/x11/standalone/screenedges_filter.cpp \
b/plugins/platforms/x11/standalone/screenedges_filter.cpp new file mode 100644
index 000000000..6958ecfc1
--- /dev/null
+++ b/plugins/platforms/x11/standalone/screenedges_filter.cpp
@@ -0,0 +1,65 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2017 Martin Flöser <mgraesslin@kde.org>
+
+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 <http://www.gnu.org/licenses/>.
+*********************************************************************/
+#include "screenedges_filter.h"
+#include "atoms.h"
+#include "screenedge.h"
+
+#include <QWidget>
+#include <xcb/xcb.h>
+
+namespace KWin
+{
+
+ScreenEdgesFilter::ScreenEdgesFilter()
+    : X11EventFilter(QVector<int>{XCB_MOTION_NOTIFY, XCB_ENTER_NOTIFY, \
XCB_CLIENT_MESSAGE}) +{
+}
+
+bool ScreenEdgesFilter::event(xcb_generic_event_t *event)
+{
+    const uint8_t eventType = event->response_type & ~0x80;
+    switch (eventType) {
+    case XCB_MOTION_NOTIFY: {
+        const auto mouseEvent = reinterpret_cast<xcb_motion_notify_event_t*>(event);
+        const QPoint rootPos(mouseEvent->root_x, mouseEvent->root_y);
+        if (QWidget::mouseGrabber()) {
+            ScreenEdges::self()->check(rootPos, \
QDateTime::fromMSecsSinceEpoch(xTime()), true); +        } else {
+            ScreenEdges::self()->check(rootPos, \
QDateTime::fromMSecsSinceEpoch(mouseEvent->time)); +        }
+        // not filtered out
+        break;
+    }
+    case XCB_ENTER_NOTIFY: {
+        const auto enter = reinterpret_cast<xcb_enter_notify_event_t*>(event);
+        return ScreenEdges::self()->handleEnterNotifiy(enter->event, \
QPoint(enter->root_x, enter->root_y), QDateTime::fromMSecsSinceEpoch(enter->time)); + \
} +    case XCB_CLIENT_MESSAGE: {
+        const auto ce = reinterpret_cast<xcb_client_message_event_t*>(event);
+        if (ce->type != atoms->xdnd_position) {
+            return false;
+        }
+        return ScreenEdges::self()->handleDndNotify(ce->window, \
QPoint(ce->data.data32[2] >> 16, ce->data.data32[2] & 0xffff)); +    }
+    }
+    return false;
+}
+
+}
diff --git a/plugins/platforms/x11/standalone/screenedges_filter.h \
b/plugins/platforms/x11/standalone/screenedges_filter.h new file mode 100644
index 000000000..19fb1c032
--- /dev/null
+++ b/plugins/platforms/x11/standalone/screenedges_filter.h
@@ -0,0 +1,37 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2017 Martin Flöser <mgraesslin@kde.org>
+
+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 <http://www.gnu.org/licenses/>.
+*********************************************************************/
+#ifndef KWIN_SCREENEDGES_FILTER_H
+#define KWIN_SCREENEDGES_FILTER_H
+#include "x11eventfilter.h"
+
+namespace KWin
+{
+
+class ScreenEdgesFilter : public X11EventFilter
+{
+public:
+    explicit ScreenEdgesFilter();
+
+    bool event(xcb_generic_event_t *event) override;
+};
+
+}
+
+#endif
diff --git a/plugins/platforms/x11/standalone/x11_platform.cpp \
b/plugins/platforms/x11/standalone/x11_platform.cpp index bbf9ec4ed..e52545fee 100644
--- a/plugins/platforms/x11/standalone/x11_platform.cpp
+++ b/plugins/platforms/x11/standalone/x11_platform.cpp
@@ -33,6 +33,7 @@ along with this program.  If not, see \
<http://www.gnu.org/licenses/>.  #include "keyboard_input.h"
 #include "logging.h"
 #include "screens_xrandr.h"
+#include "screenedges_filter.h"
 #include "options.h"
 #include "overlaywindow_x11.h"
 
@@ -113,6 +114,9 @@ OpenGLBackend *X11StandalonePlatform::createOpenGLBackend()
 
 Edge *X11StandalonePlatform::createScreenEdge(ScreenEdges *edges)
 {
+    if (m_screenEdgesFilter.isNull()) {
+        m_screenEdgesFilter.reset(new ScreenEdgesFilter);
+    }
     return new WindowBasedEdge(edges);
 }
 
diff --git a/plugins/platforms/x11/standalone/x11_platform.h \
b/plugins/platforms/x11/standalone/x11_platform.h index 295e20fdc..eb79276f3 100644
--- a/plugins/platforms/x11/standalone/x11_platform.h
+++ b/plugins/platforms/x11/standalone/x11_platform.h
@@ -29,6 +29,7 @@ namespace KWin
 {
 class XInputIntegration;
 class WindowSelector;
+class X11EventFilter;
 
 class KWIN_EXPORT X11StandalonePlatform : public Platform
 {
@@ -80,6 +81,7 @@ private:
     QTimer *m_openGLFreezeProtection = nullptr;
     Display *m_x11Display;
     QScopedPointer<WindowSelector> m_windowSelector;
+    QScopedPointer<X11EventFilter> m_screenEdgesFilter;
 
 };
 
diff --git a/screenedge.cpp b/screenedge.cpp
index 0b17a0e41..6b32abbd6 100644
--- a/screenedge.cpp
+++ b/screenedge.cpp
@@ -30,7 +30,6 @@ along with this program.  If not, see \
<http://www.gnu.org/licenses/>.  #include "screenedge.h"
 
 // KWin
-#include "atoms.h"
 #include "gestures.h"
 #include <client.h>
 #include "cursor.h"
@@ -1367,22 +1366,6 @@ void ScreenEdges::check(const QPoint &pos, const QDateTime \
&now, bool forceNoPus  }
 }
 
-bool ScreenEdges::isEntered(xcb_enter_notify_event_t *event)
-{
-    return handleEnterNotifiy(event->event,
-                              QPoint(event->root_x, event->root_y),
-                              QDateTime::fromMSecsSinceEpoch(event->time));
-}
-
-bool ScreenEdges::isEntered(xcb_client_message_event_t *event)
-{
-    if (event->type != atoms->xdnd_position) {
-        return false;
-    }
-    return handleDndNotify(event->window,
-                           QPoint(event->data.data32[2] >> 16, event->data.data32[2] \
                & 0xffff));
-}
-
 bool ScreenEdges::isEntered(QMouseEvent *event)
 {
     if (event->type() != QEvent::MouseMove) {
diff --git a/screenedge.h b/screenedge.h
index 779764c53..ee10882bb 100644
--- a/screenedge.h
+++ b/screenedge.h
@@ -312,14 +312,6 @@ public:
      * to do this if an effect input window is active.
      */
     void ensureOnTop();
-    /**
-    * Called when the user entered an electric border with the mouse.
-    * It may switch to another virtual desktop.
-    * @param e the X event which is passed to this method.
-    */
-    bool isEntered(xcb_generic_event_t *e);
-    bool isEntered(xcb_enter_notify_event_t *e);
-    bool isEntered(xcb_client_message_event_t *e);
     bool isEntered(QMouseEvent *event);
 
     /**
@@ -352,6 +344,9 @@ public:
         return m_gestureRecognizer;
     }
 
+    bool handleDndNotify(xcb_window_t window, const QPoint &point);
+    bool handleEnterNotifiy(xcb_window_t window, const QPoint &point, const \
QDateTime &timestamp); +
 public Q_SLOTS:
     void reconfigure();
     /**
@@ -387,8 +382,6 @@ private:
     void setActionForTouchBorder(ElectricBorder border, ElectricBorderAction \
newValue);  ElectricBorderAction actionForEdge(Edge *edge) const;
     ElectricBorderAction actionForTouchEdge(Edge *edge) const;
-    bool handleEnterNotifiy(xcb_window_t window, const QPoint &point, const \
                QDateTime &timestamp);
-    bool handleDndNotify(xcb_window_t window, const QPoint &point);
     void createEdgeForClient(AbstractClient *client, ElectricBorder border);
     void deleteEdgeForClient(AbstractClient *client);
     bool m_desktopSwitching;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic