diff --git a/autotests/integration/pointer_constraints_test.cpp b/autotests/integration/pointer_constraints_test.cpp --- a/autotests/integration/pointer_constraints_test.cpp +++ b/autotests/integration/pointer_constraints_test.cpp @@ -63,8 +63,6 @@ void testConfinedPointer(); void testLockedPointer_data(); void testLockedPointer(); - void testBreakConstrainedPointer_data(); - void testBreakConstrainedPointer(); void testCloseWindowWithLockedPointer_data(); void testCloseWindowWithLockedPointer(); }; @@ -188,47 +186,27 @@ QCOMPARE(pointerPositionChangedSpy.count(), 1); QCOMPARE(KWin::Cursor::pos(), position); - // let's break the constraint explicitly - input()->pointer()->breakPointerConstraints(); - QCOMPARE(input()->pointer()->isConstrained(), false); + // deactivate the client, this should unconfine + workspace()->activateClient(nullptr); QVERIFY(unconfinedSpy.wait()); + QCOMPARE(input()->pointer()->isConstrained(), false); + + // reconfine pointer (this time with persistent life time) confinedPointer.reset(Test::waylandPointerConstraints()->confinePointer(surface.data(), pointer.data(), nullptr, PointerConstraints::LifeTime::Persistent)); QSignalSpy confinedSpy2(confinedPointer.data(), &ConfinedPointer::confined); QVERIFY(confinedSpy2.isValid()); QSignalSpy unconfinedSpy2(confinedPointer.data(), &ConfinedPointer::unconfined); QVERIFY(unconfinedSpy2.isValid()); - // should get confined - QVERIFY(confinedSpy2.wait()); - QCOMPARE(input()->pointer()->isConstrained(), true); - // now let's unconfine again, any pointer movement should confine again - input()->pointer()->breakPointerConstraints(); - QCOMPARE(input()->pointer()->isConstrained(), false); - QVERIFY(unconfinedSpy2.wait()); - KWin::Cursor::setPos(c->geometry().center()); - QCOMPARE(KWin::Cursor::pos(), c->geometry().center()); - QCOMPARE(input()->pointer()->isConstrained(), true); + // activate it again, this confines again + workspace()->activateClient(static_cast(input()->pointer()->window().data())); QVERIFY(confinedSpy2.wait()); - - // let's use the other break constraint and block - input()->pointer()->breakPointerConstraints(); - input()->pointer()->blockPointerConstraints(); - QCOMPARE(input()->pointer()->isConstrained(), false); - KWin::Cursor::setPos(c->geometry().center() + QPoint(1, 1)); - QCOMPARE(input()->pointer()->isConstrained(), false); - QVERIFY(!confinedSpy2.wait()); - - // now move outside and back in again, that should confine - KWin::Cursor::setPos(c->geometry().bottomRight() + QPoint(1, 1)); - KWin::Cursor::setPos(c->geometry().center() + QPoint(1, 1)); QCOMPARE(input()->pointer()->isConstrained(), true); - QVERIFY(confinedSpy2.wait()); - // deactivate the client, this should unconfine + // deactivate the client one more time with the persistent life time constraint, this should unconfine workspace()->activateClient(nullptr); QVERIFY(unconfinedSpy2.wait()); QCOMPARE(input()->pointer()->isConstrained(), false); - // activate it again, this confines again workspace()->activateClient(static_cast(input()->pointer()->window().data())); QVERIFY(confinedSpy2.wait()); @@ -246,7 +224,7 @@ QVERIFY(confinedSpy2.wait()); // let's set a region which results in unconfined - auto r = Test::waylandCompositor()->createRegion(QRegion(0, 0, 1, 1)); + auto r = Test::waylandCompositor()->createRegion(QRegion(2, 2, 3, 3)); confinedPointer->setRegion(r.get()); surface->commit(Surface::CommitFlag::None); QVERIFY(unconfinedSpy2.wait()); @@ -323,8 +301,8 @@ KWin::Cursor::setPos(c->geometry().center() + QPoint(1, 1)); QCOMPARE(KWin::Cursor::pos(), c->geometry().center()); - // now unlock again - input()->pointer()->breakPointerConstraints(); + // deactivate the client, this should unlock + workspace()->activateClient(nullptr); QCOMPARE(input()->pointer()->isConstrained(), false); QVERIFY(unlockedSpy.wait()); @@ -335,7 +313,11 @@ lockedPointer.reset(Test::waylandPointerConstraints()->lockPointer(surface.data(), pointer.data(), nullptr, PointerConstraints::LifeTime::Persistent)); QSignalSpy lockedSpy2(lockedPointer.data(), &LockedPointer::locked); QVERIFY(lockedSpy2.isValid()); + + // activate the client again, this should lock again + workspace()->activateClient(static_cast(input()->pointer()->window().data())); QVERIFY(lockedSpy2.wait()); + QCOMPARE(input()->pointer()->isConstrained(), true); // try to move the pointer QCOMPARE(input()->pointer()->isConstrained(), true); @@ -356,95 +338,6 @@ QCOMPARE(KWin::Cursor::pos(), c->geometry().center()); } -void TestPointerConstraints::testBreakConstrainedPointer_data() -{ - QTest::addColumn("type"); - - QTest::newRow("wlShell") << Test::ShellSurfaceType::WlShell; - QTest::newRow("xdgShellV5") << Test::ShellSurfaceType::XdgShellV5; - QTest::newRow("xdgShellV6") << Test::ShellSurfaceType::XdgShellV6; -} - -void TestPointerConstraints::testBreakConstrainedPointer() -{ - // this test verifies the breaking of Pointer constraints through the keyboard event filter - QScopedPointer surface(Test::createSurface()); - QFETCH(Test::ShellSurfaceType, type); - QScopedPointer shellSurface(Test::createShellSurface(type, surface.data())); - QScopedPointer pointer(Test::waylandSeat()->createPointer()); - QScopedPointer keyboard(Test::waylandSeat()->createKeyboard()); - QSignalSpy keyboardEnteredSpy(keyboard.data(), &Keyboard::entered); - QVERIFY(keyboardEnteredSpy.isValid()); - QSignalSpy keyboardLeftSpy(keyboard.data(), &Keyboard::left); - QVERIFY(keyboardLeftSpy.isValid()); - QSignalSpy keyChangedSpy(keyboard.data(), &Keyboard::keyChanged); - QVERIFY(keyChangedSpy.isValid()); - QScopedPointer lockedPointer(Test::waylandPointerConstraints()->lockPointer(surface.data(), pointer.data(), nullptr, PointerConstraints::LifeTime::Persistent)); - QSignalSpy lockedSpy(lockedPointer.data(), &LockedPointer::locked); - QVERIFY(lockedSpy.isValid()); - QSignalSpy unlockedSpy(lockedPointer.data(), &LockedPointer::unlocked); - QVERIFY(unlockedSpy.isValid()); - - // now map the window - auto c = Test::renderAndWaitForShown(surface.data(), QSize(100, 100), Qt::blue); - QVERIFY(c); - QVERIFY(!c->geometry().contains(KWin::Cursor::pos())); - QVERIFY(keyboardEnteredSpy.wait()); - // now let's lock - QCOMPARE(input()->pointer()->isConstrained(), false); - KWin::Cursor::setPos(c->geometry().center()); - QCOMPARE(KWin::Cursor::pos(), c->geometry().center()); - QCOMPARE(input()->pointer()->isConstrained(), true); - QVERIFY(lockedSpy.wait()); - - // now try to break - quint32 timestamp = 0; - kwinApp()->platform()->keyboardKeyPressed(KEY_ESC, timestamp++); - 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()); - QCOMPARE(keyChangedSpy.count(), 1); - - // now lock again - // need to move out and in - KWin::Cursor::setPos(c->geometry().bottomRight() + QPoint(1, 1)); - KWin::Cursor::setPos(c->geometry().center()); - QCOMPARE(KWin::Cursor::pos(), c->geometry().center()); - QCOMPARE(input()->pointer()->isConstrained(), true); - QVERIFY(lockedSpy.wait()); - - // and just do a key press/release on esc - kwinApp()->platform()->keyboardKeyPressed(KEY_ESC, timestamp++); - kwinApp()->platform()->keyboardKeyReleased(KEY_ESC, timestamp++); - QCOMPARE(input()->pointer()->isConstrained(), true); - QVERIFY(keyChangedSpy.wait()); - QCOMPARE(keyChangedSpy.last().at(0).value(), quint32(KEY_ESC)); - - // and another variant which won't break - kwinApp()->platform()->keyboardKeyPressed(KEY_ESC, timestamp++); - kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTSHIFT, timestamp++); - kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTSHIFT, timestamp++); - QCOMPARE(input()->pointer()->isConstrained(), true); - QVERIFY(keyChangedSpy.wait()); - QCOMPARE(keyChangedSpy.last().at(0).value(), quint32(KEY_LEFTSHIFT)); - QVERIFY(!unlockedSpy.wait()); - kwinApp()->platform()->keyboardKeyReleased(KEY_ESC, timestamp++); - QVERIFY(keyChangedSpy.wait()); - QCOMPARE(keyChangedSpy.last().at(0).value(), quint32(KEY_ESC)); - - // and now break for real - kwinApp()->platform()->keyboardKeyPressed(KEY_ESC, timestamp++); - QVERIFY(unlockedSpy.wait()); - kwinApp()->platform()->keyboardKeyReleased(KEY_ESC, timestamp++); -} - void TestPointerConstraints::testCloseWindowWithLockedPointer_data() { QTest::addColumn("type"); diff --git a/input.h b/input.h --- a/input.h +++ b/input.h @@ -43,7 +43,6 @@ class InputEventFilter; class InputEventSpy; class KeyboardInputRedirection; -class PointerConstraintsFilter; class PointerInputRedirection; class TouchInputRedirection; class WindowSelectorFilter; @@ -224,8 +223,6 @@ void startInteractivePositionSelection(std::function callback); bool isSelectingWindow() const; - bool isBreakingPointerConstraints() const; - Q_SIGNALS: /** * @brief Emitted when the global pointer position changed @@ -285,7 +282,6 @@ LibInput::Connection *m_libInput = nullptr; WindowSelectorFilter *m_windowSelector = nullptr; - PointerConstraintsFilter *m_pointerConstraintsFilter = nullptr; QVector m_filters; QVector m_spies; diff --git a/input.cpp b/input.cpp --- a/input.cpp +++ b/input.cpp @@ -398,73 +398,6 @@ } }; -class PointerConstraintsFilter : public InputEventFilter { -public: - explicit PointerConstraintsFilter() - : InputEventFilter() - , m_timer(new QTimer) - { - 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 - waylandServer()->seat()->keyReleased(m_keyCode); - cancel(); - } - ); - } - - bool keyEvent(QKeyEvent *event) override { - if (isActive()) { - if (event->type() == QEvent::KeyPress) { - // is that another key that gets pressed? - if (!event->isAutoRepeat() && event->key() != Qt::Key_Escape) { - cancel(); - return false; - } - if (event->isAutoRepeat() && event->key() == Qt::Key_Escape) { - // filter out - return true; - } - } else { - cancel(); - return false; - } - } else if (input()->pointer()->isConstrained()) { - if (event->type() == QEvent::KeyPress && - event->key() == Qt::Key_Escape && - static_cast(event)->modifiersRelevantForGlobalShortcuts() == Qt::KeyboardModifiers()) { - // TODO: don't hard code - m_timer->start(3000); - m_keyCode = event->nativeScanCode(); - return false; - } - } - return false; - } - - void cancel() { - if (!isActive()) { - return; - } - m_timer->stop(); - input()->keyboard()->update(); - } - - bool isActive() const { - return m_timer->isActive(); - } - -private: - QScopedPointer m_timer; - int m_keyCode = 0; -}; - class EffectsFilter : public InputEventFilter { public: bool pointerEvent(QMouseEvent *event, quint32 nativeButton) override { @@ -1723,8 +1656,6 @@ installInputEventFilter(new DragAndDropInputFilter); installInputEventFilter(new LockScreenFilter); installInputEventFilter(new PopupInputFilter); - m_pointerConstraintsFilter = new PointerConstraintsFilter; - installInputEventFilter(m_pointerConstraintsFilter); m_windowSelector = new WindowSelectorFilter; installInputEventFilter(m_windowSelector); } @@ -2141,11 +2072,6 @@ return m_windowSelector ? m_windowSelector->isActive() : false; } -bool InputRedirection::isBreakingPointerConstraints() const -{ - return m_pointerConstraintsFilter ? m_pointerConstraintsFilter->isActive() : false; -} - InputDeviceHandler::InputDeviceHandler(InputRedirection *input) : QObject(input) , m_input(input) diff --git a/pointer_input.h b/pointer_input.h --- a/pointer_input.h +++ b/pointer_input.h @@ -85,12 +85,6 @@ void removeWindowSelectionCursor(); void updatePointerConstraints(); - void breakPointerConstraints(); - - /* This is only used for ESC pressing */ - void blockPointerConstraints() { - m_blockConstraint = true; - } void setEnableConstraints(bool set); @@ -174,7 +168,6 @@ QMetaObject::Connection m_decorationGeometryConnection; bool m_confined = false; bool m_locked = false; - bool m_blockConstraint = false; bool m_enableConstraints = true; }; diff --git a/pointer_input.cpp b/pointer_input.cpp --- a/pointer_input.cpp +++ b/pointer_input.cpp @@ -556,7 +556,6 @@ m_constraintsActivatedConnection = connect(workspace(), &Workspace::clientActivated, this, &PointerInputRedirection::updatePointerConstraints); // check whether a pointer confinement/lock fires - m_blockConstraint = false; updatePointerConstraints(); } else { m_window.clear(); @@ -584,11 +583,6 @@ m_locked = false; } -void PointerInputRedirection::breakPointerConstraints() -{ - breakPointerConstraints(m_window ? m_window->surface() : nullptr); -} - void PointerInputRedirection::disconnectConfinedPointerRegionConnection() { disconnect(m_confinedPointerRegionConnection); @@ -643,9 +637,6 @@ if (!supportsWarping()) { return; } - if (m_blockConstraint) { - return; - } const bool canConstrain = m_enableConstraints && m_window == workspace()->activeClient(); const auto cf = s->confinedPointer(); if (cf) { @@ -683,9 +674,6 @@ } } ); - OSD::show(i18nc("notification about mouse pointer confined", - "Pointer motion confined to the current window.\nTo release pointer hold Escape for 3 seconds."), - QStringLiteral("preferences-desktop-mouse"), 5000); return; } } else { @@ -728,9 +716,6 @@ }); } ); - OSD::show(i18nc("notification about mouse pointer locked", - "Pointer locked to current position.\nTo end pointer lock hold Escape for 3 seconds."), - QStringLiteral("preferences-desktop-mouse"), 5000); // TODO: connect to region change - is it needed at all? If the pointer is locked it's always in the region } } else {