From 521470b04a7502d804805dee99a9159a3d34b73c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Wed, 17 Feb 2016 13:34:24 +0100 Subject: [PATCH] Improve keyboard handling for internal windows So far the key handler in the InternalWindowEventFilter used the PointerInputRedirection's internal window. This had the result that key events were only delivered to an internal window if the window was under the cursor. This change tries sending the event to the latest created and visible window. Thus e.g. with nested context menus it goes to the current sub menu as expected. The return value of sendEvent is used to filter out the event. --- autotests/wayland/internal_window.cpp | 12 +++++++++++- input.cpp | 22 ++++++++++++++++++---- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/autotests/wayland/internal_window.cpp b/autotests/wayland/internal_window.cpp index d32405d967..af449c3797 100644 --- a/autotests/wayland/internal_window.cpp +++ b/autotests/wayland/internal_window.cpp @@ -44,6 +44,7 @@ private Q_SLOTS: void testEnterLeave(); void testPointerPressRelease(); void testPointerAxis(); + void testKeyboard_data(); void testKeyboard(); }; @@ -237,6 +238,14 @@ void InternalWindowTest::testPointerAxis() QTRY_COMPARE(wheelSpy.count(), 2); } +void InternalWindowTest::testKeyboard_data() +{ + QTest::addColumn("cursorPos"); + + QTest::newRow("on Window") << QPoint(50, 50); + QTest::newRow("outside Window") << QPoint(250, 250); +} + void InternalWindowTest::testKeyboard() { QSignalSpy clientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded); @@ -252,7 +261,8 @@ void InternalWindowTest::testKeyboard() QCOMPARE(clientAddedSpy.count(), 1); quint32 timestamp = 1; - waylandServer()->backend()->pointerMotion(QPoint(50, 50), timestamp++); + QFETCH(QPoint, cursorPos); + waylandServer()->backend()->pointerMotion(cursorPos, timestamp++); waylandServer()->backend()->keyboardKeyPressed(KEY_A, timestamp++); QTRY_COMPARE(pressSpy.count(), 1); diff --git a/input.cpp b/input.cpp index 10e83b0d0b..8bb324e166 100644 --- a/input.cpp +++ b/input.cpp @@ -385,13 +385,27 @@ class InternalWindowEventFilter : public InputEventFilter { return e.isAccepted(); } bool keyEvent(QKeyEvent *event) override { - auto internal = input()->pointer()->internalWindow(); - if (!internal) { + const auto &internalClients = waylandServer()->internalClients(); + if (internalClients.isEmpty()) { + return false; + } + QWindow *found = nullptr; + auto it = internalClients.end(); + do { + it--; + if (QWindow *w = (*it)->internalWindow()) { + if (!w->isVisible()) { + continue; + } + found = w; + break; + } + } while (it != internalClients.begin()); + if (!found) { return false; } event->setAccepted(false); - QCoreApplication::sendEvent(internal.data(), event); - return true; + return QCoreApplication::sendEvent(found, event); } };