From 229be65e4002987e2de0113ef9b7140492d2d681 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Tue, 18 Apr 2017 07:10:46 +0200 Subject: [PATCH] Improve the escape key handling for breaking constrained pointers Summary: So far KWin started to filter out the escape key as soon as it gets pressed. This was done by unsetting keyboard focus. The idea was to reset keyboard focus when it is only a short press and that then the keyboard state is correct for the application. But in practice this does not work. The only application currently supporting pointer constraints (Xwayland) does not do anything on a key which is pressed when gaining keyboard focus. The result is escape not working in pointer constrained Xwayland windows. This change addresses this problem by changing the interaction to only unset keyboard focus when our break constraints condition is met. This should also result in the application not handling the key release, but it means it gets the key press. Unfortunately I don't have a good way to test. BUG: 378452 Test Plan: None Reviewers: #kwin, #plasma Subscribers: plasma-devel, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D5488 --- autotests/integration/pointer_constraints_test.cpp | 5 +++-- input.cpp | 8 +++++--- keyboard_input.cpp | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/autotests/integration/pointer_constraints_test.cpp b/autotests/integration/pointer_constraints_test.cpp index 7890a346d7..602c9b68ea 100644 --- a/autotests/integration/pointer_constraints_test.cpp +++ b/autotests/integration/pointer_constraints_test.cpp @@ -340,16 +340,17 @@ void TestPointerConstraints::testBreakConstrainedPointer() // now try to break quint32 timestamp = 0; kwinApp()->platform()->keyboardKeyPressed(KEY_ESC, timestamp++); - QVERIFY(keyboardLeftSpy.wait()); + QVERIFY(keyChangedSpy.wait()); // and just waiting should break constrain QVERIFY(unlockedSpy.wait()); + QCOMPARE(keyboardLeftSpy.count(), 1); QCOMPARE(input()->pointer()->isConstrained(), false); // and should enter again QTRY_COMPARE(keyboardEnteredSpy.count(), 2); QCOMPARE(waylandServer()->seat()->focusedKeyboardSurface(), c->surface()); kwinApp()->platform()->keyboardKeyReleased(KEY_ESC, timestamp++); QVERIFY(!keyChangedSpy.wait()); - QVERIFY(keyChangedSpy.isEmpty()); + QCOMPARE(keyChangedSpy.count(), 1); // now lock again // need to move out and in diff --git a/input.cpp b/input.cpp index ad432624e8..2733c6d91e 100644 --- a/input.cpp +++ b/input.cpp @@ -403,6 +403,10 @@ public: { QObject::connect(m_timer.data(), &QTimer::timeout, [this] { + if (waylandServer()) { + // break keyboard focus, this cancels the pressed ESC + waylandServer()->seat()->setFocusedKeyboardSurface(nullptr); + } input()->pointer()->breakPointerConstraints(); input()->pointer()->blockPointerConstraints(); // TODO: show notification @@ -434,10 +438,8 @@ public: static_cast(event)->modifiersRelevantForGlobalShortcuts() == Qt::KeyboardModifiers()) { // TODO: don't hard code m_timer->start(3000); - input()->keyboard()->update(); m_keyCode = event->nativeScanCode(); - passToWaylandServer(event); - return true; + return false; } } return false; diff --git a/keyboard_input.cpp b/keyboard_input.cpp index 8a941b0267..e6e5512e79 100644 --- a/keyboard_input.cpp +++ b/keyboard_input.cpp @@ -598,7 +598,7 @@ void KeyboardInputRedirection::update() break; } while (it != stacking.begin()); } - } else if (!input()->isSelectingWindow() && !input()->isBreakingPointerConstraints()) { + } else if (!input()->isSelectingWindow()) { found = workspace()->activeClient(); } if (found && found->surface()) {