diff --git a/abstract_client.cpp b/abstract_client.cpp index f6911129b6..841eba7116 100644 --- a/abstract_client.cpp +++ b/abstract_client.cpp @@ -1430,14 +1430,14 @@ void AbstractClient::setupWindowManagementInterface() connect(w, &PlasmaWindowInterface::closeRequested, this, [this] { closeWindow(); }); connect(w, &PlasmaWindowInterface::moveRequested, this, [this] { - Cursor::setPos(frameGeometry().center()); - performMouseCommand(Options::MouseMove, Cursor::pos()); + Cursors::self()->mouse()->setPos(frameGeometry().center()); + performMouseCommand(Options::MouseMove, Cursors::self()->mouse()->pos()); } ); connect(w, &PlasmaWindowInterface::resizeRequested, this, [this] { - Cursor::setPos(frameGeometry().bottomRight()); - performMouseCommand(Options::MouseResize, Cursor::pos()); + Cursors::self()->mouse()->setPos(frameGeometry().bottomRight()); + performMouseCommand(Options::MouseResize, Cursors::self()->mouse()->pos()); } ); connect(w, &PlasmaWindowInterface::virtualDesktopRequested, this, @@ -2060,7 +2060,7 @@ void AbstractClient::keyPressEvent(uint key_code) bool is_alt = key_code & Qt::ALT; key_code = key_code & ~Qt::KeyboardModifierMask; int delta = is_control ? 1 : is_alt ? 32 : 8; - QPoint pos = Cursor::pos(); + QPoint pos = Cursors::self()->mouse()->pos(); switch(key_code) { case Qt::Key_Left: pos.rx() -= delta; @@ -2089,7 +2089,7 @@ void AbstractClient::keyPressEvent(uint key_code) default: return; } - Cursor::setPos(pos); + Cursors::self()->mouse()->setPos(pos); } QSize AbstractClient::resizeIncrements() const @@ -2659,7 +2659,7 @@ void AbstractClient::setElectricBorderMaximizing(bool maximizing) { m_electricMaximizing = maximizing; if (maximizing) - outline()->show(electricBorderMaximizeGeometry(Cursor::pos(), desktop()), moveResizeGeometry()); + outline()->show(electricBorderMaximizeGeometry(Cursors::self()->mouse()->pos(), desktop()), moveResizeGeometry()); else outline()->hide(); elevate(maximizing); @@ -2694,7 +2694,7 @@ void AbstractClient::setQuickTileMode(QuickTileMode mode, bool keyboard) return; } - workspace()->updateFocusMousePosition(Cursor::pos()); // may cause leave event + workspace()->updateFocusMousePosition(Cursors::self()->mouse()->pos()); // may cause leave event GeometryUpdatesBlocker blocker(this); @@ -2736,7 +2736,7 @@ void AbstractClient::setQuickTileMode(QuickTileMode mode, bool keyboard) setMaximize(false, false); - setFrameGeometry(electricBorderMaximizeGeometry(keyboard ? frameGeometry().center() : Cursor::pos(), desktop()), geom_mode); + setFrameGeometry(electricBorderMaximizeGeometry(keyboard ? frameGeometry().center() : Cursors::self()->mouse()->pos(), desktop()), geom_mode); // Store the mode change m_quickTileMode = mode; } else { @@ -2750,7 +2750,7 @@ void AbstractClient::setQuickTileMode(QuickTileMode mode, bool keyboard) } if (mode != QuickTileMode(QuickTileFlag::None)) { - QPoint whichScreen = keyboard ? frameGeometry().center() : Cursor::pos(); + QPoint whichScreen = keyboard ? frameGeometry().center() : Cursors::self()->mouse()->pos(); // If trying to tile to the side that the window is already tiled to move the window to the next // screen if it exists, otherwise toggle the mode (set QuickTileFlag::None) diff --git a/activation.cpp b/activation.cpp index 068cc60b53..c2218069c6 100644 --- a/activation.cpp +++ b/activation.cpp @@ -238,7 +238,7 @@ void Workspace::setActiveClient(AbstractClient* c) } StackingUpdatesBlocker blocker(this); ++set_active_client_recursion; - updateFocusMousePosition(Cursor::pos()); + updateFocusMousePosition(Cursors::self()->mouse()->pos()); if (active_client != nullptr) { // note that this may call setActiveClient( NULL ), therefore the recursion counter active_client->setActive(false); @@ -430,7 +430,7 @@ AbstractClient *Workspace::clientUnderMouse(int screen) const client->isOnCurrentActivity() && client->isOnScreen(screen))) continue; - if (client->frameGeometry().contains(Cursor::pos())) { + if (client->frameGeometry().contains(Cursors::self()->mouse()->pos())) { return client; } } diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index 40ce86eeb2..7f62ded9e4 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -167,6 +167,7 @@ ecm_mark_as_test(testBuiltInEffectLoader) include_directories(${KWin_SOURCE_DIR}) set(testScriptedEffectLoader_SRCS ../effectloader.cpp + ../cursor.cpp ../screens.cpp ../scripting/scriptedeffect.cpp ../scripting/scripting_logging.cpp @@ -244,6 +245,7 @@ target_link_libraries(effectversionplugin kwineffects) ######################################################## set(testScreens_SRCS ../screens.cpp + ../cursor.cpp ../x11eventfilter.cpp mock_abstract_client.cpp mock_screens.cpp @@ -282,6 +284,7 @@ set(testScreenEdges_SRCS ../screenedge.cpp ../screens.cpp ../virtualdesktops.cpp + ../cursor.cpp ../xcbutils.cpp # init of extensions mock_abstract_client.cpp mock_screens.cpp diff --git a/autotests/integration/activation_test.cpp b/autotests/integration/activation_test.cpp index c0898374a7..2758a6deae 100644 --- a/autotests/integration/activation_test.cpp +++ b/autotests/integration/activation_test.cpp @@ -78,7 +78,7 @@ void ActivationTest::init() QVERIFY(Test::setupWaylandConnection()); screens()->setCurrent(0); - Cursor::setPos(QPoint(640, 512)); + Cursors::self()->mouse()->setPos(QPoint(640, 512)); } void ActivationTest::cleanup() diff --git a/autotests/integration/activities_test.cpp b/autotests/integration/activities_test.cpp index 668ea8d59c..838778f302 100644 --- a/autotests/integration/activities_test.cpp +++ b/autotests/integration/activities_test.cpp @@ -88,7 +88,7 @@ void ActivitiesTest::cleanupTestCase() void ActivitiesTest::init() { screens()->setCurrent(0); - Cursor::setPos(QPoint(640, 512)); + Cursors::self()->mouse()->setPos(QPoint(640, 512)); } void ActivitiesTest::cleanup() diff --git a/autotests/integration/decoration_input_test.cpp b/autotests/integration/decoration_input_test.cpp index d2a4687e28..362cf2f7ac 100644 --- a/autotests/integration/decoration_input_test.cpp +++ b/autotests/integration/decoration_input_test.cpp @@ -165,7 +165,7 @@ void DecorationInputTest::init() QVERIFY(Test::waitForWaylandPointer()); screens()->setCurrent(0); - Cursor::setPos(QPoint(640, 512)); + Cursors::self()->mouse()->setPos(QPoint(640, 512)); } void DecorationInputTest::cleanup() @@ -556,7 +556,7 @@ void DecorationInputTest::testResizeOutsideWindow() default: break; } - QVERIFY(!c->frameGeometry().contains(KWin::Cursor::pos())); + QVERIFY(!c->frameGeometry().contains(KWin::Cursors::self()->mouse()->pos())); // pressing should trigger resize PRESS; @@ -641,7 +641,7 @@ void DecorationInputTest::testModifierClickUnrestrictedMove() QVERIFY(!c->noBorder()); c->move(screens()->geometry(0).center() - QPoint(c->width()/2, c->height()/2)); // move cursor on window - Cursor::setPos(QPoint(c->frameGeometry().center().x(), c->y() + c->clientPos().y() / 2)); + Cursors::self()->mouse()->setPos(QPoint(c->frameGeometry().center().x(), c->y() + c->clientPos().y() / 2)); // simulate modifier+click quint32 timestamp = 1; @@ -711,7 +711,7 @@ void DecorationInputTest::testModifierScrollOpacity() QVERIFY(!c->noBorder()); c->move(screens()->geometry(0).center() - QPoint(c->width()/2, c->height()/2)); // move cursor on window - Cursor::setPos(QPoint(c->frameGeometry().center().x(), c->y() + c->clientPos().y() / 2)); + Cursors::self()->mouse()->setPos(QPoint(c->frameGeometry().center().x(), c->y() + c->clientPos().y() / 2)); // set the opacity to 0.5 c->setOpacity(0.5); QCOMPARE(c->opacity(), 0.5); @@ -797,7 +797,7 @@ void DecorationInputTest::testTouchEvents() QCOMPARE(c->isMove(), false); // let's check that a hover motion is sent if the pointer is on deco, when touch release - Cursor::setPos(tapPoint); + Cursors::self()->mouse()->setPos(tapPoint); QCOMPARE(hoverMoveSpy.count(), 2); kwinApp()->platform()->touchDown(0, tapPoint, timestamp++); QCOMPARE(hoverMoveSpy.count(), 3); diff --git a/autotests/integration/desktop_window_x11_test.cpp b/autotests/integration/desktop_window_x11_test.cpp index 42525ea638..859ac4426f 100644 --- a/autotests/integration/desktop_window_x11_test.cpp +++ b/autotests/integration/desktop_window_x11_test.cpp @@ -72,7 +72,7 @@ void X11DesktopWindowTest::initTestCase() void X11DesktopWindowTest::init() { screens()->setCurrent(0); - Cursor::setPos(QPoint(640, 512)); + Cursors::self()->mouse()->setPos(QPoint(640, 512)); } void X11DesktopWindowTest::cleanup() diff --git a/autotests/integration/dont_crash_aurorae_destroy_deco.cpp b/autotests/integration/dont_crash_aurorae_destroy_deco.cpp index dfb5a2ca79..91224e577c 100644 --- a/autotests/integration/dont_crash_aurorae_destroy_deco.cpp +++ b/autotests/integration/dont_crash_aurorae_destroy_deco.cpp @@ -83,7 +83,7 @@ void DontCrashAuroraeDestroyDecoTest::initTestCase() void DontCrashAuroraeDestroyDecoTest::init() { screens()->setCurrent(0); - Cursor::setPos(QPoint(640, 512)); + Cursors::self()->mouse()->setPos(QPoint(640, 512)); } void DontCrashAuroraeDestroyDecoTest::testBorderlessMaximizedWindows() diff --git a/autotests/integration/dont_crash_cursor_physical_size_empty.cpp b/autotests/integration/dont_crash_cursor_physical_size_empty.cpp index 17864b39e2..0b7f5dd01c 100644 --- a/autotests/integration/dont_crash_cursor_physical_size_empty.cpp +++ b/autotests/integration/dont_crash_cursor_physical_size_empty.cpp @@ -56,7 +56,7 @@ void DontCrashCursorPhysicalSizeEmpty::init() QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Decoration)); screens()->setCurrent(0); - KWin::Cursor::setPos(QPoint(640, 512)); + KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); } void DontCrashCursorPhysicalSizeEmpty::cleanup() @@ -110,9 +110,9 @@ void DontCrashCursorPhysicalSizeEmpty::testMoveCursorOverDeco() auto output = display->outputs().first(); output->setPhysicalSize(QSize(0, 0)); // and fake a cursor theme change, so that the theme gets recreated - emit KWin::Cursor::self()->themeChanged(); + emit KWin::Cursors::self()->mouse()->themeChanged(); - KWin::Cursor::setPos(QPoint(c->frameGeometry().center().x(), c->clientPos().y() / 2)); + KWin::Cursors::self()->mouse()->setPos(QPoint(c->frameGeometry().center().x(), c->clientPos().y() / 2)); } WAYLANDTEST_MAIN(DontCrashCursorPhysicalSizeEmpty) diff --git a/autotests/integration/dont_crash_empty_deco.cpp b/autotests/integration/dont_crash_empty_deco.cpp index 273a8489ff..a8ee608032 100644 --- a/autotests/integration/dont_crash_empty_deco.cpp +++ b/autotests/integration/dont_crash_empty_deco.cpp @@ -74,7 +74,7 @@ void DontCrashEmptyDecorationTest::initTestCase() void DontCrashEmptyDecorationTest::init() { screens()->setCurrent(0); - Cursor::setPos(QPoint(640, 512)); + Cursors::self()->mouse()->setPos(QPoint(640, 512)); } void DontCrashEmptyDecorationTest::testBug361551() diff --git a/autotests/integration/dont_crash_no_border.cpp b/autotests/integration/dont_crash_no_border.cpp index 2d1568eb0c..a4352630e5 100644 --- a/autotests/integration/dont_crash_no_border.cpp +++ b/autotests/integration/dont_crash_no_border.cpp @@ -87,7 +87,7 @@ void DontCrashNoBorder::init() QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Decoration)); screens()->setCurrent(0); - Cursor::setPos(QPoint(640, 512)); + Cursors::self()->mouse()->setPos(QPoint(640, 512)); } void DontCrashNoBorder::cleanup() diff --git a/autotests/integration/dont_crash_useractions_menu.cpp b/autotests/integration/dont_crash_useractions_menu.cpp index 86cd72c419..7f9fae0856 100644 --- a/autotests/integration/dont_crash_useractions_menu.cpp +++ b/autotests/integration/dont_crash_useractions_menu.cpp @@ -79,7 +79,7 @@ void TestDontCrashUseractionsMenu::init() QVERIFY(Test::setupWaylandConnection()); screens()->setCurrent(0); - KWin::Cursor::setPos(QPoint(1280, 512)); + KWin::Cursors::self()->mouse()->setPos(QPoint(1280, 512)); } void TestDontCrashUseractionsMenu::cleanup() diff --git a/autotests/integration/effects/translucency_test.cpp b/autotests/integration/effects/translucency_test.cpp index 3cff53ccf2..a5a69cecb9 100644 --- a/autotests/integration/effects/translucency_test.cpp +++ b/autotests/integration/effects/translucency_test.cpp @@ -162,7 +162,7 @@ void TranslucencyTest::testMoveAfterDesktopChange() workspace()->sendClientToDesktop(client, 2, false); effects->setCurrentDesktop(2); QVERIFY(!m_translucencyEffect->isActive()); - KWin::Cursor::setPos(client->frameGeometry().center()); + KWin::Cursors::self()->mouse()->setPos(client->frameGeometry().center()); workspace()->performWindowOperation(client, Options::MoveOp); QVERIFY(m_translucencyEffect->isActive()); QTest::qWait(200); diff --git a/autotests/integration/effects/wobbly_shade_test.cpp b/autotests/integration/effects/wobbly_shade_test.cpp index 8a6860fae7..e07780b951 100644 --- a/autotests/integration/effects/wobbly_shade_test.cpp +++ b/autotests/integration/effects/wobbly_shade_test.cpp @@ -168,19 +168,19 @@ void WobblyWindowsShadeTest::testShadeMove() // send some key events, not going through input redirection client->keyPressEvent(Qt::Key_Right); - client->updateMoveResize(KWin::Cursor::pos()); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); // wait for frame rendered QTest::qWait(100); client->keyPressEvent(Qt::Key_Right); - client->updateMoveResize(KWin::Cursor::pos()); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); // wait for frame rendered QTest::qWait(100); client->keyPressEvent(Qt::Key_Down | Qt::ALT); - client->updateMoveResize(KWin::Cursor::pos()); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); // wait for frame rendered QTest::qWait(100); diff --git a/autotests/integration/globalshortcuts_test.cpp b/autotests/integration/globalshortcuts_test.cpp index 9403ac7bfb..c041108439 100644 --- a/autotests/integration/globalshortcuts_test.cpp +++ b/autotests/integration/globalshortcuts_test.cpp @@ -82,7 +82,7 @@ void GlobalShortcutsTest::init() { QVERIFY(Test::setupWaylandConnection()); screens()->setCurrent(0); - KWin::Cursor::setPos(QPoint(640, 512)); + KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); } void GlobalShortcutsTest::cleanup() diff --git a/autotests/integration/input_stacking_order.cpp b/autotests/integration/input_stacking_order.cpp index 3af47a71aa..bebfb1426e 100644 --- a/autotests/integration/input_stacking_order.cpp +++ b/autotests/integration/input_stacking_order.cpp @@ -84,7 +84,7 @@ void InputStackingOrderTest::init() QVERIFY(Test::waitForWaylandPointer()); screens()->setCurrent(0); - Cursor::setPos(QPoint(640, 512)); + Cursors::self()->mouse()->setPos(QPoint(640, 512)); } void InputStackingOrderTest::cleanup() diff --git a/autotests/integration/internal_window.cpp b/autotests/integration/internal_window.cpp index ac2fcab900..e4d110feca 100644 --- a/autotests/integration/internal_window.cpp +++ b/autotests/integration/internal_window.cpp @@ -201,7 +201,7 @@ void InternalWindowTest::initTestCase() void InternalWindowTest::init() { - Cursor::setPos(QPoint(1280, 512)); + Cursors::self()->mouse()->setPos(QPoint(1280, 512)); QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Seat)); QVERIFY(Test::waitForWaylandKeyboard()); } @@ -617,7 +617,7 @@ void InternalWindowTest::testModifierClickUnrestrictedMove() QCOMPARE(options->commandAll3(), Options::MouseUnrestrictedMove); // move cursor on window - Cursor::setPos(internalClient->frameGeometry().center()); + Cursors::self()->mouse()->setPos(internalClient->frameGeometry().center()); // simulate modifier+click quint32 timestamp = 1; @@ -653,7 +653,7 @@ void InternalWindowTest::testModifierScroll() workspace()->slotReconfigure(); // move cursor on window - Cursor::setPos(internalClient->frameGeometry().center()); + Cursors::self()->mouse()->setPos(internalClient->frameGeometry().center()); // set the opacity to 0.5 internalClient->setOpacity(0.5); diff --git a/autotests/integration/kwinbindings_test.cpp b/autotests/integration/kwinbindings_test.cpp index ca61d426c2..ba86bd1406 100644 --- a/autotests/integration/kwinbindings_test.cpp +++ b/autotests/integration/kwinbindings_test.cpp @@ -74,7 +74,7 @@ void KWinBindingsTest::init() { QVERIFY(Test::setupWaylandConnection()); screens()->setCurrent(0); - KWin::Cursor::setPos(QPoint(640, 512)); + KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); } void KWinBindingsTest::cleanup() diff --git a/autotests/integration/lockscreen.cpp b/autotests/integration/lockscreen.cpp index eff058bf81..6058c7a7be 100644 --- a/autotests/integration/lockscreen.cpp +++ b/autotests/integration/lockscreen.cpp @@ -213,7 +213,7 @@ void LockScreenTest::init() m_seat = Test::waylandSeat(); screens()->setCurrent(0); - Cursor::setPos(QPoint(640, 512)); + Cursors::self()->mouse()->setPos(QPoint(640, 512)); } void LockScreenTest::cleanup() diff --git a/autotests/integration/maximize_test.cpp b/autotests/integration/maximize_test.cpp index 9b8cd7851a..e11e8db99d 100644 --- a/autotests/integration/maximize_test.cpp +++ b/autotests/integration/maximize_test.cpp @@ -85,7 +85,7 @@ void TestMaximized::init() Test::AdditionalWaylandInterface::PlasmaShell)); screens()->setCurrent(0); - KWin::Cursor::setPos(QPoint(1280, 512)); + KWin::Cursors::self()->mouse()->setPos(QPoint(1280, 512)); } void TestMaximized::cleanup() diff --git a/autotests/integration/modifier_only_shortcut_test.cpp b/autotests/integration/modifier_only_shortcut_test.cpp index e88cbb0a53..a974727d53 100644 --- a/autotests/integration/modifier_only_shortcut_test.cpp +++ b/autotests/integration/modifier_only_shortcut_test.cpp @@ -107,7 +107,7 @@ void ModifierOnlyShortcutTest::initTestCase() void ModifierOnlyShortcutTest::init() { screens()->setCurrent(0); - KWin::Cursor::setPos(QPoint(640, 512)); + KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); } void ModifierOnlyShortcutTest::cleanup() diff --git a/autotests/integration/move_resize_window_test.cpp b/autotests/integration/move_resize_window_test.cpp index 5b0e3122b5..d2fe89fe79 100644 --- a/autotests/integration/move_resize_window_test.cpp +++ b/autotests/integration/move_resize_window_test.cpp @@ -164,27 +164,27 @@ void MoveResizeWindowTest::testMove() QCOMPARE(c->geometryRestore(), QRect(0, 0, 100, 50)); // send some key events, not going through input redirection - const QPoint cursorPos = Cursor::pos(); + const QPoint cursorPos = Cursors::self()->mouse()->pos(); c->keyPressEvent(Qt::Key_Right); - c->updateMoveResize(Cursor::pos()); - QCOMPARE(Cursor::pos(), cursorPos + QPoint(8, 0)); + c->updateMoveResize(Cursors::self()->mouse()->pos()); + QCOMPARE(Cursors::self()->mouse()->pos(), cursorPos + QPoint(8, 0)); QEXPECT_FAIL("", "First event is ignored", Continue); QCOMPARE(clientStepUserMovedResizedSpy.count(), 1); clientStepUserMovedResizedSpy.clear(); windowStepUserMovedResizedSpy.clear(); c->keyPressEvent(Qt::Key_Right); - c->updateMoveResize(Cursor::pos()); - QCOMPARE(Cursor::pos(), cursorPos + QPoint(16, 0)); + c->updateMoveResize(Cursors::self()->mouse()->pos()); + QCOMPARE(Cursors::self()->mouse()->pos(), cursorPos + QPoint(16, 0)); QCOMPARE(clientStepUserMovedResizedSpy.count(), 1); QCOMPARE(windowStepUserMovedResizedSpy.count(), 1); c->keyPressEvent(Qt::Key_Down | Qt::ALT); - c->updateMoveResize(Cursor::pos()); + c->updateMoveResize(Cursors::self()->mouse()->pos()); QCOMPARE(clientStepUserMovedResizedSpy.count(), 2); QCOMPARE(windowStepUserMovedResizedSpy.count(), 2); QCOMPARE(c->frameGeometry(), QRect(16, 32, 100, 50)); - QCOMPARE(Cursor::pos(), cursorPos + QPoint(16, 32)); + QCOMPARE(Cursors::self()->mouse()->pos(), cursorPos + QPoint(16, 32)); // let's end QCOMPARE(clientFinishUserMovedResizedSpy.count(), 0); @@ -266,10 +266,10 @@ void MoveResizeWindowTest::testResize() QVERIFY(states.testFlag(XdgShellSurface::State::Resizing)); // Trigger a change. - const QPoint cursorPos = Cursor::pos(); + const QPoint cursorPos = Cursors::self()->mouse()->pos(); c->keyPressEvent(Qt::Key_Right); - c->updateMoveResize(Cursor::pos()); - QCOMPARE(Cursor::pos(), cursorPos + QPoint(8, 0)); + c->updateMoveResize(Cursors::self()->mouse()->pos()); + QCOMPARE(Cursors::self()->mouse()->pos(), cursorPos + QPoint(8, 0)); // The client should receive a configure event with the new size. QVERIFY(configureRequestedSpy.wait()); @@ -290,8 +290,8 @@ void MoveResizeWindowTest::testResize() // Go down. c->keyPressEvent(Qt::Key_Down); - c->updateMoveResize(Cursor::pos()); - QCOMPARE(Cursor::pos(), cursorPos + QPoint(8, 8)); + c->updateMoveResize(Cursors::self()->mouse()->pos()); + QCOMPARE(Cursors::self()->mouse()->pos(), cursorPos + QPoint(8, 8)); // The client should receive another configure event. QVERIFY(configureRequestedSpy.wait()); @@ -556,7 +556,7 @@ void MoveResizeWindowTest::testClientSideMove_data() void MoveResizeWindowTest::testClientSideMove() { using namespace KWayland::Client; - Cursor::setPos(640, 512); + Cursors::self()->mouse()->setPos(640, 512); QScopedPointer pointer(Test::waylandSeat()->createPointer()); QSignalSpy pointerEnteredSpy(pointer.data(), &Pointer::entered); QVERIFY(pointerEnteredSpy.isValid()); @@ -573,7 +573,7 @@ void MoveResizeWindowTest::testClientSideMove() // move pointer into center of geometry const QRect startGeometry = c->frameGeometry(); - Cursor::setPos(startGeometry.center()); + Cursors::self()->mouse()->setPos(startGeometry.center()); QVERIFY(pointerEnteredSpy.wait()); QCOMPARE(pointerEnteredSpy.first().last().toPoint(), QPoint(49, 24)); // simulate press @@ -681,8 +681,8 @@ void MoveResizeWindowTest::testNetMove() const QRect origGeo = client->frameGeometry(); // let's move the cursor outside the window - Cursor::setPos(screens()->geometry(0).center()); - QVERIFY(!origGeo.contains(Cursor::pos())); + Cursors::self()->mouse()->setPos(screens()->geometry(0).center()); + QVERIFY(!origGeo.contains(Cursors::self()->mouse()->pos())); QSignalSpy moveStartSpy(client, &X11Client::clientStartUserMovedResized); QVERIFY(moveStartSpy.isValid()); @@ -701,10 +701,10 @@ void MoveResizeWindowTest::testNetMove() QCOMPARE(workspace()->moveResizeClient(), client); QVERIFY(client->isMove()); QCOMPARE(client->geometryRestore(), origGeo); - QCOMPARE(Cursor::pos(), origGeo.center()); + QCOMPARE(Cursors::self()->mouse()->pos(), origGeo.center()); // let's move a step - Cursor::setPos(Cursor::pos() + QPoint(10, 10)); + Cursors::self()->mouse()->setPos(Cursors::self()->mouse()->pos() + QPoint(10, 10)); QCOMPARE(moveStepSpy.count(), 1); QCOMPARE(moveStepSpy.first().last().toRect(), origGeo.translated(10, 10)); diff --git a/autotests/integration/no_global_shortcuts_test.cpp b/autotests/integration/no_global_shortcuts_test.cpp index 7524dc2d02..5b08ea05cc 100644 --- a/autotests/integration/no_global_shortcuts_test.cpp +++ b/autotests/integration/no_global_shortcuts_test.cpp @@ -117,7 +117,7 @@ void NoGlobalShortcutsTest::initTestCase() void NoGlobalShortcutsTest::init() { screens()->setCurrent(0); - KWin::Cursor::setPos(QPoint(640, 512)); + KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); } void NoGlobalShortcutsTest::cleanup() diff --git a/autotests/integration/placement_test.cpp b/autotests/integration/placement_test.cpp index 1ec5788619..22ecee9ec0 100644 --- a/autotests/integration/placement_test.cpp +++ b/autotests/integration/placement_test.cpp @@ -80,7 +80,7 @@ void TestPlacement::init() Test::AdditionalWaylandInterface::PlasmaShell)); screens()->setCurrent(0); - KWin::Cursor::setPos(QPoint(512, 512)); + KWin::Cursors::self()->mouse()->setPos(QPoint(512, 512)); } void TestPlacement::cleanup() @@ -267,8 +267,8 @@ void TestPlacement::testPlaceUnderMouse() group.sync(); workspace()->slotReconfigure(); - KWin::Cursor::setPos(QPoint(200, 300)); - QCOMPARE(KWin::Cursor::pos(), QPoint(200, 300)); + KWin::Cursors::self()->mouse()->setPos(QPoint(200, 300)); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), QPoint(200, 300)); QScopedPointer surface(Test::createSurface()); QScopedPointer shellSurface(Test::createXdgShellStableSurface(surface.data())); diff --git a/autotests/integration/plasma_surface_test.cpp b/autotests/integration/plasma_surface_test.cpp index d03c0a22fb..67db9fb1df 100644 --- a/autotests/integration/plasma_surface_test.cpp +++ b/autotests/integration/plasma_surface_test.cpp @@ -85,7 +85,7 @@ void PlasmaSurfaceTest::init() m_compositor = Test::waylandCompositor(); m_plasmaShell = Test::waylandPlasmaShell(); - KWin::Cursor::setPos(640, 512); + KWin::Cursors::self()->mouse()->setPos(640, 512); } void PlasmaSurfaceTest::cleanup() @@ -391,7 +391,7 @@ void PlasmaSurfaceTest::testPanelWindowsCanCover() QVERIFY(stackingOrderChangedSpy.isValid()); // trigger screenedge QFETCH(QPoint, triggerPoint); - KWin::Cursor::setPos(triggerPoint); + KWin::Cursors::self()->mouse()->setPos(triggerPoint); QCOMPARE(stackingOrderChangedSpy.count(), 1); stackingOrder = workspace()->stackingOrder(); QCOMPARE(stackingOrder.count(), 2); diff --git a/autotests/integration/plasmawindow_test.cpp b/autotests/integration/plasmawindow_test.cpp index 4b22e98f2f..22cffcfe1a 100644 --- a/autotests/integration/plasmawindow_test.cpp +++ b/autotests/integration/plasmawindow_test.cpp @@ -91,7 +91,7 @@ void PlasmaWindowTest::init() m_compositor = Test::waylandCompositor(); screens()->setCurrent(0); - Cursor::setPos(QPoint(640, 512)); + Cursors::self()->mouse()->setPos(QPoint(640, 512)); } void PlasmaWindowTest::cleanup() diff --git a/autotests/integration/platformcursor.cpp b/autotests/integration/platformcursor.cpp index 3d0ff4581c..0f5b188cb8 100644 --- a/autotests/integration/platformcursor.cpp +++ b/autotests/integration/platformcursor.cpp @@ -51,17 +51,17 @@ void PlatformCursorTest::testPos() // that is QCursor should work just like KWin::Cursor // cursor should be centered on screen - QCOMPARE(Cursor::pos(), QPoint(639, 511)); - QCOMPARE(QCursor::pos(), QPoint(639, 511)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(639, 511)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(639, 511)); // let's set the pos through QCursor API QCursor::setPos(QPoint(10, 10)); - QCOMPARE(Cursor::pos(), QPoint(10, 10)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(10, 10)); QCOMPARE(QCursor::pos(), QPoint(10, 10)); // and let's set the pos through Cursor API QCursor::setPos(QPoint(20, 20)); - QCOMPARE(Cursor::pos(), QPoint(20, 20)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(20, 20)); QCOMPARE(QCursor::pos(), QPoint(20, 20)); } diff --git a/autotests/integration/pointer_constraints_test.cpp b/autotests/integration/pointer_constraints_test.cpp index 5514e14658..68570275e6 100644 --- a/autotests/integration/pointer_constraints_test.cpp +++ b/autotests/integration/pointer_constraints_test.cpp @@ -99,7 +99,7 @@ void TestPointerConstraints::init() QVERIFY(Test::waitForWaylandPointer()); screens()->setCurrent(0); - KWin::Cursor::setPos(QPoint(1280, 512)); + KWin::Cursors::self()->mouse()->setPos(QPoint(1280, 512)); } void TestPointerConstraints::cleanup() @@ -144,37 +144,37 @@ void TestPointerConstraints::testConfinedPointer() if (c->pos() == QPoint(0, 0)) { c->move(QPoint(1, 1)); } - QVERIFY(!c->frameGeometry().contains(KWin::Cursor::pos())); + QVERIFY(!c->frameGeometry().contains(KWin::Cursors::self()->mouse()->pos())); // now let's confine QCOMPARE(input()->pointer()->isConstrained(), false); - KWin::Cursor::setPos(c->frameGeometry().center()); + KWin::Cursors::self()->mouse()->setPos(c->frameGeometry().center()); QCOMPARE(input()->pointer()->isConstrained(), true); QVERIFY(confinedSpy.wait()); // picking a position outside the window geometry should not move pointer QSignalSpy pointerPositionChangedSpy(input(), &InputRedirection::globalPointerChanged); QVERIFY(pointerPositionChangedSpy.isValid()); - KWin::Cursor::setPos(QPoint(1280, 512)); + KWin::Cursors::self()->mouse()->setPos(QPoint(1280, 512)); QVERIFY(pointerPositionChangedSpy.isEmpty()); - QCOMPARE(KWin::Cursor::pos(), c->frameGeometry().center()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), c->frameGeometry().center()); // TODO: test relative motion QFETCH(PointerFunc, positionFunction); const QPoint position = positionFunction(c->frameGeometry()); - KWin::Cursor::setPos(position); + KWin::Cursors::self()->mouse()->setPos(position); QCOMPARE(pointerPositionChangedSpy.count(), 1); - QCOMPARE(KWin::Cursor::pos(), position); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), position); // moving one to right should not be possible QFETCH(int, xOffset); - KWin::Cursor::setPos(position + QPoint(xOffset, 0)); + KWin::Cursors::self()->mouse()->setPos(position + QPoint(xOffset, 0)); QCOMPARE(pointerPositionChangedSpy.count(), 1); - QCOMPARE(KWin::Cursor::pos(), position); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), position); // moving one to bottom should not be possible QFETCH(int, yOffset); - KWin::Cursor::setPos(position + QPoint(0, yOffset)); + KWin::Cursors::self()->mouse()->setPos(position + QPoint(0, yOffset)); QCOMPARE(pointerPositionChangedSpy.count(), 1); - QCOMPARE(KWin::Cursor::pos(), position); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), position); // modifier + click should be ignored // first ensure the settings are ok @@ -308,19 +308,19 @@ void TestPointerConstraints::testLockedPointer() // now map the window auto c = Test::renderAndWaitForShown(surface.data(), QSize(100, 100), Qt::blue); QVERIFY(c); - QVERIFY(!c->frameGeometry().contains(KWin::Cursor::pos())); + QVERIFY(!c->frameGeometry().contains(KWin::Cursors::self()->mouse()->pos())); // now let's lock QCOMPARE(input()->pointer()->isConstrained(), false); - KWin::Cursor::setPos(c->frameGeometry().center()); - QCOMPARE(KWin::Cursor::pos(), c->frameGeometry().center()); + KWin::Cursors::self()->mouse()->setPos(c->frameGeometry().center()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), c->frameGeometry().center()); QCOMPARE(input()->pointer()->isConstrained(), true); QVERIFY(lockedSpy.wait()); // try to move the pointer // TODO: add relative pointer - KWin::Cursor::setPos(c->frameGeometry().center() + QPoint(1, 1)); - QCOMPARE(KWin::Cursor::pos(), c->frameGeometry().center()); + KWin::Cursors::self()->mouse()->setPos(c->frameGeometry().center() + QPoint(1, 1)); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), c->frameGeometry().center()); // deactivate the client, this should unlock workspace()->activateClient(nullptr); @@ -328,8 +328,8 @@ void TestPointerConstraints::testLockedPointer() QVERIFY(unlockedSpy.wait()); // moving cursor should be allowed again - KWin::Cursor::setPos(c->frameGeometry().center() + QPoint(1, 1)); - QCOMPARE(KWin::Cursor::pos(), c->frameGeometry().center() + QPoint(1, 1)); + KWin::Cursors::self()->mouse()->setPos(c->frameGeometry().center() + QPoint(1, 1)); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), c->frameGeometry().center() + QPoint(1, 1)); lockedPointer.reset(Test::waylandPointerConstraints()->lockPointer(surface.data(), pointer.data(), nullptr, PointerConstraints::LifeTime::Persistent)); QSignalSpy lockedSpy2(lockedPointer.data(), &LockedPointer::locked); @@ -342,8 +342,8 @@ void TestPointerConstraints::testLockedPointer() // try to move the pointer QCOMPARE(input()->pointer()->isConstrained(), true); - KWin::Cursor::setPos(c->frameGeometry().center()); - QCOMPARE(KWin::Cursor::pos(), c->frameGeometry().center() + QPoint(1, 1)); + KWin::Cursors::self()->mouse()->setPos(c->frameGeometry().center()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), c->frameGeometry().center() + QPoint(1, 1)); // delete pointer lock lockedPointer.reset(nullptr); @@ -355,8 +355,8 @@ void TestPointerConstraints::testLockedPointer() // moving cursor should be allowed again QCOMPARE(input()->pointer()->isConstrained(), false); - KWin::Cursor::setPos(c->frameGeometry().center()); - QCOMPARE(KWin::Cursor::pos(), c->frameGeometry().center()); + KWin::Cursors::self()->mouse()->setPos(c->frameGeometry().center()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), c->frameGeometry().center()); } void TestPointerConstraints::testCloseWindowWithLockedPointer_data() @@ -382,12 +382,12 @@ void TestPointerConstraints::testCloseWindowWithLockedPointer() // now map the window auto c = Test::renderAndWaitForShown(surface.data(), QSize(100, 100), Qt::blue); QVERIFY(c); - QVERIFY(!c->frameGeometry().contains(KWin::Cursor::pos())); + QVERIFY(!c->frameGeometry().contains(KWin::Cursors::self()->mouse()->pos())); // now let's lock QCOMPARE(input()->pointer()->isConstrained(), false); - KWin::Cursor::setPos(c->frameGeometry().center()); - QCOMPARE(KWin::Cursor::pos(), c->frameGeometry().center()); + KWin::Cursors::self()->mouse()->setPos(c->frameGeometry().center()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), c->frameGeometry().center()); QCOMPARE(input()->pointer()->isConstrained(), true); QVERIFY(lockedSpy.wait()); diff --git a/autotests/integration/pointer_input.cpp b/autotests/integration/pointer_input.cpp index 36a1eee309..e81715404c 100644 --- a/autotests/integration/pointer_input.cpp +++ b/autotests/integration/pointer_input.cpp @@ -175,7 +175,7 @@ void PointerInputTest::init() m_seat = Test::waylandSeat(); screens()->setCurrent(0); - Cursor::setPos(QPoint(640, 512)); + Cursors::self()->mouse()->setPos(QPoint(640, 512)); } void PointerInputTest::cleanup() @@ -219,7 +219,7 @@ void PointerInputTest::testWarpingUpdatesFocus() QVERIFY(!pointer->enteredSurface()); // enter - Cursor::setPos(QPoint(25, 25)); + Cursors::self()->mouse()->setPos(QPoint(25, 25)); QVERIFY(enteredSpy.wait()); QCOMPARE(enteredSpy.count(), 1); QCOMPARE(enteredSpy.first().at(1).toPointF(), QPointF(25, 25)); @@ -229,7 +229,7 @@ void PointerInputTest::testWarpingUpdatesFocus() QCOMPARE(waylandServer()->seat()->focusedPointerSurface(), window->surface()); // and out again - Cursor::setPos(QPoint(250, 250));; + Cursors::self()->mouse()->setPos(QPoint(250, 250));; QVERIFY(leftSpy.wait()); QCOMPARE(leftSpy.count(), 1); // there should not be a focused pointer surface anymore @@ -268,7 +268,7 @@ void PointerInputTest::testWarpingGeneratesPointerMotion() QCOMPARE(enteredSpy.first().at(1).toPointF(), QPointF(25, 25)); // now warp - Cursor::setPos(QPoint(26, 26)); + Cursors::self()->mouse()->setPos(QPoint(26, 26)); QVERIFY(movedSpy.wait()); QCOMPARE(movedSpy.count(), 1); QCOMPARE(movedSpy.last().first().toPointF(), QPointF(26, 26)); @@ -288,7 +288,7 @@ void PointerInputTest::testWarpingDuringFilter() QVERIFY(movedSpy.isValid()); // warp cursor into expected geometry - Cursor::setPos(10, 10); + Cursors::self()->mouse()->setPos(10, 10); // create a window QSignalSpy clientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded); @@ -303,7 +303,7 @@ void PointerInputTest::testWarpingDuringFilter() QVERIFY(window); QCOMPARE(window->pos(), QPoint(0, 0)); - QVERIFY(window->frameGeometry().contains(Cursor::pos())); + QVERIFY(window->frameGeometry().contains(Cursors::self()->mouse()->pos())); // is PresentWindows effect for top left screen edge loaded QVERIFY(static_cast(effects)->isEffectLoaded("presentwindows")); @@ -311,7 +311,7 @@ void PointerInputTest::testWarpingDuringFilter() quint32 timestamp = 0; kwinApp()->platform()->pointerMotion(QPoint(0, 0), timestamp++); // screen edges push back - QCOMPARE(Cursor::pos(), QPoint(1, 1)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(1, 1)); QVERIFY(movedSpy.wait()); QCOMPARE(movedSpy.count(), 2); QCOMPARE(movedSpy.at(0).first().toPoint(), QPoint(0, 0)); @@ -324,7 +324,7 @@ void PointerInputTest::testUpdateFocusAfterScreenChange() // screen due to removal of screen using namespace KWayland::Client; // ensure cursor is on second screen - Cursor::setPos(1500, 300); + Cursors::self()->mouse()->setPos(1500, 300); // create pointer and signal spy for enter and motion auto pointer = m_seat->createPointer(m_seat); @@ -344,7 +344,7 @@ void PointerInputTest::testUpdateFocusAfterScreenChange() QVERIFY(clientAddedSpy.wait()); AbstractClient *window = workspace()->activeClient(); QVERIFY(window); - QVERIFY(!window->frameGeometry().contains(Cursor::pos())); + QVERIFY(!window->frameGeometry().contains(Cursors::self()->mouse()->pos())); QSignalSpy screensChangedSpy(screens(), &Screens::changed); QVERIFY(screensChangedSpy.isValid()); @@ -357,8 +357,8 @@ void PointerInputTest::testUpdateFocusAfterScreenChange() QCOMPARE(screens()->count(), 1); // this should have warped the cursor - QCOMPARE(Cursor::pos(), QPoint(639, 511)); - QVERIFY(window->frameGeometry().contains(Cursor::pos())); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(639, 511)); + QVERIFY(window->frameGeometry().contains(Cursors::self()->mouse()->pos())); // and we should get an enter event QTRY_COMPARE(enteredSpy.count(), 1); @@ -442,7 +442,7 @@ void PointerInputTest::testModifierClickUnrestrictedMove() QVERIFY(window); // move cursor on window - Cursor::setPos(window->frameGeometry().center()); + Cursors::self()->mouse()->setPos(window->frameGeometry().center()); // simulate modifier+click quint32 timestamp = 1; @@ -514,7 +514,7 @@ void PointerInputTest::testModifierClickUnrestrictedMoveGlobalShortcutsDisabled( QVERIFY(workspace()->globalShortcutsDisabled()); // move cursor on window - Cursor::setPos(window->frameGeometry().center()); + Cursors::self()->mouse()->setPos(window->frameGeometry().center()); // simulate modifier+click quint32 timestamp = 1; @@ -585,7 +585,7 @@ void PointerInputTest::testModifierScrollOpacity() QCOMPARE(window->opacity(), 0.5); // move cursor on window - Cursor::setPos(window->frameGeometry().center()); + Cursors::self()->mouse()->setPos(window->frameGeometry().center()); // simulate modifier+wheel quint32 timestamp = 1; @@ -644,7 +644,7 @@ void PointerInputTest::testModifierScrollOpacityGlobalShortcutsDisabled() QCOMPARE(window->opacity(), 0.5); // move cursor on window - Cursor::setPos(window->frameGeometry().center()); + Cursors::self()->mouse()->setPos(window->frameGeometry().center()); // disable global shortcuts QVERIFY(!workspace()->globalShortcutsDisabled()); @@ -700,7 +700,7 @@ void PointerInputTest::testScrollAction() QVERIFY(window1 != window2); // move cursor to the inactive window - Cursor::setPos(window1->frameGeometry().center()); + Cursors::self()->mouse()->setPos(window1->frameGeometry().center()); quint32 timestamp = 1; QVERIFY(!window1->isActive()); @@ -722,7 +722,7 @@ void PointerInputTest::testFocusFollowsMouse() QVERIFY(pointer); QVERIFY(pointer->isValid()); // move cursor out of the way of first window to be created - Cursor::setPos(900, 900); + Cursors::self()->mouse()->setPos(900, 900); // first modify the config for this run KConfigGroup group = kwinApp()->config()->group("Windows"); @@ -774,18 +774,18 @@ void PointerInputTest::testFocusFollowsMouse() // move on top of first window QVERIFY(window1->frameGeometry().contains(10, 10)); QVERIFY(!window2->frameGeometry().contains(10, 10)); - Cursor::setPos(10, 10); + Cursors::self()->mouse()->setPos(10, 10); QVERIFY(stackingOrderChangedSpy.wait()); QCOMPARE(stackingOrderChangedSpy.count(), 1); QCOMPARE(workspace()->topClientOnDesktop(1, -1), window1); QTRY_VERIFY(window1->isActive()); // move on second window, but move away before active window change delay hits - Cursor::setPos(810, 810); + Cursors::self()->mouse()->setPos(810, 810); QVERIFY(stackingOrderChangedSpy.wait()); QCOMPARE(stackingOrderChangedSpy.count(), 2); QCOMPARE(workspace()->topClientOnDesktop(1, -1), window2); - Cursor::setPos(10, 10); + Cursors::self()->mouse()->setPos(10, 10); QVERIFY(!activeWindowChangedSpy.wait(250)); QVERIFY(window1->isActive()); QCOMPARE(workspace()->topClientOnDesktop(1, -1), window1); @@ -793,8 +793,8 @@ void PointerInputTest::testFocusFollowsMouse() QCOMPARE(stackingOrderChangedSpy.count(), 3); // quickly move on window 2 and back on window 1 should not raise window 2 - Cursor::setPos(810, 810); - Cursor::setPos(10, 10); + Cursors::self()->mouse()->setPos(810, 810); + Cursors::self()->mouse()->setPos(10, 10); QVERIFY(!stackingOrderChangedSpy.wait(250)); } @@ -860,7 +860,7 @@ void PointerInputTest::testMouseActionInactiveWindow() // move on top of first window QVERIFY(window1->frameGeometry().contains(10, 10)); QVERIFY(!window2->frameGeometry().contains(10, 10)); - Cursor::setPos(10, 10); + Cursors::self()->mouse()->setPos(10, 10); // no focus follows mouse QVERIFY(!stackingOrderChangedSpy.wait(200)); QVERIFY(stackingOrderChangedSpy.isEmpty()); @@ -952,7 +952,7 @@ void PointerInputTest::testMouseActionActiveWindow() // move on top of second window QVERIFY(!window1->frameGeometry().contains(900, 900)); QVERIFY(window2->frameGeometry().contains(900, 900)); - Cursor::setPos(900, 900); + Cursors::self()->mouse()->setPos(900, 900); // and click quint32 timestamp = 1; @@ -989,10 +989,11 @@ void PointerInputTest::testCursorImage() QVERIFY(enteredSpy.isValid()); // move cursor somewhere the new window won't open - Cursor::setPos(800, 800); + auto cursor = Cursors::self()->mouse(); + cursor->setPos(800, 800); auto p = input()->pointer(); // at the moment it should be the fallback cursor - const QImage fallbackCursor = p->cursorImage(); + const QImage fallbackCursor = cursor->image(); QVERIFY(!fallbackCursor.isNull()); // create a window @@ -1008,9 +1009,9 @@ void PointerInputTest::testCursorImage() QVERIFY(window); // move cursor to center of window, this should first set a null pointer, so we still show old cursor - Cursor::setPos(window->frameGeometry().center()); + cursor->setPos(window->frameGeometry().center()); QCOMPARE(p->focus().data(), window); - QCOMPARE(p->cursorImage(), fallbackCursor); + QCOMPARE(cursor->image(), fallbackCursor); QVERIFY(enteredSpy.wait()); // create a cursor on the pointer @@ -1025,13 +1026,13 @@ void PointerInputTest::testCursorImage() cursorSurface->commit(); pointer->setCursor(cursorSurface, QPoint(5, 5)); QVERIFY(cursorRenderedSpy.wait()); - QCOMPARE(p->cursorImage(), red); - QCOMPARE(p->cursorHotSpot(), QPoint(5, 5)); + QCOMPARE(cursor->image(), red); + QCOMPARE(cursor->hotspot(), QPoint(5, 5)); // change hotspot pointer->setCursor(cursorSurface, QPoint(6, 6)); Test::flushWaylandConnection(); - QTRY_COMPARE(p->cursorHotSpot(), QPoint(6, 6)); - QCOMPARE(p->cursorImage(), red); + QTRY_COMPARE(cursor->hotspot(), QPoint(6, 6)); + QCOMPARE(cursor->image(), red); // change the buffer QImage blue = QImage(QSize(10, 10), QImage::Format_ARGB32_Premultiplied); @@ -1041,8 +1042,8 @@ void PointerInputTest::testCursorImage() cursorSurface->damage(QRect(0, 0, 10, 10)); cursorSurface->commit(); QVERIFY(cursorRenderedSpy.wait()); - QTRY_COMPARE(p->cursorImage(), blue); - QCOMPARE(p->cursorHotSpot(), QPoint(6, 6)); + QTRY_COMPARE(cursor->image(), blue); + QCOMPARE(cursor->hotspot(), QPoint(6, 6)); // scaled cursor QImage blueScaled = QImage(QSize(20, 20), QImage::Format_ARGB32_Premultiplied); @@ -1054,19 +1055,19 @@ void PointerInputTest::testCursorImage() cursorSurface->damage(QRect(0, 0, 20, 20)); cursorSurface->commit(); QVERIFY(cursorRenderedSpy.wait()); - QTRY_COMPARE(p->cursorImage(), blueScaled); - QCOMPARE(p->cursorHotSpot(), QPoint(6, 6)); //surface-local (so not changed) + QTRY_COMPARE(cursor->image(), blueScaled); + QCOMPARE(cursor->hotspot(), QPoint(6, 6)); //surface-local (so not changed) // hide the cursor pointer->setCursor(nullptr); Test::flushWaylandConnection(); - QTRY_VERIFY(p->cursorImage().isNull()); + QTRY_VERIFY(cursor->image().isNull()); // move cursor somewhere else, should reset to fallback cursor - Cursor::setPos(window->frameGeometry().bottomLeft() + QPoint(20, 20)); + Cursors::self()->mouse()->setPos(window->frameGeometry().bottomLeft() + QPoint(20, 20)); QVERIFY(p->focus().isNull()); - QVERIFY(!p->cursorImage().isNull()); - QCOMPARE(p->cursorImage(), fallbackCursor); + QVERIFY(!cursor->image().isNull()); + QCOMPARE(cursor->image(), fallbackCursor); } class HelperEffect : public Effect @@ -1083,6 +1084,7 @@ void PointerInputTest::testEffectOverrideCursorImage() using namespace KWayland::Client; // we need a pointer to get the enter event and set a cursor auto pointer = m_seat->createPointer(m_seat); + auto cursor = Cursors::self()->mouse(); QVERIFY(pointer); QVERIFY(pointer->isValid()); QSignalSpy enteredSpy(pointer, &Pointer::entered); @@ -1090,10 +1092,9 @@ void PointerInputTest::testEffectOverrideCursorImage() QSignalSpy leftSpy(pointer, &Pointer::left); QVERIFY(leftSpy.isValid()); // move cursor somewhere the new window won't open - Cursor::setPos(800, 800); - auto p = input()->pointer(); + cursor->setPos(800, 800); // here we should have the fallback cursor - const QImage fallback = p->cursorImage(); + const QImage fallback = cursor->image(); QVERIFY(!fallback.isNull()); // now let's create a window @@ -1110,46 +1111,46 @@ void PointerInputTest::testEffectOverrideCursorImage() // and move cursor to the window QVERIFY(!window->frameGeometry().contains(QPoint(800, 800))); - Cursor::setPos(window->frameGeometry().center()); + cursor->setPos(window->frameGeometry().center()); QVERIFY(enteredSpy.wait()); // cursor image should still be fallback - QCOMPARE(p->cursorImage(), fallback); + QCOMPARE(cursor->image(), fallback); // now create an effect and set an override cursor QScopedPointer effect(new HelperEffect); effects->startMouseInterception(effect.data(), Qt::SizeAllCursor); - const QImage sizeAll = p->cursorImage(); + const QImage sizeAll = cursor->image(); QVERIFY(!sizeAll.isNull()); QVERIFY(sizeAll != fallback); QVERIFY(leftSpy.wait()); // let's change to arrow cursor, this should be our fallback effects->defineCursor(Qt::ArrowCursor); - QCOMPARE(p->cursorImage(), fallback); + QCOMPARE(cursor->image(), fallback); // back to size all effects->defineCursor(Qt::SizeAllCursor); - QCOMPARE(p->cursorImage(), sizeAll); + QCOMPARE(cursor->image(), sizeAll); // move cursor outside the window area - Cursor::setPos(800, 800); + Cursors::self()->mouse()->setPos(800, 800); // and end the override, which should switch to fallback effects->stopMouseInterception(effect.data()); - QCOMPARE(p->cursorImage(), fallback); + QCOMPARE(cursor->image(), fallback); // start mouse interception again effects->startMouseInterception(effect.data(), Qt::SizeAllCursor); - QCOMPARE(p->cursorImage(), sizeAll); + QCOMPARE(cursor->image(), sizeAll); // move cursor to area of window - Cursor::setPos(window->frameGeometry().center()); + Cursors::self()->mouse()->setPos(window->frameGeometry().center()); // this should not result in an enter event QVERIFY(!enteredSpy.wait(100)); // after ending the interception we should get an enter event effects->stopMouseInterception(effect.data()); QVERIFY(enteredSpy.wait()); - QVERIFY(p->cursorImage().isNull()); + QVERIFY(cursor->image().isNull()); } void PointerInputTest::testPopup() @@ -1171,7 +1172,7 @@ void PointerInputTest::testPopup() QSignalSpy motionSpy(pointer, &Pointer::motion); QVERIFY(motionSpy.isValid()); - Cursor::setPos(800, 800); + Cursors::self()->mouse()->setPos(800, 800); QSignalSpy clientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded); QVERIFY(clientAddedSpy.isValid()); @@ -1186,7 +1187,7 @@ void PointerInputTest::testPopup() QCOMPARE(window->hasPopupGrab(), false); // move pointer into window QVERIFY(!window->frameGeometry().contains(QPoint(800, 800))); - Cursor::setPos(window->frameGeometry().center()); + Cursors::self()->mouse()->setPos(window->frameGeometry().center()); QVERIFY(enteredSpy.wait()); // click inside window to create serial quint32 timestamp = 0; @@ -1216,7 +1217,7 @@ void PointerInputTest::testPopup() QCOMPARE(popupClient->hasPopupGrab(), true); // let's move the pointer into the center of the window - Cursor::setPos(popupClient->frameGeometry().center()); + Cursors::self()->mouse()->setPos(popupClient->frameGeometry().center()); QVERIFY(enteredSpy.wait()); QCOMPARE(enteredSpy.count(), 2); QCOMPARE(leftSpy.count(), 1); @@ -1224,7 +1225,7 @@ void PointerInputTest::testPopup() // let's move the pointer outside of the popup window // this should not really change anything, it gets a leave event - Cursor::setPos(popupClient->frameGeometry().bottomRight() + QPoint(2, 2)); + Cursors::self()->mouse()->setPos(popupClient->frameGeometry().bottomRight() + QPoint(2, 2)); QVERIFY(leftSpy.wait()); QCOMPARE(leftSpy.count(), 2); QVERIFY(popupDoneSpy.isEmpty()); @@ -1253,7 +1254,7 @@ void PointerInputTest::testDecoCancelsPopup() QSignalSpy motionSpy(pointer, &Pointer::motion); QVERIFY(motionSpy.isValid()); - Cursor::setPos(800, 800); + Cursors::self()->mouse()->setPos(800, 800); QSignalSpy clientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded); QVERIFY(clientAddedSpy.isValid()); Surface *surface = Test::createSurface(m_compositor); @@ -1277,7 +1278,7 @@ void PointerInputTest::testDecoCancelsPopup() // move pointer into window QVERIFY(!window->frameGeometry().contains(QPoint(800, 800))); - Cursor::setPos(window->frameGeometry().center()); + Cursors::self()->mouse()->setPos(window->frameGeometry().center()); QVERIFY(enteredSpy.wait()); // click inside window to create serial quint32 timestamp = 0; @@ -1307,7 +1308,7 @@ void PointerInputTest::testDecoCancelsPopup() QCOMPARE(popupClient->hasPopupGrab(), true); // let's move the pointer into the center of the deco - Cursor::setPos(window->frameGeometry().center().x(), window->y() + (window->height() - window->clientSize().height()) / 2); + Cursors::self()->mouse()->setPos(window->frameGeometry().center().x(), window->y() + (window->height() - window->clientSize().height()) / 2); kwinApp()->platform()->pointerButtonPressed(BTN_RIGHT, timestamp++); QVERIFY(popupDoneSpy.wait()); @@ -1330,7 +1331,7 @@ void PointerInputTest::testWindowUnderCursorWhileButtonPressed() QSignalSpy leftSpy(pointer, &Pointer::left); QVERIFY(leftSpy.isValid()); - Cursor::setPos(800, 800); + Cursors::self()->mouse()->setPos(800, 800); QSignalSpy clientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded); QVERIFY(clientAddedSpy.isValid()); Surface *surface = Test::createSurface(m_compositor); @@ -1344,7 +1345,7 @@ void PointerInputTest::testWindowUnderCursorWhileButtonPressed() // move cursor over window QVERIFY(!window->frameGeometry().contains(QPoint(800, 800))); - Cursor::setPos(window->frameGeometry().center()); + Cursors::self()->mouse()->setPos(window->frameGeometry().center()); QVERIFY(enteredSpy.wait()); // click inside window quint32 timestamp = 0; @@ -1363,8 +1364,8 @@ void PointerInputTest::testWindowUnderCursorWhileButtonPressed() auto popupClient = clientAddedSpy.last().first().value(); QVERIFY(popupClient); QVERIFY(popupClient != window); - QVERIFY(window->frameGeometry().contains(Cursor::pos())); - QVERIFY(popupClient->frameGeometry().contains(Cursor::pos())); + QVERIFY(window->frameGeometry().contains(Cursors::self()->mouse()->pos())); + QVERIFY(popupClient->frameGeometry().contains(Cursors::self()->mouse()->pos())); QVERIFY(!leftSpy.wait()); kwinApp()->platform()->pointerButtonReleased(BTN_LEFT, timestamp++); @@ -1454,15 +1455,15 @@ void PointerInputTest::testConfineToScreenGeometry() // move pointer to initial position QFETCH(QPoint, startPos); - Cursor::setPos(startPos); - QCOMPARE(Cursor::pos(), startPos); + Cursors::self()->mouse()->setPos(startPos); + QCOMPARE(Cursors::self()->mouse()->pos(), startPos); // perform movement QFETCH(QPoint, targetPos); kwinApp()->platform()->pointerMotion(targetPos, 1); QFETCH(QPoint, expectedPos); - QCOMPARE(Cursor::pos(), expectedPos); + QCOMPARE(Cursors::self()->mouse()->pos(), expectedPos); } void PointerInputTest::testResizeCursor_data() @@ -1522,7 +1523,7 @@ void PointerInputTest::testResizeCursor() cursorPos.setY(c->frameGeometry().center().y()); } - Cursor::setPos(cursorPos); + Cursors::self()->mouse()->setPos(cursorPos); const PlatformCursorImage arrowCursor = loadReferenceThemeCursor(Qt::ArrowCursor); QVERIFY(!arrowCursor.image().isNull()); @@ -1573,7 +1574,7 @@ void PointerInputTest::testMoveCursor() QVERIFY(c); // move cursor to the test position - Cursor::setPos(c->frameGeometry().center()); + Cursors::self()->mouse()->setPos(c->frameGeometry().center()); const PlatformCursorImage arrowCursor = loadReferenceThemeCursor(Qt::ArrowCursor); QVERIFY(!arrowCursor.image().isNull()); diff --git a/autotests/integration/quick_tiling_test.cpp b/autotests/integration/quick_tiling_test.cpp index 750d1dcfa7..7f48634e39 100644 --- a/autotests/integration/quick_tiling_test.cpp +++ b/autotests/integration/quick_tiling_test.cpp @@ -364,31 +364,31 @@ void QuickTilingTest::testQuickTilingKeyboardMove() workspace()->performWindowOperation(c, Options::UnrestrictedMoveOp); QCOMPARE(c, workspace()->moveResizeClient()); - QCOMPARE(Cursor::pos(), QPoint(49, 24)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(49, 24)); QFETCH(QPoint, targetPos); quint32 timestamp = 1; kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTCTRL, timestamp++); - while (Cursor::pos().x() > targetPos.x()) { + while (Cursors::self()->mouse()->pos().x() > targetPos.x()) { kwinApp()->platform()->keyboardKeyPressed(KEY_LEFT, timestamp++); kwinApp()->platform()->keyboardKeyReleased(KEY_LEFT, timestamp++); } - while (Cursor::pos().x() < targetPos.x()) { + while (Cursors::self()->mouse()->pos().x() < targetPos.x()) { kwinApp()->platform()->keyboardKeyPressed(KEY_RIGHT, timestamp++); kwinApp()->platform()->keyboardKeyReleased(KEY_RIGHT, timestamp++); } - while (Cursor::pos().y() < targetPos.y()) { + while (Cursors::self()->mouse()->pos().y() < targetPos.y()) { kwinApp()->platform()->keyboardKeyPressed(KEY_DOWN, timestamp++); kwinApp()->platform()->keyboardKeyReleased(KEY_DOWN, timestamp++); } - while (Cursor::pos().y() > targetPos.y()) { + while (Cursors::self()->mouse()->pos().y() > targetPos.y()) { kwinApp()->platform()->keyboardKeyPressed(KEY_UP, timestamp++); kwinApp()->platform()->keyboardKeyReleased(KEY_UP, timestamp++); } kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTCTRL, timestamp++); kwinApp()->platform()->keyboardKeyPressed(KEY_ENTER, timestamp++); kwinApp()->platform()->keyboardKeyReleased(KEY_ENTER, timestamp++); - QCOMPARE(Cursor::pos(), targetPos); + QCOMPARE(Cursors::self()->mouse()->pos(), targetPos); QVERIFY(!workspace()->moveResizeClient()); QCOMPARE(quickTileChangedSpy.count(), 1); @@ -445,7 +445,7 @@ void QuickTilingTest::testQuickTilingPointerMove() workspace()->performWindowOperation(c, Options::UnrestrictedMoveOp); QCOMPARE(c, workspace()->moveResizeClient()); - QCOMPARE(Cursor::pos(), QPoint(49, 24)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(49, 24)); QVERIFY(configureRequestedSpy.wait()); QCOMPARE(configureRequestedSpy.count(), 3); @@ -454,7 +454,7 @@ void QuickTilingTest::testQuickTilingPointerMove() kwinApp()->platform()->pointerMotion(targetPos, timestamp++); kwinApp()->platform()->pointerButtonPressed(BTN_LEFT, timestamp++); kwinApp()->platform()->pointerButtonReleased(BTN_LEFT, timestamp++); - QCOMPARE(Cursor::pos(), targetPos); + QCOMPARE(Cursors::self()->mouse()->pos(), targetPos); QVERIFY(!workspace()->moveResizeClient()); QCOMPARE(quickTileChangedSpy.count(), 1); diff --git a/autotests/integration/scene_qpainter_test.cpp b/autotests/integration/scene_qpainter_test.cpp index f04d15c7ff..cdbd61b70d 100644 --- a/autotests/integration/scene_qpainter_test.cpp +++ b/autotests/integration/scene_qpainter_test.cpp @@ -113,9 +113,11 @@ void SceneQPainterTest::testStartFrame() QImage referenceImage(QSize(1280, 1024), QImage::Format_RGB32); referenceImage.fill(Qt::black); QPainter p(&referenceImage); - const QImage cursorImage = kwinApp()->platform()->softwareCursor(); + + auto cursor = KWin::Cursors::self()->mouse(); + const QImage cursorImage = cursor->image(); QVERIFY(!cursorImage.isNull()); - p.drawImage(KWin::Cursor::pos() - kwinApp()->platform()->softwareCursorHotspot(), cursorImage); + p.drawImage(cursor->pos() - cursor->hotspot(), cursorImage); QCOMPARE(referenceImage, *scene->qpainterRenderBuffer()); } @@ -126,25 +128,27 @@ void SceneQPainterTest::testCursorMoving() QVERIFY(scene); QSignalSpy frameRenderedSpy(scene, &Scene::frameRendered); QVERIFY(frameRenderedSpy.isValid()); - KWin::Cursor::setPos(0, 0); + KWin::Cursors::self()->mouse()->setPos(0, 0); QVERIFY(frameRenderedSpy.wait()); - KWin::Cursor::setPos(10, 0); + KWin::Cursors::self()->mouse()->setPos(10, 0); QVERIFY(frameRenderedSpy.wait()); - KWin::Cursor::setPos(10, 12); + KWin::Cursors::self()->mouse()->setPos(10, 12); QVERIFY(frameRenderedSpy.wait()); - KWin::Cursor::setPos(12, 14); + KWin::Cursors::self()->mouse()->setPos(12, 14); QVERIFY(frameRenderedSpy.wait()); - KWin::Cursor::setPos(50, 60); + KWin::Cursors::self()->mouse()->setPos(50, 60); QVERIFY(frameRenderedSpy.wait()); - KWin::Cursor::setPos(45, 45); + KWin::Cursors::self()->mouse()->setPos(45, 45); QVERIFY(frameRenderedSpy.wait()); // now let's render a reference image for comparison QImage referenceImage(QSize(1280, 1024), QImage::Format_RGB32); referenceImage.fill(Qt::black); QPainter p(&referenceImage); - const QImage cursorImage = kwinApp()->platform()->softwareCursor(); + + auto cursor = Cursors::self()->currentCursor(); + const QImage cursorImage = cursor->image(); QVERIFY(!cursorImage.isNull()); - p.drawImage(QPoint(45, 45) - kwinApp()->platform()->softwareCursorHotspot(), cursorImage); + p.drawImage(QPoint(45, 45) - cursor->hotspot(), cursorImage); QCOMPARE(referenceImage, *scene->qpainterRenderBuffer()); } @@ -157,7 +161,7 @@ void SceneQPainterTest::testWindow_data() void SceneQPainterTest::testWindow() { - KWin::Cursor::setPos(45, 45); + KWin::Cursors::self()->mouse()->setPos(45, 45); // this test verifies that a window is rendered correctly using namespace KWayland::Client; QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Seat)); @@ -190,10 +194,10 @@ void SceneQPainterTest::testWindow() Test::render(cs.data(), QSize(10, 10), Qt::red); p->setCursor(cs.data(), QPoint(5, 5)); QVERIFY(frameRenderedSpy.wait()); - painter.fillRect(KWin::Cursor::pos().x() - 5, KWin::Cursor::pos().y() - 5, 10, 10, Qt::red); + painter.fillRect(KWin::Cursors::self()->mouse()->pos().x() - 5, KWin::Cursors::self()->mouse()->pos().y() - 5, 10, 10, Qt::red); QCOMPARE(referenceImage, *scene->qpainterRenderBuffer()); // let's move the cursor again - KWin::Cursor::setPos(10, 10); + KWin::Cursors::self()->mouse()->setPos(10, 10); QVERIFY(frameRenderedSpy.wait()); painter.fillRect(0, 0, 200, 300, Qt::blue); painter.fillRect(5, 5, 10, 10, Qt::red); @@ -202,7 +206,7 @@ void SceneQPainterTest::testWindow() void SceneQPainterTest::testWindowScaled() { - KWin::Cursor::setPos(10, 10); + KWin::Cursors::self()->mouse()->setPos(10, 10); // this test verifies that a window is rendered correctly using namespace KWayland::Client; QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Seat)); @@ -260,7 +264,7 @@ void SceneQPainterTest::testCompositorRestart_data() void SceneQPainterTest::testCompositorRestart() { // this test verifies that the compositor/SceneQPainter survive a restart of the compositor and still render correctly - KWin::Cursor::setPos(400, 400); + KWin::Cursors::self()->mouse()->setPos(400, 400); // first create a window using namespace KWayland::Client; @@ -294,9 +298,11 @@ void SceneQPainterTest::testCompositorRestart() referenceImage.fill(Qt::black); QPainter painter(&referenceImage); painter.fillRect(0, 0, 200, 300, Qt::blue); - const QImage cursorImage = kwinApp()->platform()->softwareCursor(); + + auto cursor = Cursors::self()->mouse(); + const QImage cursorImage = cursor->image(); QVERIFY(!cursorImage.isNull()); - painter.drawImage(QPoint(400, 400) - kwinApp()->platform()->softwareCursorHotspot(), cursorImage); + painter.drawImage(QPoint(400, 400) - cursor->hotspot(), cursorImage); QCOMPARE(referenceImage, *scene->qpainterRenderBuffer()); } diff --git a/autotests/integration/screen_changes_test.cpp b/autotests/integration/screen_changes_test.cpp index 0a691124ef..e06afa1634 100644 --- a/autotests/integration/screen_changes_test.cpp +++ b/autotests/integration/screen_changes_test.cpp @@ -61,7 +61,7 @@ void ScreenChangesTest::init() QVERIFY(Test::setupWaylandConnection()); screens()->setCurrent(0); - KWin::Cursor::setPos(QPoint(640, 512)); + KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); } void ScreenChangesTest::cleanup() diff --git a/autotests/integration/screenedge_client_show_test.cpp b/autotests/integration/screenedge_client_show_test.cpp index 1aecfec8e3..cb9f68d7a0 100644 --- a/autotests/integration/screenedge_client_show_test.cpp +++ b/autotests/integration/screenedge_client_show_test.cpp @@ -78,7 +78,7 @@ void ScreenEdgeClientShowTest::initTestCase() void ScreenEdgeClientShowTest::init() { screens()->setCurrent(0); - Cursor::setPos(QPoint(640, 512)); + Cursors::self()->mouse()->setPos(QPoint(640, 512)); QVERIFY(waylandServer()->clients().isEmpty()); } @@ -166,7 +166,7 @@ void ScreenEdgeClientShowTest::testScreenEdgeShowHideX11() QSignalSpy effectsWindowShownSpy(effects, &EffectsHandler::windowShown); QVERIFY(effectsWindowShownSpy.isValid()); QFETCH(QPoint, triggerPos); - Cursor::setPos(triggerPos); + Cursors::self()->mouse()->setPos(triggerPos); QVERIFY(!client->isHiddenInternal()); QCOMPARE(effectsWindowShownSpy.count(), 1); @@ -174,7 +174,7 @@ void ScreenEdgeClientShowTest::testScreenEdgeShowHideX11() QTest::qWait(1); //hide window again - Cursor::setPos(QPoint(640, 512)); + Cursors::self()->mouse()->setPos(QPoint(640, 512)); xcb_change_property(c.data(), XCB_PROP_MODE_REPLACE, w, atom, XCB_ATOM_CARDINAL, 32, 1, &location); xcb_flush(c.data()); QVERIFY(clientHiddenSpy.wait()); @@ -183,7 +183,7 @@ void ScreenEdgeClientShowTest::testScreenEdgeShowHideX11() //resizewhile hidden client->setFrameGeometry(resizedWindowGeometry); //triggerPos shouldn't be valid anymore - Cursor::setPos(triggerPos); + Cursors::self()->mouse()->setPos(triggerPos); QVERIFY(client->isHiddenInternal()); // destroy window again diff --git a/autotests/integration/scripting/screenedge_test.cpp b/autotests/integration/scripting/screenedge_test.cpp index 1d85474013..b06459758c 100644 --- a/autotests/integration/scripting/screenedge_test.cpp +++ b/autotests/integration/scripting/screenedge_test.cpp @@ -92,7 +92,7 @@ void ScreenEdgeTest::initTestCase() void ScreenEdgeTest::init() { - KWin::Cursor::setPos(640, 512); + KWin::Cursors::self()->mouse()->setPos(640, 512); if (workspace()->showingDesktop()) { workspace()->slotToggleShowDesktop(); } @@ -160,7 +160,7 @@ void ScreenEdgeTest::testEdge() // trigger the edge QFETCH(QPoint, triggerPos); - KWin::Cursor::setPos(triggerPos); + KWin::Cursors::self()->mouse()->setPos(triggerPos); QCOMPARE(showDesktopSpy.count(), 1); QVERIFY(workspace()->showingDesktop()); } @@ -243,27 +243,27 @@ void ScreenEdgeTest::testEdgeUnregister() QVERIFY(showDesktopSpy.isValid()); //trigger the edge - KWin::Cursor::setPos(triggerPos); + KWin::Cursors::self()->mouse()->setPos(triggerPos); QCOMPARE(showDesktopSpy.count(), 1); //reset - KWin::Cursor::setPos(500,500); + KWin::Cursors::self()->mouse()->setPos(500,500); workspace()->slotToggleShowDesktop(); showDesktopSpy.clear(); //trigger again, to show that retriggering works - KWin::Cursor::setPos(triggerPos); + KWin::Cursors::self()->mouse()->setPos(triggerPos); QCOMPARE(showDesktopSpy.count(), 1); //reset - KWin::Cursor::setPos(500,500); + KWin::Cursors::self()->mouse()->setPos(500,500); workspace()->slotToggleShowDesktop(); showDesktopSpy.clear(); //make the script unregister the edge configGroup.writeEntry("mode", "unregister"); triggerConfigReload(); - KWin::Cursor::setPos(triggerPos); + KWin::Cursors::self()->mouse()->setPos(triggerPos); QCOMPARE(showDesktopSpy.count(), 0); //not triggered //force the script to unregister a non-registered edge to prove it doesn't explode diff --git a/autotests/integration/shade_test.cpp b/autotests/integration/shade_test.cpp index 556eae2345..8491502096 100644 --- a/autotests/integration/shade_test.cpp +++ b/autotests/integration/shade_test.cpp @@ -67,7 +67,7 @@ void ShadeTest::initTestCase() void ShadeTest::init() { screens()->setCurrent(0); - Cursor::setPos(QPoint(640, 512)); + Cursors::self()->mouse()->setPos(QPoint(640, 512)); } void ShadeTest::testShadeGeometry() diff --git a/autotests/integration/struts_test.cpp b/autotests/integration/struts_test.cpp index 5ef2ad5afb..3a9e26faf4 100644 --- a/autotests/integration/struts_test.cpp +++ b/autotests/integration/struts_test.cpp @@ -98,7 +98,7 @@ void StrutsTest::init() m_plasmaShell = Test::waylandPlasmaShell(); screens()->setCurrent(0); - Cursor::setPos(QPoint(640, 512)); + Cursors::self()->mouse()->setPos(QPoint(640, 512)); QVERIFY(waylandServer()->clients().isEmpty()); } @@ -944,7 +944,7 @@ void StrutsTest::testWindowMoveWithPanelBetweenScreens() QCOMPARE(client2->pos(), QPoint(1500, 400)); const QRect origGeo = client2->frameGeometry(); - Cursor::setPos(origGeo.center()); + Cursors::self()->mouse()->setPos(origGeo.center()); workspace()->performWindowOperation(client2, Options::MoveOp); QTRY_COMPARE(workspace()->moveResizeClient(), client2); QVERIFY(client2->isMove()); diff --git a/autotests/integration/tabbox_test.cpp b/autotests/integration/tabbox_test.cpp index 9a84b93f52..651c193986 100644 --- a/autotests/integration/tabbox_test.cpp +++ b/autotests/integration/tabbox_test.cpp @@ -73,7 +73,7 @@ void TabBoxTest::init() { QVERIFY(Test::setupWaylandConnection()); screens()->setCurrent(0); - KWin::Cursor::setPos(QPoint(640, 512)); + KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); } void TabBoxTest::cleanup() diff --git a/autotests/integration/touch_input_test.cpp b/autotests/integration/touch_input_test.cpp index f494b3fbac..a220515596 100644 --- a/autotests/integration/touch_input_test.cpp +++ b/autotests/integration/touch_input_test.cpp @@ -82,7 +82,7 @@ void TouchInputTest::init() QVERIFY(m_touch->isValid()); screens()->setCurrent(0); - Cursor::setPos(QPoint(1280, 512)); + Cursors::self()->mouse()->setPos(QPoint(1280, 512)); } void TouchInputTest::cleanup() diff --git a/autotests/integration/transient_placement.cpp b/autotests/integration/transient_placement.cpp index 49578bec21..3c0f4b3fcf 100644 --- a/autotests/integration/transient_placement.cpp +++ b/autotests/integration/transient_placement.cpp @@ -83,7 +83,7 @@ void TransientPlacementTest::init() QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Decoration | Test::AdditionalWaylandInterface::PlasmaShell)); screens()->setCurrent(0); - Cursor::setPos(QPoint(640, 512)); + Cursors::self()->mouse()->setPos(QPoint(640, 512)); } void TransientPlacementTest::cleanup() diff --git a/autotests/integration/window_rules_test.cpp b/autotests/integration/window_rules_test.cpp index ec9720d098..3127a43b0a 100644 --- a/autotests/integration/window_rules_test.cpp +++ b/autotests/integration/window_rules_test.cpp @@ -71,7 +71,7 @@ void WindowRuleTest::initTestCase() void WindowRuleTest::init() { screens()->setCurrent(0); - Cursor::setPos(QPoint(640, 512)); + Cursors::self()->mouse()->setPos(QPoint(640, 512)); QVERIFY(waylandServer()->clients().isEmpty()); } diff --git a/autotests/integration/window_selection_test.cpp b/autotests/integration/window_selection_test.cpp index 9429b5dc2c..a818e57672 100644 --- a/autotests/integration/window_selection_test.cpp +++ b/autotests/integration/window_selection_test.cpp @@ -85,7 +85,7 @@ void TestWindowSelection::init() QVERIFY(Test::waitForWaylandPointer()); screens()->setCurrent(0); - KWin::Cursor::setPos(QPoint(1280, 512)); + KWin::Cursors::self()->mouse()->setPos(QPoint(1280, 512)); } void TestWindowSelection::cleanup() @@ -112,7 +112,7 @@ void TestWindowSelection::testSelectOnWindowPointer() auto client = Test::renderAndWaitForShown(surface.data(), QSize(100, 50), Qt::blue); QVERIFY(client); QVERIFY(keyboardEnteredSpy.wait()); - KWin::Cursor::setPos(client->frameGeometry().center()); + KWin::Cursors::self()->mouse()->setPos(client->frameGeometry().center()); QCOMPARE(input()->pointer()->focus().data(), client); QVERIFY(pointerEnteredSpy.wait()); @@ -198,7 +198,7 @@ void TestWindowSelection::testSelectOnWindowKeyboard() auto client = Test::renderAndWaitForShown(surface.data(), QSize(100, 50), Qt::blue); QVERIFY(client); QVERIFY(keyboardEnteredSpy.wait()); - QVERIFY(!client->frameGeometry().contains(KWin::Cursor::pos())); + QVERIFY(!client->frameGeometry().contains(KWin::Cursors::self()->mouse()->pos())); Toplevel *selectedWindow = nullptr; auto callback = [&selectedWindow] (Toplevel *t) { @@ -222,16 +222,16 @@ void TestWindowSelection::testSelectOnWindowKeyboard() kwinApp()->platform()->keyboardKeyPressed(key, timestamp++); kwinApp()->platform()->keyboardKeyReleased(key, timestamp++); }; - while (KWin::Cursor::pos().x() >= client->frameGeometry().x() + client->frameGeometry().width()) { + while (KWin::Cursors::self()->mouse()->pos().x() >= client->frameGeometry().x() + client->frameGeometry().width()) { keyPress(KEY_LEFT); } - while (KWin::Cursor::pos().x() <= client->frameGeometry().x()) { + while (KWin::Cursors::self()->mouse()->pos().x() <= client->frameGeometry().x()) { keyPress(KEY_RIGHT); } - while (KWin::Cursor::pos().y() <= client->frameGeometry().y()) { + while (KWin::Cursors::self()->mouse()->pos().y() <= client->frameGeometry().y()) { keyPress(KEY_DOWN); } - while (KWin::Cursor::pos().y() >= client->frameGeometry().y() + client->frameGeometry().height()) { + while (KWin::Cursors::self()->mouse()->pos().y() >= client->frameGeometry().y() + client->frameGeometry().height()) { keyPress(KEY_UP); } QFETCH(qint32, key); @@ -333,7 +333,7 @@ void TestWindowSelection::testCancelOnWindowPointer() auto client = Test::renderAndWaitForShown(surface.data(), QSize(100, 50), Qt::blue); QVERIFY(client); QVERIFY(keyboardEnteredSpy.wait()); - KWin::Cursor::setPos(client->frameGeometry().center()); + KWin::Cursors::self()->mouse()->setPos(client->frameGeometry().center()); QCOMPARE(input()->pointer()->focus().data(), client); QVERIFY(pointerEnteredSpy.wait()); @@ -392,7 +392,7 @@ void TestWindowSelection::testCancelOnWindowKeyboard() auto client = Test::renderAndWaitForShown(surface.data(), QSize(100, 50), Qt::blue); QVERIFY(client); QVERIFY(keyboardEnteredSpy.wait()); - KWin::Cursor::setPos(client->frameGeometry().center()); + KWin::Cursors::self()->mouse()->setPos(client->frameGeometry().center()); QCOMPARE(input()->pointer()->focus().data(), client); QVERIFY(pointerEnteredSpy.wait()); @@ -451,7 +451,7 @@ void TestWindowSelection::testSelectPointPointer() auto client = Test::renderAndWaitForShown(surface.data(), QSize(100, 50), Qt::blue); QVERIFY(client); QVERIFY(keyboardEnteredSpy.wait()); - KWin::Cursor::setPos(client->frameGeometry().center()); + KWin::Cursors::self()->mouse()->setPos(client->frameGeometry().center()); QCOMPARE(input()->pointer()->focus().data(), client); QVERIFY(pointerEnteredSpy.wait()); diff --git a/autotests/integration/x11_client_test.cpp b/autotests/integration/x11_client_test.cpp index cee372e7ba..6eac215b8f 100644 --- a/autotests/integration/x11_client_test.cpp +++ b/autotests/integration/x11_client_test.cpp @@ -142,46 +142,46 @@ void X11ClientTest::testMinimumSize() QCOMPARE(clientStartMoveResizedSpy.count(), 1); QVERIFY(client->isResize()); - const QPoint cursorPos = KWin::Cursor::pos(); + const QPoint cursorPos = KWin::Cursors::self()->mouse()->pos(); client->keyPressEvent(Qt::Key_Left); - client->updateMoveResize(KWin::Cursor::pos()); - QCOMPARE(KWin::Cursor::pos(), cursorPos + QPoint(-8, 0)); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), cursorPos + QPoint(-8, 0)); QVERIFY(!clientStepUserMovedResizedSpy.wait(1000)); QCOMPARE(clientStepUserMovedResizedSpy.count(), 0); QCOMPARE(client->clientSize().width(), 100); client->keyPressEvent(Qt::Key_Right); - client->updateMoveResize(KWin::Cursor::pos()); - QCOMPARE(KWin::Cursor::pos(), cursorPos); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), cursorPos); QVERIFY(!clientStepUserMovedResizedSpy.wait(1000)); QCOMPARE(clientStepUserMovedResizedSpy.count(), 0); QCOMPARE(client->clientSize().width(), 100); client->keyPressEvent(Qt::Key_Right); - client->updateMoveResize(KWin::Cursor::pos()); - QCOMPARE(KWin::Cursor::pos(), cursorPos + QPoint(8, 0)); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), cursorPos + QPoint(8, 0)); QVERIFY(clientStepUserMovedResizedSpy.wait()); QCOMPARE(clientStepUserMovedResizedSpy.count(), 1); QCOMPARE(client->clientSize().width(), 108); client->keyPressEvent(Qt::Key_Up); - client->updateMoveResize(KWin::Cursor::pos()); - QCOMPARE(KWin::Cursor::pos(), cursorPos + QPoint(8, -8)); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), cursorPos + QPoint(8, -8)); QVERIFY(!clientStepUserMovedResizedSpy.wait(1000)); QCOMPARE(clientStepUserMovedResizedSpy.count(), 1); QCOMPARE(client->clientSize().height(), 200); client->keyPressEvent(Qt::Key_Down); - client->updateMoveResize(KWin::Cursor::pos()); - QCOMPARE(KWin::Cursor::pos(), cursorPos + QPoint(8, 0)); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), cursorPos + QPoint(8, 0)); QVERIFY(!clientStepUserMovedResizedSpy.wait(1000)); QCOMPARE(clientStepUserMovedResizedSpy.count(), 1); QCOMPARE(client->clientSize().height(), 200); client->keyPressEvent(Qt::Key_Down); - client->updateMoveResize(KWin::Cursor::pos()); - QCOMPARE(KWin::Cursor::pos(), cursorPos + QPoint(8, 8)); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), cursorPos + QPoint(8, 8)); QVERIFY(clientStepUserMovedResizedSpy.wait()); QCOMPARE(clientStepUserMovedResizedSpy.count(), 2); QCOMPARE(client->clientSize().height(), 208); @@ -249,46 +249,46 @@ void X11ClientTest::testMaximumSize() QCOMPARE(clientStartMoveResizedSpy.count(), 1); QVERIFY(client->isResize()); - const QPoint cursorPos = KWin::Cursor::pos(); + const QPoint cursorPos = KWin::Cursors::self()->mouse()->pos(); client->keyPressEvent(Qt::Key_Right); - client->updateMoveResize(KWin::Cursor::pos()); - QCOMPARE(KWin::Cursor::pos(), cursorPos + QPoint(8, 0)); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), cursorPos + QPoint(8, 0)); QVERIFY(!clientStepUserMovedResizedSpy.wait(1000)); QCOMPARE(clientStepUserMovedResizedSpy.count(), 0); QCOMPARE(client->clientSize().width(), 100); client->keyPressEvent(Qt::Key_Left); - client->updateMoveResize(KWin::Cursor::pos()); - QCOMPARE(KWin::Cursor::pos(), cursorPos); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), cursorPos); QVERIFY(!clientStepUserMovedResizedSpy.wait(1000)); QCOMPARE(clientStepUserMovedResizedSpy.count(), 0); QCOMPARE(client->clientSize().width(), 100); client->keyPressEvent(Qt::Key_Left); - client->updateMoveResize(KWin::Cursor::pos()); - QCOMPARE(KWin::Cursor::pos(), cursorPos + QPoint(-8, 0)); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), cursorPos + QPoint(-8, 0)); QVERIFY(clientStepUserMovedResizedSpy.wait()); QCOMPARE(clientStepUserMovedResizedSpy.count(), 1); QCOMPARE(client->clientSize().width(), 92); client->keyPressEvent(Qt::Key_Down); - client->updateMoveResize(KWin::Cursor::pos()); - QCOMPARE(KWin::Cursor::pos(), cursorPos + QPoint(-8, 8)); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), cursorPos + QPoint(-8, 8)); QVERIFY(!clientStepUserMovedResizedSpy.wait(1000)); QCOMPARE(clientStepUserMovedResizedSpy.count(), 1); QCOMPARE(client->clientSize().height(), 200); client->keyPressEvent(Qt::Key_Up); - client->updateMoveResize(KWin::Cursor::pos()); - QCOMPARE(KWin::Cursor::pos(), cursorPos + QPoint(-8, 0)); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), cursorPos + QPoint(-8, 0)); QVERIFY(!clientStepUserMovedResizedSpy.wait(1000)); QCOMPARE(clientStepUserMovedResizedSpy.count(), 1); QCOMPARE(client->clientSize().height(), 200); client->keyPressEvent(Qt::Key_Up); - client->updateMoveResize(KWin::Cursor::pos()); - QCOMPARE(KWin::Cursor::pos(), cursorPos + QPoint(-8, -8)); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), cursorPos + QPoint(-8, -8)); QVERIFY(clientStepUserMovedResizedSpy.wait()); QCOMPARE(clientStepUserMovedResizedSpy.count(), 2); QCOMPARE(client->clientSize().height(), 192); @@ -357,18 +357,18 @@ void X11ClientTest::testResizeIncrements() QCOMPARE(clientStartMoveResizedSpy.count(), 1); QVERIFY(client->isResize()); - const QPoint cursorPos = KWin::Cursor::pos(); + const QPoint cursorPos = KWin::Cursors::self()->mouse()->pos(); client->keyPressEvent(Qt::Key_Right); - client->updateMoveResize(KWin::Cursor::pos()); - QCOMPARE(KWin::Cursor::pos(), cursorPos + QPoint(8, 0)); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), cursorPos + QPoint(8, 0)); QVERIFY(clientStepUserMovedResizedSpy.wait()); QCOMPARE(clientStepUserMovedResizedSpy.count(), 1); QCOMPARE(client->clientSize(), QSize(106, 200)); client->keyPressEvent(Qt::Key_Down); - client->updateMoveResize(KWin::Cursor::pos()); - QCOMPARE(KWin::Cursor::pos(), cursorPos + QPoint(8, 8)); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), cursorPos + QPoint(8, 8)); QVERIFY(clientStepUserMovedResizedSpy.wait()); QCOMPARE(clientStepUserMovedResizedSpy.count(), 2); QCOMPARE(client->clientSize(), QSize(106, 205)); @@ -435,18 +435,18 @@ void X11ClientTest::testResizeIncrementsNoBaseSize() QCOMPARE(clientStartMoveResizedSpy.count(), 1); QVERIFY(client->isResize()); - const QPoint cursorPos = KWin::Cursor::pos(); + const QPoint cursorPos = KWin::Cursors::self()->mouse()->pos(); client->keyPressEvent(Qt::Key_Right); - client->updateMoveResize(KWin::Cursor::pos()); - QCOMPARE(KWin::Cursor::pos(), cursorPos + QPoint(8, 0)); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), cursorPos + QPoint(8, 0)); QVERIFY(clientStepUserMovedResizedSpy.wait()); QCOMPARE(clientStepUserMovedResizedSpy.count(), 1); QCOMPARE(client->clientSize(), QSize(106, 200)); client->keyPressEvent(Qt::Key_Down); - client->updateMoveResize(KWin::Cursor::pos()); - QCOMPARE(KWin::Cursor::pos(), cursorPos + QPoint(8, 8)); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), cursorPos + QPoint(8, 8)); QVERIFY(clientStepUserMovedResizedSpy.wait()); QCOMPARE(clientStepUserMovedResizedSpy.count(), 2); QCOMPARE(client->clientSize(), QSize(106, 205)); diff --git a/autotests/integration/xdgshellclient_rules_test.cpp b/autotests/integration/xdgshellclient_rules_test.cpp index a339813e92..53e5051fc6 100644 --- a/autotests/integration/xdgshellclient_rules_test.cpp +++ b/autotests/integration/xdgshellclient_rules_test.cpp @@ -375,10 +375,10 @@ void TestXdgShellClientRules::testPositionApply() QVERIFY(client->isMove()); QVERIFY(!client->isResize()); - const QPoint cursorPos = KWin::Cursor::pos(); + const QPoint cursorPos = KWin::Cursors::self()->mouse()->pos(); client->keyPressEvent(Qt::Key_Right); - client->updateMoveResize(KWin::Cursor::pos()); - QCOMPARE(KWin::Cursor::pos(), cursorPos + QPoint(8, 0)); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), cursorPos + QPoint(8, 0)); QCOMPARE(clientStepUserMovedResizedSpy.count(), 1); QCOMPARE(client->pos(), QPoint(50, 42)); @@ -454,10 +454,10 @@ void TestXdgShellClientRules::testPositionRemember() QVERIFY(client->isMove()); QVERIFY(!client->isResize()); - const QPoint cursorPos = KWin::Cursor::pos(); + const QPoint cursorPos = KWin::Cursors::self()->mouse()->pos(); client->keyPressEvent(Qt::Key_Right); - client->updateMoveResize(KWin::Cursor::pos()); - QCOMPARE(KWin::Cursor::pos(), cursorPos + QPoint(8, 0)); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), cursorPos + QPoint(8, 0)); QCOMPARE(clientStepUserMovedResizedSpy.count(), 1); QCOMPARE(client->pos(), QPoint(50, 42)); @@ -602,10 +602,10 @@ void TestXdgShellClientRules::testPositionApplyNow() QVERIFY(client->isMove()); QVERIFY(!client->isResize()); - const QPoint cursorPos = KWin::Cursor::pos(); + const QPoint cursorPos = KWin::Cursors::self()->mouse()->pos(); client->keyPressEvent(Qt::Key_Right); - client->updateMoveResize(KWin::Cursor::pos()); - QCOMPARE(KWin::Cursor::pos(), cursorPos + QPoint(8, 0)); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), cursorPos + QPoint(8, 0)); QCOMPARE(clientStepUserMovedResizedSpy.count(), 1); QCOMPARE(client->pos(), QPoint(50, 42)); @@ -816,10 +816,10 @@ void TestXdgShellClientRules::testSizeApply() QVERIFY(states.testFlag(XdgShellSurface::State::Resizing)); shellSurface->ackConfigure(configureRequestedSpy->last().at(2).value()); - const QPoint cursorPos = KWin::Cursor::pos(); + const QPoint cursorPos = KWin::Cursors::self()->mouse()->pos(); client->keyPressEvent(Qt::Key_Right); - client->updateMoveResize(KWin::Cursor::pos()); - QCOMPARE(KWin::Cursor::pos(), cursorPos + QPoint(8, 0)); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), cursorPos + QPoint(8, 0)); QVERIFY(configureRequestedSpy->wait()); QCOMPARE(configureRequestedSpy->count(), 4); states = configureRequestedSpy->last().at(1).value(); @@ -954,10 +954,10 @@ void TestXdgShellClientRules::testSizeRemember() QVERIFY(states.testFlag(XdgShellSurface::State::Resizing)); shellSurface->ackConfigure(configureRequestedSpy->last().at(2).value()); - const QPoint cursorPos = KWin::Cursor::pos(); + const QPoint cursorPos = KWin::Cursors::self()->mouse()->pos(); client->keyPressEvent(Qt::Key_Right); - client->updateMoveResize(KWin::Cursor::pos()); - QCOMPARE(KWin::Cursor::pos(), cursorPos + QPoint(8, 0)); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), cursorPos + QPoint(8, 0)); QVERIFY(configureRequestedSpy->wait()); QCOMPARE(configureRequestedSpy->count(), 4); states = configureRequestedSpy->last().at(1).value(); diff --git a/autotests/integration/xdgshellclient_test.cpp b/autotests/integration/xdgshellclient_test.cpp index 40ce0eaedf..1a0a4fa2de 100644 --- a/autotests/integration/xdgshellclient_test.cpp +++ b/autotests/integration/xdgshellclient_test.cpp @@ -150,7 +150,7 @@ void TestXdgShellClient::init() Test::AdditionalWaylandInterface::AppMenu)); screens()->setCurrent(0); - KWin::Cursor::setPos(QPoint(1280, 512)); + KWin::Cursors::self()->mouse()->setPos(QPoint(1280, 512)); } void TestXdgShellClient::cleanup() @@ -1458,10 +1458,10 @@ void TestXdgShellClient::testXdgWindowGeometryInteractiveResize() QVERIFY(states.testFlag(XdgShellSurface::State::Resizing)); // Go right. - QPoint cursorPos = KWin::Cursor::pos(); + QPoint cursorPos = KWin::Cursors::self()->mouse()->pos(); client->keyPressEvent(Qt::Key_Right); - client->updateMoveResize(KWin::Cursor::pos()); - QCOMPARE(KWin::Cursor::pos(), cursorPos + QPoint(8, 0)); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), cursorPos + QPoint(8, 0)); QVERIFY(configureRequestedSpy.wait()); QCOMPARE(configureRequestedSpy.count(), 3); states = configureRequestedSpy.last().at(1).value(); @@ -1476,10 +1476,10 @@ void TestXdgShellClient::testXdgWindowGeometryInteractiveResize() QCOMPARE(client->frameGeometry().size(), QSize(188, 80)); // Go down. - cursorPos = KWin::Cursor::pos(); + cursorPos = KWin::Cursors::self()->mouse()->pos(); client->keyPressEvent(Qt::Key_Down); - client->updateMoveResize(KWin::Cursor::pos()); - QCOMPARE(KWin::Cursor::pos(), cursorPos + QPoint(0, 8)); + client->updateMoveResize(KWin::Cursors::self()->mouse()->pos()); + QCOMPARE(KWin::Cursors::self()->mouse()->pos(), cursorPos + QPoint(0, 8)); QVERIFY(configureRequestedSpy.wait()); QCOMPARE(configureRequestedSpy.count(), 4); states = configureRequestedSpy.last().at(1).value(); diff --git a/autotests/integration/xwayland_input_test.cpp b/autotests/integration/xwayland_input_test.cpp index bb8248e6eb..a75264b3a5 100644 --- a/autotests/integration/xwayland_input_test.cpp +++ b/autotests/integration/xwayland_input_test.cpp @@ -71,7 +71,7 @@ void XWaylandInputTest::initTestCase() void XWaylandInputTest::init() { screens()->setCurrent(0); - Cursor::setPos(QPoint(640, 512)); + Cursors::self()->mouse()->setPos(QPoint(640, 512)); xcb_warp_pointer(connection(), XCB_WINDOW_NONE, kwinApp()->x11RootWindow(), 0, 0, 0, 0, 640, 512); xcb_flush(connection()); QVERIFY(waylandServer()->clients().isEmpty()); @@ -188,16 +188,16 @@ void XWaylandInputTest::testPointerEnterLeaveSsd() QVERIFY(client->surface()); // move pointer into the window, should trigger an enter - QVERIFY(!client->frameGeometry().contains(Cursor::pos())); + QVERIFY(!client->frameGeometry().contains(Cursors::self()->mouse()->pos())); QVERIFY(enteredSpy.isEmpty()); - Cursor::setPos(client->frameGeometry().center()); + Cursors::self()->mouse()->setPos(client->frameGeometry().center()); QCOMPARE(waylandServer()->seat()->focusedPointerSurface(), client->surface()); QVERIFY(waylandServer()->seat()->focusedPointer()); QVERIFY(enteredSpy.wait()); QCOMPARE(enteredSpy.last().first(), client->frameGeometry().center() - client->clientPos()); // move out of window - Cursor::setPos(client->frameGeometry().bottomRight() + QPoint(10, 10)); + Cursors::self()->mouse()->setPos(client->frameGeometry().bottomRight() + QPoint(10, 10)); QVERIFY(leftSpy.wait()); QCOMPARE(leftSpy.last().first(), client->frameGeometry().center() - client->clientPos()); @@ -284,9 +284,9 @@ void XWaylandInputTest::testPointerEventLeaveCsd() QVERIFY(client->surface()); // Move pointer into the window, should trigger an enter. - QVERIFY(!client->frameGeometry().contains(Cursor::pos())); + QVERIFY(!client->frameGeometry().contains(Cursors::self()->mouse()->pos())); QVERIFY(enteredSpy.isEmpty()); - Cursor::setPos(client->frameGeometry().center()); + Cursors::self()->mouse()->setPos(client->frameGeometry().center()); QCOMPARE(waylandServer()->seat()->focusedPointerSurface(), client->surface()); QVERIFY(waylandServer()->seat()->focusedPointer()); QVERIFY(enteredSpy.wait()); @@ -294,7 +294,7 @@ void XWaylandInputTest::testPointerEventLeaveCsd() // Move out of the window, should trigger a leave. QVERIFY(leftSpy.isEmpty()); - Cursor::setPos(client->frameGeometry().bottomRight() + QPoint(100, 100)); + Cursors::self()->mouse()->setPos(client->frameGeometry().bottomRight() + QPoint(100, 100)); QVERIFY(leftSpy.wait()); QCOMPARE(leftSpy.last().first(), QPoint(59, 104)); diff --git a/autotests/test_screen_edges.cpp b/autotests/test_screen_edges.cpp index b100cafa9b..202bcdc0f1 100644 --- a/autotests/test_screen_edges.cpp +++ b/autotests/test_screen_edges.cpp @@ -49,30 +49,6 @@ namespace KWin Atoms* atoms; int screen_number = 0; -Cursor *Cursor::s_self = nullptr; -static QPoint s_cursorPos = QPoint(); -QPoint Cursor::pos() -{ - return s_cursorPos; -} - -void Cursor::setPos(const QPoint &pos) -{ - s_cursorPos = pos; -} - -void Cursor::setPos(int x, int y) -{ - setPos(QPoint(x, y)); -} - -void Cursor::startMousePolling() -{ -} -void Cursor::stopMousePolling() -{ -} - InputRedirection *InputRedirection::s_self = nullptr; void InputRedirection::registerShortcut(const QKeySequence &shortcut, QAction *action) @@ -149,6 +125,8 @@ void TestScreenEdges::cleanupTestCase() void TestScreenEdges::init() { + KWin::Cursors::self()->setMouse(new KWin::Cursor(this)); + using namespace KWin; new MockWorkspace; auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig); @@ -455,7 +433,7 @@ void TestScreenEdges::testCallback() xcb_enter_notify_event_t event; auto setPos = [&event] (const QPoint &pos) { - Cursor::setPos(pos); + Cursors::self()->mouse()->setPos(pos); event.root_x = pos.x(); event.root_y = pos.y(); event.event_x = pos.x(); @@ -473,7 +451,7 @@ void TestScreenEdges::testCallback() QVERIFY(isEntered(&event)); // doesn't trigger as the edge was not triggered yet QVERIFY(spy.isEmpty()); - QCOMPARE(Cursor::pos(), QPoint(1, 50)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(1, 50)); // test doesn't trigger due to too much offset QTest::qWait(160); @@ -481,7 +459,7 @@ void TestScreenEdges::testCallback() event.time = QDateTime::currentMSecsSinceEpoch(); QVERIFY(isEntered(&event)); QVERIFY(spy.isEmpty()); - QCOMPARE(Cursor::pos(), QPoint(1, 100)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(1, 100)); // doesn't trigger as we are waiting too long already QTest::qWait(200); @@ -489,7 +467,7 @@ void TestScreenEdges::testCallback() event.time = QDateTime::currentMSecsSinceEpoch(); QVERIFY(isEntered(&event)); QVERIFY(spy.isEmpty()); - QCOMPARE(Cursor::pos(), QPoint(1, 101)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(1, 101)); // doesn't activate as we are waiting too short QTest::qWait(50); @@ -497,7 +475,7 @@ void TestScreenEdges::testCallback() event.time = QDateTime::currentMSecsSinceEpoch(); QVERIFY(isEntered(&event)); QVERIFY(spy.isEmpty()); - QCOMPARE(Cursor::pos(), QPoint(1, 100)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(1, 100)); // and this one triggers QTest::qWait(110); @@ -505,7 +483,7 @@ void TestScreenEdges::testCallback() event.time = QDateTime::currentMSecsSinceEpoch(); QVERIFY(isEntered(&event)); QVERIFY(!spy.isEmpty()); - QCOMPARE(Cursor::pos(), QPoint(1, 101)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(1, 101)); // now let's try to trigger again QTest::qWait(351); @@ -513,14 +491,14 @@ void TestScreenEdges::testCallback() event.time = QDateTime::currentMSecsSinceEpoch(); QVERIFY(isEntered(&event)); QCOMPARE(spy.count(), 1); - QCOMPARE(Cursor::pos(), QPoint(1, 100)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(1, 100)); // it's still under the reactivation QTest::qWait(50); setPos(QPoint(0, 100)); event.time = QDateTime::currentMSecsSinceEpoch(); QVERIFY(isEntered(&event)); QCOMPARE(spy.count(), 1); - QCOMPARE(Cursor::pos(), QPoint(1, 100)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(1, 100)); // now it should trigger again QTest::qWait(250); setPos(QPoint(0, 100)); @@ -529,7 +507,7 @@ void TestScreenEdges::testCallback() QCOMPARE(spy.count(), 2); QCOMPARE(spy.first().first().value(), ElectricLeft); QCOMPARE(spy.last().first().value(), ElectricLeft); - QCOMPARE(Cursor::pos(), QPoint(1, 100)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(1, 100)); // let's disable pushback auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig); @@ -545,7 +523,7 @@ void TestScreenEdges::testCallback() QCOMPARE(spy.at(0).first().value(), ElectricLeft); QCOMPARE(spy.at(1).first().value(), ElectricLeft); QCOMPARE(spy.at(2).first().value(), ElectricLeft); - QCOMPARE(Cursor::pos(), QPoint(0, 100)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(0, 100)); // now let's unreserve again s->unreserve(ElectricTopLeft, &callback); @@ -578,26 +556,26 @@ void TestScreenEdges::testCallbackWithCheck() QVERIFY(spy.isEmpty()); // try a direct activate without pushback - Cursor::setPos(0, 50); + Cursors::self()->mouse()->setPos(0, 50); s->check(QPoint(0, 50), QDateTime::currentDateTimeUtc(), true); QCOMPARE(spy.count(), 1); QEXPECT_FAIL("", "Argument says force no pushback, but it gets pushed back. Needs investigation", Continue); - QCOMPARE(Cursor::pos(), QPoint(0, 50)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(0, 50)); // use a different edge, this time with pushback s->reserve(KWin::ElectricRight, &callback, "callback"); - Cursor::setPos(99, 50); + Cursors::self()->mouse()->setPos(99, 50); s->check(QPoint(99, 50), QDateTime::currentDateTimeUtc()); QCOMPARE(spy.count(), 1); QCOMPARE(spy.last().first().value(), ElectricLeft); - QCOMPARE(Cursor::pos(), QPoint(98, 50)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(98, 50)); // and trigger it again QTest::qWait(160); - Cursor::setPos(99, 50); + Cursors::self()->mouse()->setPos(99, 50); s->check(QPoint(99, 50), QDateTime::currentDateTimeUtc()); QCOMPARE(spy.count(), 2); QCOMPARE(spy.last().first().value(), ElectricRight); - QCOMPARE(Cursor::pos(), QPoint(98, 50)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(98, 50)); } void TestScreenEdges::testPushBack_data() @@ -638,7 +616,7 @@ void TestScreenEdges::testPushBack() s->reserve(border, &callback, "callback"); QFETCH(QPoint, trigger); - Cursor::setPos(trigger); + Cursors::self()->mouse()->setPos(trigger); xcb_enter_notify_event_t event; event.root_x = trigger.x(); event.root_y = trigger.y(); @@ -654,13 +632,13 @@ void TestScreenEdges::testPushBack() }; QVERIFY(isEntered(&event)); QVERIFY(spy.isEmpty()); - QTEST(Cursor::pos(), "expected"); + QTEST(Cursors::self()->mouse()->pos(), "expected"); // do the same without the event, but the check method - Cursor::setPos(trigger); + Cursors::self()->mouse()->setPos(trigger); s->check(trigger, QDateTime::currentDateTimeUtc()); QVERIFY(spy.isEmpty()); - QTEST(Cursor::pos(), "expected"); + QTEST(Cursors::self()->mouse()->pos(), "expected"); } void TestScreenEdges::testFullScreenBlocking() @@ -689,7 +667,7 @@ void TestScreenEdges::testFullScreenBlocking() } xcb_enter_notify_event_t event; - Cursor::setPos(0, 50); + Cursors::self()->mouse()->setPos(0, 50); event.root_x = 0; event.root_y = 50; event.event_x = 0; @@ -704,7 +682,7 @@ void TestScreenEdges::testFullScreenBlocking() }; QVERIFY(isEntered(&event)); QVERIFY(spy.isEmpty()); - QCOMPARE(Cursor::pos(), QPoint(1, 50)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(1, 50)); client.setFrameGeometry(screens()->geometry()); client.setActive(true); @@ -718,12 +696,12 @@ void TestScreenEdges::testFullScreenBlocking() } // calling again should not trigger QTest::qWait(160); - Cursor::setPos(0, 50); + Cursors::self()->mouse()->setPos(0, 50); event.time = QDateTime::currentMSecsSinceEpoch(); QVERIFY(isEntered(&event)); QVERIFY(spy.isEmpty()); // and no pushback - QCOMPARE(Cursor::pos(), QPoint(0, 50)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(0, 50)); // let's make the client not fullscreen, which should trigger client.setFullScreen(false); @@ -734,7 +712,7 @@ void TestScreenEdges::testFullScreenBlocking() event.time = QDateTime::currentMSecsSinceEpoch(); QVERIFY(isEntered(&event)); QVERIFY(!spy.isEmpty()); - QCOMPARE(Cursor::pos(), QPoint(1, 50)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(1, 50)); // let's make the client fullscreen again, but with a geometry not intersecting the left edge QTest::qWait(351); @@ -742,21 +720,21 @@ void TestScreenEdges::testFullScreenBlocking() client.setFrameGeometry(client.frameGeometry().translated(10, 0)); emit s->checkBlocking(); spy.clear(); - Cursor::setPos(0, 50); + Cursors::self()->mouse()->setPos(0, 50); event.time = QDateTime::currentMSecsSinceEpoch(); QVERIFY(isEntered(&event)); QVERIFY(spy.isEmpty()); // and a pushback - QCOMPARE(Cursor::pos(), QPoint(1, 50)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(1, 50)); // just to be sure, let's set geometry back client.setFrameGeometry(screens()->geometry()); emit s->checkBlocking(); - Cursor::setPos(0, 50); + Cursors::self()->mouse()->setPos(0, 50); QVERIFY(isEntered(&event)); QVERIFY(spy.isEmpty()); // and no pushback - QCOMPARE(Cursor::pos(), QPoint(0, 50)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(0, 50)); // the corner should always trigger s->unreserve(KWin::ElectricLeft, &callback); @@ -766,14 +744,14 @@ void TestScreenEdges::testFullScreenBlocking() event.root_y = 99; event.event = s->windows().first(); event.time = QDateTime::currentMSecsSinceEpoch(); - Cursor::setPos(99, 99); + Cursors::self()->mouse()->setPos(99, 99); QVERIFY(isEntered(&event)); QVERIFY(spy.isEmpty()); // and pushback - QCOMPARE(Cursor::pos(), QPoint(98, 98)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(98, 98)); QTest::qWait(160); event.time = QDateTime::currentMSecsSinceEpoch(); - Cursor::setPos(99, 99); + Cursors::self()->mouse()->setPos(99, 99); QVERIFY(isEntered(&event)); QVERIFY(!spy.isEmpty()); } @@ -812,7 +790,7 @@ void TestScreenEdges::testClientEdge() QCOMPARE(client.isHiddenInternal(), true); xcb_enter_notify_event_t event; - Cursor::setPos(0, 50); + Cursors::self()->mouse()->setPos(0, 50); event.root_x = 0; event.root_y = 50; event.event_x = 0; @@ -828,7 +806,7 @@ void TestScreenEdges::testClientEdge() QVERIFY(isEntered(&event)); // autohiding panels shall activate instantly QCOMPARE(client.isHiddenInternal(), false); - QCOMPARE(Cursor::pos(), QPoint(1, 50)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(1, 50)); // now let's reserve the client for each of the edges, in the end for the right one client.setHiddenInternal(true); @@ -862,19 +840,19 @@ void TestScreenEdges::testClientEdge() // now let's try to trigger the client showing with the check method instead of enter notify s->reserve(&client, KWin::ElectricTop); QCOMPARE(client.isHiddenInternal(), true); - Cursor::setPos(50, 0); + Cursors::self()->mouse()->setPos(50, 0); s->check(QPoint(50, 0), QDateTime::currentDateTimeUtc()); QCOMPARE(client.isHiddenInternal(), false); - QCOMPARE(Cursor::pos(), QPoint(50, 1)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(50, 1)); // unreserve by setting to none edge s->reserve(&client, KWin::ElectricNone); // check on previous edge again, should fail client.setHiddenInternal(true); - Cursor::setPos(50, 0); + Cursors::self()->mouse()->setPos(50, 0); s->check(QPoint(50, 0), QDateTime::currentDateTimeUtc()); QCOMPARE(client.isHiddenInternal(), true); - QCOMPARE(Cursor::pos(), QPoint(50, 0)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(50, 0)); // set to windows can cover client.setFrameGeometry(screens()->geometry()); @@ -885,7 +863,7 @@ void TestScreenEdges::testClientEdge() QCOMPARE(client.isHiddenInternal(), false); xcb_enter_notify_event_t event2; - Cursor::setPos(0, 50); + Cursors::self()->mouse()->setPos(0, 50); event2.root_x = 0; event2.root_y = 50; event2.event_x = 0; @@ -898,7 +876,7 @@ void TestScreenEdges::testClientEdge() QVERIFY(isEntered(&event2)); QCOMPARE(client.keepBelow(), false); QCOMPARE(client.isHiddenInternal(), false); - QCOMPARE(Cursor::pos(), QPoint(1, 50)); + QCOMPARE(Cursors::self()->mouse()->pos(), QPoint(1, 50)); } void TestScreenEdges::testTouchEdge() @@ -947,7 +925,7 @@ void TestScreenEdges::testTouchEdge() xcb_enter_notify_event_t event; auto setPos = [&event] (const QPoint &pos) { - Cursor::setPos(pos); + Cursors::self()->mouse()->setPos(pos); event.root_x = pos.x(); event.root_y = pos.y(); event.event_x = pos.x(); diff --git a/autotests/test_screens.cpp b/autotests/test_screens.cpp index 4d42658ef0..e21fda5fb0 100644 --- a/autotests/test_screens.cpp +++ b/autotests/test_screens.cpp @@ -29,16 +29,6 @@ along with this program. If not, see . Q_LOGGING_CATEGORY(KWIN_CORE, "kwin_core") // Mock -namespace KWin -{ - -static QPoint s_cursorPos = QPoint(); -QPoint Cursor::pos() -{ - return s_cursorPos; -} - -} class TestScreens : public QObject { @@ -64,7 +54,7 @@ private Q_SLOTS: void TestScreens::init() { - KWin::s_cursorPos = QPoint(); + KWin::Cursors::self()->setMouse(new KWin::Cursor(this)); } void TestScreens::testCurrentFollowsMouse() @@ -325,7 +315,7 @@ void TestScreens::testCurrentWithFollowsMouse() QVERIFY(changedSpy.wait()); QFETCH(QPoint, cursorPos); - KWin::s_cursorPos = cursorPos; + KWin::Cursors::self()->mouse()->setPos(cursorPos); QTEST(screens()->current(), "expected"); } diff --git a/autotests/test_scripted_effectloader.cpp b/autotests/test_scripted_effectloader.cpp index 0508a55d75..593502effe 100644 --- a/autotests/test_scripted_effectloader.cpp +++ b/autotests/test_scripted_effectloader.cpp @@ -63,13 +63,6 @@ void registration(QScriptEngine *) } } -static QPoint s_cursorPos = QPoint(); -QPoint Cursor::pos() -{ - return s_cursorPos; -} - - } class TestScriptedEffectLoader : public QObject @@ -93,6 +86,8 @@ void TestScriptedEffectLoader::initTestCase() qputenv("XDG_DATA_DIRS", QCoreApplication::applicationDirPath().toUtf8()); auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig); QCoreApplication::instance()->setProperty("config", QVariant::fromValue(config)); + + KWin::Cursors::self()->setMouse(new KWin::Cursor(this)); } void TestScriptedEffectLoader::testHasEffect_data() diff --git a/cursor.cpp b/cursor.cpp index 7576690061..47e7b1b812 100644 --- a/cursor.cpp +++ b/cursor.cpp @@ -39,7 +39,60 @@ along with this program. If not, see . namespace KWin { -Cursor *Cursor::s_self = nullptr; +Cursors *Cursors::s_self = nullptr; +Cursors *Cursors::self() { + if (!s_self) + s_self = new Cursors; + return s_self; +} + +void Cursors::addCursor(Cursor* cursor) +{ + Q_ASSERT(!m_cursors.contains(cursor)); + m_cursors += cursor; + + connect(cursor, &Cursor::posChanged, this, [this, cursor] (const QPoint &pos) { + setCurrentCursor(cursor); + Q_EMIT positionChanged(cursor, pos); + }); +} + +void Cursors::removeCursor(Cursor* cursor) +{ + m_cursors.removeOne(cursor); + if (m_currentCursor == cursor) { + if (m_cursors.isEmpty()) + m_currentCursor = nullptr; + else + setCurrentCursor(m_cursors.constFirst()); + } + if (m_mouse == cursor) { + m_mouse = nullptr; + } +} + +void Cursors::setCurrentCursor(Cursor* cursor) +{ + if (m_currentCursor == cursor) + return; + + Q_ASSERT(m_cursors.contains(cursor) || !cursor); + + if (m_currentCursor) { + disconnect(m_currentCursor, &Cursor::rendered, this, &Cursors::currentCursorRendered); + disconnect(m_currentCursor, &Cursor::cursorChanged, this, &Cursors::emitCurrentCursorChanged); + } + m_currentCursor = cursor; + connect(m_currentCursor, &Cursor::rendered, this, &Cursors::currentCursorRendered); + connect(m_currentCursor, &Cursor::cursorChanged, this, &Cursors::emitCurrentCursorChanged); + + Q_EMIT currentCursorChanged(m_currentCursor); +} + +void Cursors::emitCurrentCursorChanged() +{ + Q_EMIT currentCursorChanged(m_currentCursor); +} Cursor::Cursor(QObject *parent) : QObject(parent) @@ -48,7 +101,6 @@ Cursor::Cursor(QObject *parent) , m_themeName("default") , m_themeSize(24) { - s_self = this; loadThemeSettings(); QDBusConnection::sessionBus().connect(QString(), QStringLiteral("/KGlobalSettings"), QStringLiteral("org.kde.KGlobalSettings"), QStringLiteral("notifyChange"), this, SLOT(slotKGlobalSettingsNotifyChange(int,int))); @@ -56,7 +108,7 @@ Cursor::Cursor(QObject *parent) Cursor::~Cursor() { - s_self = nullptr; + Cursors::self()->removeCursor(this); } void Cursor::loadThemeSettings() @@ -102,25 +154,37 @@ void Cursor::slotKGlobalSettingsNotifyChange(int type, int arg) } } +QRect Cursor::geometry() const +{ + return QRect(m_pos - hotspot(), image().size()); +} + QPoint Cursor::pos() { - s_self->doGetPos(); - return s_self->m_pos; + doGetPos(); + return m_pos; } void Cursor::setPos(const QPoint &pos) { // first query the current pos to not warp to the already existing pos - if (pos == Cursor::pos()) { + if (pos == m_pos) { return; } - s_self->m_pos = pos; - s_self->doSetPos(); + m_pos = pos; + doSetPos(); } void Cursor::setPos(int x, int y) { - Cursor::setPos(QPoint(x, y)); + setPos(QPoint(x, y)); +} + +void Cursor::updateCursor(const QImage &image, const QPoint &hotspot) +{ + m_image = image; + m_hotspot = hotspot; + Q_EMIT cursorChanged(); } xcb_cursor_t Cursor::getX11Cursor(CursorShape shape) @@ -137,12 +201,12 @@ xcb_cursor_t Cursor::getX11Cursor(const QByteArray &name) xcb_cursor_t Cursor::x11Cursor(CursorShape shape) { - return s_self->getX11Cursor(shape); + return getX11Cursor(shape); } xcb_cursor_t Cursor::x11Cursor(const QByteArray &name) { - return s_self->getX11Cursor(name); + return getX11Cursor(name); } void Cursor::doSetPos() @@ -411,65 +475,4 @@ QByteArray CursorShape::name() const } } -InputRedirectionCursor::InputRedirectionCursor(QObject *parent) - : Cursor(parent) - , m_currentButtons(Qt::NoButton) -{ - connect(input(), SIGNAL(globalPointerChanged(QPointF)), SLOT(slotPosChanged(QPointF))); - connect(input(), SIGNAL(pointerButtonStateChanged(uint32_t,InputRedirection::PointerButtonState)), - SLOT(slotPointerButtonChanged())); -#ifndef KCMRULES - connect(input(), &InputRedirection::keyboardModifiersChanged, - this, &InputRedirectionCursor::slotModifiersChanged); -#endif -} - -InputRedirectionCursor::~InputRedirectionCursor() -{ -} - -void InputRedirectionCursor::doSetPos() -{ - if (input()->supportsPointerWarping()) { - input()->warpPointer(currentPos()); - } - slotPosChanged(input()->globalPointer()); - emit posChanged(currentPos()); -} - -void InputRedirectionCursor::slotPosChanged(const QPointF &pos) -{ - const QPoint oldPos = currentPos(); - updatePos(pos.toPoint()); - emit mouseChanged(pos.toPoint(), oldPos, m_currentButtons, m_currentButtons, - input()->keyboardModifiers(), input()->keyboardModifiers()); -} - -void InputRedirectionCursor::slotModifiersChanged(Qt::KeyboardModifiers mods, Qt::KeyboardModifiers oldMods) -{ - emit mouseChanged(currentPos(), currentPos(), m_currentButtons, m_currentButtons, mods, oldMods); -} - -void InputRedirectionCursor::slotPointerButtonChanged() -{ - const Qt::MouseButtons oldButtons = m_currentButtons; - m_currentButtons = input()->qtButtonStates(); - const QPoint pos = currentPos(); - emit mouseChanged(pos, pos, m_currentButtons, oldButtons, input()->keyboardModifiers(), input()->keyboardModifiers()); -} - -void InputRedirectionCursor::doStartCursorTracking() -{ -#ifndef KCMRULES - connect(kwinApp()->platform(), &Platform::cursorChanged, this, &Cursor::cursorChanged); -#endif -} - -void InputRedirectionCursor::doStopCursorTracking() -{ -#ifndef KCMRULES - disconnect(kwinApp()->platform(), &Platform::cursorChanged, this, &Cursor::cursorChanged); -#endif -} - } // namespace diff --git a/cursor.h b/cursor.h index 3a561a3027..40138cac23 100644 --- a/cursor.h +++ b/cursor.h @@ -1,4 +1,4 @@ -/******************************************************************** + /******************************************************************** KWin - the KDE window manager This file is part of the KDE project. @@ -97,6 +97,7 @@ class KWIN_EXPORT Cursor : public QObject { Q_OBJECT public: + Cursor(QObject* parent); ~Cursor() override; void startMousePolling(); void stopMousePolling(); @@ -147,21 +148,30 @@ public: * Implementing subclasses should prefer to use currentPos which is not performing a check * for update. */ - static QPoint pos(); + QPoint pos(); /** * Warps the mouse cursor to new @p pos. */ - static void setPos(const QPoint &pos); - static void setPos(int x, int y); - static xcb_cursor_t x11Cursor(CursorShape shape); + void setPos(const QPoint &pos); + void setPos(int x, int y); + xcb_cursor_t x11Cursor(CursorShape shape); /** * Notice: if available always use the CursorShape variant to avoid cache duplicates for * ambiguous cursor names in the non existing cursor name specification */ - static xcb_cursor_t x11Cursor(const QByteArray &name); + xcb_cursor_t x11Cursor(const QByteArray &name); + + QImage image() const { return m_image; } + QPoint hotspot() const { return m_hotspot; } + QRect geometry() const; + + void updateCursor(const QImage &image, const QPoint &hotspot); + void markAsRendered() { + Q_EMIT rendered(geometry()); + } Q_SIGNALS: - void posChanged(QPoint pos); + void posChanged(const QPoint& pos); void mouseChanged(const QPoint& pos, const QPoint& oldpos, Qt::MouseButtons buttons, Qt::MouseButtons oldbuttons, Qt::KeyboardModifiers modifiers, Qt::KeyboardModifiers oldmodifiers); @@ -176,6 +186,8 @@ Q_SIGNALS: void cursorChanged(); void themeChanged(); + void rendered(const QRect &geometry); + protected: /** * Called from x11Cursor to actually retrieve the X11 cursor. Base implementation returns @@ -240,36 +252,55 @@ private: void updateTheme(const QString &name, int size); void loadThemeFromKConfig(); QPoint m_pos; + QPoint m_hotspot; + QImage m_image; int m_mousePollingCounter; int m_cursorTrackingCounter; QString m_themeName; int m_themeSize; - - KWIN_SINGLETON(Cursor) }; -/** - * @brief Implementation using the InputRedirection framework to get pointer positions. - * - * Does not support warping of cursor. - */ -class InputRedirectionCursor : public Cursor + +class KWIN_EXPORT Cursors : public QObject { Q_OBJECT public: - explicit InputRedirectionCursor(QObject *parent); - ~InputRedirectionCursor() override; -protected: - void doSetPos() override; - void doStartCursorTracking() override; - void doStopCursorTracking() override; -private Q_SLOTS: - void slotPosChanged(const QPointF &pos); - void slotPointerButtonChanged(); - void slotModifiersChanged(Qt::KeyboardModifiers mods, Qt::KeyboardModifiers oldMods); + Cursor* mouse() const { + return m_mouse; + } + + void setMouse(Cursor* mouse) { + if (m_mouse != mouse) { + m_mouse = mouse; + + addCursor(m_mouse); + setCurrentCursor(m_mouse); + } + } + + void addCursor(Cursor* cursor); + void removeCursor(Cursor* cursor); + + ///@returns the last cursor that moved + Cursor* currentCursor() const { + return m_currentCursor; + } + + static Cursors* self(); + +Q_SIGNALS: + void currentCursorChanged(Cursor* cursor); + void currentCursorRendered(const QRect &geometry); + void positionChanged(Cursor* cursor, const QPoint &position); + private: - Qt::MouseButtons m_currentButtons; - friend class Cursor; + void emitCurrentCursorChanged(); + void setCurrentCursor(Cursor* cursor); + + static Cursors* s_self; + Cursor* m_currentCursor = nullptr; + Cursor* m_mouse = nullptr; + QVector m_cursors; }; inline const QPoint &Cursor::currentPos() const diff --git a/decorations/decoratedclient.cpp b/decorations/decoratedclient.cpp index 3637f3a41f..311a278139 100644 --- a/decorations/decoratedclient.cpp +++ b/decorations/decoratedclient.cpp @@ -123,7 +123,7 @@ DecoratedClientImpl::DecoratedClientImpl(AbstractClient *client, KDecoration2::D int fallAsleepDelay = QApplication::style()->styleHint(QStyle::SH_ToolTip_FallAsleepDelay); this->m_toolTipFallAsleep.setRemainingTime(fallAsleepDelay); - QToolTip::showText(Cursor::pos(), this->m_toolTipText); + QToolTip::showText(Cursors::self()->mouse()->pos(), this->m_toolTipText); m_toolTipShowing = true; } ); @@ -241,7 +241,7 @@ void DecoratedClientImpl::requestHideToolTip() void DecoratedClientImpl::requestShowWindowMenu() { // TODO: add rect to requestShowWindowMenu - Workspace::self()->showWindowMenu(QRect(Cursor::pos(), Cursor::pos()), m_client); + Workspace::self()->showWindowMenu(QRect(Cursors::self()->mouse()->pos(), Cursors::self()->mouse()->pos()), m_client); } void DecoratedClientImpl::requestShowApplicationMenu(const QRect &rect, int actionId) diff --git a/effects.cpp b/effects.cpp index 9deaac1c17..c9173f61aa 100644 --- a/effects.cpp +++ b/effects.cpp @@ -199,7 +199,7 @@ EffectsHandlerImpl::EffectsHandlerImpl(Compositor *compositor, Scene *scene) connect(ws->sessionManager(), &SessionManager::stateChanged, this, &KWin::EffectsHandler::sessionStateChanged); connect(vds, &VirtualDesktopManager::countChanged, this, &EffectsHandler::numberDesktopsChanged); - connect(Cursor::self(), &Cursor::mouseChanged, this, &EffectsHandler::mouseChanged); + connect(Cursors::self()->mouse(), &Cursor::mouseChanged, this, &EffectsHandler::mouseChanged); connect(screens(), &Screens::countChanged, this, &EffectsHandler::numberScreensChanged); connect(screens(), &Screens::sizeChanged, this, &EffectsHandler::virtualScreenSizeChanged); connect(screens(), &Screens::geometryChanged, this, &EffectsHandler::virtualScreenGeometryChanged); @@ -813,14 +813,14 @@ void* EffectsHandlerImpl::getProxy(QString name) void EffectsHandlerImpl::startMousePolling() { - if (Cursor::self()) - Cursor::self()->startMousePolling(); + if (Cursors::self()->mouse()) + Cursors::self()->mouse()->startMousePolling(); } void EffectsHandlerImpl::stopMousePolling() { - if (Cursor::self()) - Cursor::self()->stopMousePolling(); + if (Cursors::self()->mouse()) + Cursors::self()->mouse()->stopMousePolling(); } bool EffectsHandlerImpl::hasKeyboardGrab() const @@ -1321,8 +1321,8 @@ void EffectsHandlerImpl::connectNotify(const QMetaMethod &signal) { if (signal == QMetaMethod::fromSignal(&EffectsHandler::cursorShapeChanged)) { if (!m_trackingCursorChanges) { - connect(Cursor::self(), &Cursor::cursorChanged, this, &EffectsHandler::cursorShapeChanged); - Cursor::self()->startCursorTracking(); + connect(Cursors::self()->mouse(), &Cursor::cursorChanged, this, &EffectsHandler::cursorShapeChanged); + Cursors::self()->mouse()->startCursorTracking(); } ++m_trackingCursorChanges; } @@ -1334,8 +1334,8 @@ void EffectsHandlerImpl::disconnectNotify(const QMetaMethod &signal) if (signal == QMetaMethod::fromSignal(&EffectsHandler::cursorShapeChanged)) { Q_ASSERT(m_trackingCursorChanges > 0); if (!--m_trackingCursorChanges) { - Cursor::self()->stopCursorTracking(); - disconnect(Cursor::self(), &Cursor::cursorChanged, this, &EffectsHandler::cursorShapeChanged); + Cursors::self()->mouse()->stopCursorTracking(); + disconnect(Cursors::self()->mouse(), &Cursor::cursorChanged, this, &EffectsHandler::cursorShapeChanged); } } EffectsHandler::disconnectNotify(signal); @@ -1356,7 +1356,7 @@ void EffectsHandlerImpl::doCheckInputWindowStacking() QPoint EffectsHandlerImpl::cursorPos() const { - return Cursor::pos(); + return Cursors::self()->mouse()->pos(); } void EffectsHandlerImpl::reserveElectricBorder(ElectricBorder border, Effect *effect) diff --git a/events.cpp b/events.cpp index 0cd659a58c..63d9c2fc21 100644 --- a/events.cpp +++ b/events.cpp @@ -1181,7 +1181,7 @@ void X11Client::NETMoveResize(int x_root, int y_root, NET::Direction direction) // move cursor to the provided position to prevent the window jumping there on first movement // the expectation is that the cursor is already at the provided position, // thus it's more a safety measurement - Cursor::setPos(QPoint(x_root, y_root)); + Cursors::self()->mouse()->setPos(QPoint(x_root, y_root)); performMouseCommand(Options::MouseMove, QPoint(x_root, y_root)); } else if (isMoveResize() && direction == NET::MoveResizeCancel) { finishMoveResize(true); @@ -1212,11 +1212,11 @@ void X11Client::NETMoveResize(int x_root, int y_root, NET::Direction direction) updateCursor(); } else if (direction == NET::KeyboardMove) { // ignore mouse coordinates given in the message, mouse position is used by the moving algorithm - Cursor::setPos(frameGeometry().center()); + Cursors::self()->mouse()->setPos(frameGeometry().center()); performMouseCommand(Options::MouseUnrestrictedMove, frameGeometry().center()); } else if (direction == NET::KeyboardSize) { // ignore mouse coordinates given in the message, mouse position is used by the resizing algorithm - Cursor::setPos(frameGeometry().bottomRight()); + Cursors::self()->mouse()->setPos(frameGeometry().bottomRight()); performMouseCommand(Options::MouseUnrestrictedResize, frameGeometry().bottomRight()); } } @@ -1258,7 +1258,7 @@ bool Unmanaged::windowEvent(xcb_generic_event_t *e) release(ReleaseReason::Destroyed); break; case XCB_UNMAP_NOTIFY:{ - workspace()->updateFocusMousePosition(Cursor::pos()); // may cause leave event + workspace()->updateFocusMousePosition(Cursors::self()->mouse()->pos()); // may cause leave event // unmap notify might have been emitted due to a destroy notify // but unmap notify gets emitted before the destroy notify, nevertheless at this diff --git a/input.cpp b/input.cpp index c0879252fe..41155fd405 100644 --- a/input.cpp +++ b/input.cpp @@ -55,6 +55,7 @@ along with this program. If not, see . #include #include #include +#include #include #include #include @@ -1658,6 +1659,42 @@ public: break; } tool = tabletSeat->addTool(toolType, event->serialId(), event->uniqueId(), ifaceCapabilities); + + const auto cursor = new Cursor(tool); + Cursors::self()->addCursor(cursor); + m_cursorByTool[tool] = cursor; + + connect(tool, &TabletToolInterface::cursorChanged, cursor, &Cursor::cursorChanged); + connect(tool, &TabletToolInterface::cursorChanged, cursor, [cursor] (TabletCursor* tcursor) { + static const auto createDefaultCursor = [] { + WaylandCursorImage defaultCursor; + WaylandCursorImage::Image ret; + defaultCursor.loadThemeCursor(CursorShape(Qt::CrossCursor), &ret); + return ret; + }; + static const auto defaultCursor = createDefaultCursor(); + if (!tcursor) { + cursor->updateCursor(defaultCursor.image, defaultCursor.hotspot); + return; + } + auto cursorSurface = tcursor->surface(); + if (!cursorSurface) { + cursor->updateCursor(defaultCursor.image, defaultCursor.hotspot); + return; + } + auto buffer = cursorSurface->buffer(); + if (!buffer) { + cursor->updateCursor(defaultCursor.image, defaultCursor.hotspot); + return; + } + + QImage cursorImage; + cursorImage = buffer->data().copy(); + cursorImage.setDevicePixelRatio(cursorSurface->scale()); + + cursor->updateCursor(cursorImage, tcursor->hotspot()); + }); + emit cursor->cursorChanged(); } KWayland::Server::TabletInterface *tablet = tabletSeat->tabletByName(event->tabletSysName()); @@ -1678,6 +1715,7 @@ public: case QEvent::TabletMove: { const auto pos = event->globalPosF() - toplevel->pos(); tool->sendMotion(pos); + m_cursorByTool[tool]->setPos(event->globalPos()); break; } case QEvent::TabletEnterProximity: { tool->sendProximityIn(tablet); @@ -1730,6 +1768,7 @@ public: waylandServer()->simulateUserActivity(); return true; } + QHash m_cursorByTool; }; class DragAndDropInputFilter : public InputEventFilter diff --git a/placement.cpp b/placement.cpp index 7be7b8ea34..5e1c66580f 100644 --- a/placement.cpp +++ b/placement.cpp @@ -537,7 +537,7 @@ void Placement::placeUnderMouse(AbstractClient *c, const QRect &area, Policy /*n Q_ASSERT(area.isValid()); QRect geom = c->frameGeometry(); - geom.moveCenter(Cursor::pos()); + geom.moveCenter(Cursors::self()->mouse()->pos()); c->move(geom.topLeft()); c->keepInArea(area); // make sure it's kept inside workarea } @@ -694,7 +694,7 @@ const char* Placement::policyToString(Policy policy) void AbstractClient::packTo(int left, int top) { - workspace()->updateFocusMousePosition(Cursor::pos()); // may cause leave event; + workspace()->updateFocusMousePosition(Cursors::self()->mouse()->pos()); // may cause leave event; const int oldScreen = screen(); move(left, top); @@ -759,7 +759,7 @@ void AbstractClient::growHorizontal() } geom.setSize(constrainFrameSize(geom.size(), SizeModeFixedW)); geom.setSize(constrainFrameSize(geom.size(), SizeModeFixedH)); - workspace()->updateFocusMousePosition(Cursor::pos()); // may cause leave event; + workspace()->updateFocusMousePosition(Cursors::self()->mouse()->pos()); // may cause leave event; setFrameGeometry(geom); } @@ -779,7 +779,7 @@ void AbstractClient::shrinkHorizontal() return; geom.setSize(constrainFrameSize(geom.size(), SizeModeFixedW)); if (geom.width() > 20) { - workspace()->updateFocusMousePosition(Cursor::pos()); // may cause leave event; + workspace()->updateFocusMousePosition(Cursors::self()->mouse()->pos()); // may cause leave event; setFrameGeometry(geom); } } @@ -805,7 +805,7 @@ void AbstractClient::growVertical() geom.setBottom(newbottom); } geom.setSize(constrainFrameSize(geom.size(), SizeModeFixedH)); - workspace()->updateFocusMousePosition(Cursor::pos()); // may cause leave event; + workspace()->updateFocusMousePosition(Cursors::self()->mouse()->pos()); // may cause leave event; setFrameGeometry(geom); } @@ -826,7 +826,7 @@ void AbstractClient::shrinkVertical() return; geom.setSize(constrainFrameSize(geom.size(), SizeModeFixedH)); if (geom.height() > 20) { - workspace()->updateFocusMousePosition(Cursor::pos()); // may cause leave event; + workspace()->updateFocusMousePosition(Cursors::self()->mouse()->pos()); // may cause leave event; setFrameGeometry(geom); } } diff --git a/platform.cpp b/platform.cpp index 703d1f30da..257d9ea068 100644 --- a/platform.cpp +++ b/platform.cpp @@ -45,7 +45,8 @@ Platform::Platform(QObject *parent) , m_eglDisplay(EGL_NO_DISPLAY) { setSoftWareCursor(false); - m_colorCorrect = new ColorCorrect::Manager(this); + m_colorCorrect = new ColorCorrect::Manager(this); + connect(Cursors::self(), &Cursors::currentCursorRendered, this, &Platform::cursorRendered); } Platform::~Platform() @@ -55,19 +56,10 @@ Platform::~Platform() } } -QImage Platform::softwareCursor() const -{ - return input()->pointer()->cursorImage(); -} - -QPoint Platform::softwareCursorHotspot() const -{ - return input()->pointer()->cursorHotSpot(); -} - PlatformCursorImage Platform::cursorImage() const { - return PlatformCursorImage(softwareCursor(), softwareCursorHotspot()); + Cursor* cursor = Cursors::self()->currentCursor(); + return PlatformCursorImage(cursor->image(), cursor->hotspot()); } void Platform::hideCursor() @@ -201,11 +193,11 @@ void Platform::setSoftWareCursor(bool set) } m_softWareCursor = set; if (m_softWareCursor) { - connect(Cursor::self(), &Cursor::posChanged, this, &Platform::triggerCursorRepaint); - connect(this, &Platform::cursorChanged, this, &Platform::triggerCursorRepaint); + connect(Cursors::self(), &Cursors::positionChanged, this, &Platform::triggerCursorRepaint); + connect(Cursors::self(), &Cursors::currentCursorChanged, this, &Platform::triggerCursorRepaint); } else { - disconnect(Cursor::self(), &Cursor::posChanged, this, &Platform::triggerCursorRepaint); - disconnect(this, &Platform::cursorChanged, this, &Platform::triggerCursorRepaint); + disconnect(Cursors::self(), &Cursors::positionChanged, this, &Platform::triggerCursorRepaint); + disconnect(Cursors::self(), &Cursors::currentCursorChanged, this, &Platform::triggerCursorRepaint); } } @@ -215,16 +207,13 @@ void Platform::triggerCursorRepaint() return; } Compositor::self()->addRepaint(m_cursor.lastRenderedGeometry); - Compositor::self()->addRepaint(QRect(Cursor::pos() - softwareCursorHotspot(), softwareCursor().size())); + Compositor::self()->addRepaint(Cursors::self()->currentCursor()->geometry()); } -void Platform::markCursorAsRendered() +void Platform::cursorRendered(const QRect &geometry) { if (m_softWareCursor) { - m_cursor.lastRenderedGeometry = QRect(Cursor::pos() - softwareCursorHotspot(), softwareCursor().size()); - } - if (input()->pointer()) { - input()->pointer()->markCursorAsRendered(); + m_cursor.lastRenderedGeometry = geometry; } } diff --git a/platform.h b/platform.h index 10a6db64e8..d6da5c4e86 100644 --- a/platform.h +++ b/platform.h @@ -287,9 +287,6 @@ public: bool usesSoftwareCursor() const { return m_softWareCursor; } - QImage softwareCursor() const; - QPoint softwareCursorHotspot() const; - void markCursorAsRendered(); /** * Returns a PlatformCursorImage. By default this is created by softwareCursor and @@ -483,10 +480,11 @@ public Q_SLOTS: void processPinchGestureEnd(quint32 time); void processPinchGestureCancelled(quint32 time); + void cursorRendered(const QRect &geometry); + Q_SIGNALS: void screensQueried(); void initFailed(); - void cursorChanged(); void readyChanged(bool); /** * Emitted by backends using a one screen (nested window) approach and when the size of that changes. diff --git a/plugins/platforms/drm/drm_backend.cpp b/plugins/platforms/drm/drm_backend.cpp index fadd238ab3..e5bad20442 100644 --- a/plugins/platforms/drm/drm_backend.cpp +++ b/plugins/platforms/drm/drm_backend.cpp @@ -194,14 +194,15 @@ void DrmBackend::reactivate() } m_active = true; if (!usesSoftwareCursor()) { - const QPoint cp = Cursor::pos() - softwareCursorHotspot(); + Cursor* cursor = Cursors::self()->mouse(); + const QPoint cp = cursor->pos() - cursor->hotspot(); for (auto it = m_outputs.constBegin(); it != m_outputs.constEnd(); ++it) { DrmOutput *o = *it; // only relevant in atomic mode o->m_modesetRequested = true; o->m_crtc->blank(); o->showCursor(); - o->moveCursor(cp); + o->moveCursor(cursor, cp); } } // restart compositor @@ -647,8 +648,8 @@ void DrmBackend::initCursor() } m_cursorSize = cursorSize; // now we have screens and can set cursors, so start tracking - connect(this, &DrmBackend::cursorChanged, this, &DrmBackend::updateCursor); - connect(Cursor::self(), &Cursor::posChanged, this, &DrmBackend::moveCursor); + connect(Cursors::self(), &Cursors::currentCursorChanged, this, &DrmBackend::updateCursor); + connect(Cursors::self(), &Cursors::positionChanged, this, &DrmBackend::moveCursor); } void DrmBackend::setCursor() @@ -660,7 +661,8 @@ void DrmBackend::setCursor() } } } - markCursorAsRendered(); + + Cursors::self()->currentCursor()->markAsRendered(); } void DrmBackend::updateCursor() @@ -671,7 +673,9 @@ void DrmBackend::updateCursor() if (isCursorHidden()) { return; } - const QImage &cursorImage = softwareCursor(); + + auto cursor = Cursors::self()->currentCursor(); + const QImage &cursorImage = cursor->image(); if (cursorImage.isNull()) { doHideCursor(); return; @@ -681,7 +685,8 @@ void DrmBackend::updateCursor() } setCursor(); - moveCursor(); + + moveCursor(cursor, cursor->pos()); } void DrmBackend::doShowCursor() @@ -699,13 +704,13 @@ void DrmBackend::doHideCursor() } } -void DrmBackend::moveCursor() +void DrmBackend::moveCursor(Cursor *cursor, const QPoint &pos) { if (!m_cursorEnabled || isCursorHidden() || usesSoftwareCursor()) { return; } for (auto it = m_outputs.constBegin(); it != m_outputs.constEnd(); ++it) { - (*it)->moveCursor(Cursor::pos()); + (*it)->moveCursor(cursor, pos); } } diff --git a/plugins/platforms/drm/drm_backend.h b/plugins/platforms/drm/drm_backend.h index 36e6931387..3bde4de35f 100644 --- a/plugins/platforms/drm/drm_backend.h +++ b/plugins/platforms/drm/drm_backend.h @@ -53,6 +53,7 @@ class DrmPlane; class DrmCrtc; class DrmConnector; class GbmSurface; +class Cursor; class KWIN_EXPORT DrmBackend : public Platform @@ -158,7 +159,7 @@ private: void updateOutputs(); void setCursor(); void updateCursor(); - void moveCursor(); + void moveCursor(Cursor *cursor, const QPoint &pos); void initCursor(); void readOutputsConfiguration(); void writeOutputsConfiguration(); diff --git a/plugins/platforms/drm/drm_output.cpp b/plugins/platforms/drm/drm_output.cpp index 09c41106f8..4626bf0ec0 100644 --- a/plugins/platforms/drm/drm_output.cpp +++ b/plugins/platforms/drm/drm_output.cpp @@ -24,6 +24,7 @@ along with this program. If not, see . #include "drm_object_connector.h" #include "composite.h" +#include "cursor.h" #include "logind.h" #include "logging.h" #include "main.h" @@ -165,7 +166,7 @@ QMatrix4x4 DrmOutput::matrixDisplay(const QSize &s) const void DrmOutput::updateCursor() { - QImage cursorImage = m_backend->softwareCursor(); + QImage cursorImage = Cursors::self()->currentCursor()->image(); if (cursorImage.isNull()) { return; } @@ -180,9 +181,9 @@ void DrmOutput::updateCursor() p.end(); } -void DrmOutput::moveCursor(const QPoint &globalPos) +void DrmOutput::moveCursor(Cursor* cursor, const QPoint &globalPos) { - const QMatrix4x4 hotspotMatrix = matrixDisplay(m_backend->softwareCursor().size()); + const QMatrix4x4 hotspotMatrix = matrixDisplay(cursor->image().size()); const QPoint localPos = globalPos - AbstractWaylandOutput::globalPos(); QPoint pos = localPos; @@ -209,7 +210,7 @@ void DrmOutput::moveCursor(const QPoint &globalPos) Q_UNREACHABLE(); } pos *= scale(); - pos -= hotspotMatrix.map(m_backend->softwareCursorHotspot()); + pos -= hotspotMatrix.map(cursor->hotspot()); drmModeMoveCursor(m_backend->fd(), m_crtc->id(), pos.x(), pos.y()); } diff --git a/plugins/platforms/drm/drm_output.h b/plugins/platforms/drm/drm_output.h index 4681b38db1..52d383bd93 100644 --- a/plugins/platforms/drm/drm_output.h +++ b/plugins/platforms/drm/drm_output.h @@ -41,6 +41,7 @@ class DrmDumbBuffer; class DrmPlane; class DrmConnector; class DrmCrtc; +class Cursor; class KWIN_EXPORT DrmOutput : public AbstractWaylandOutput { @@ -55,7 +56,7 @@ public: bool showCursor(); bool hideCursor(); void updateCursor(); - void moveCursor(const QPoint &globalPos); + void moveCursor(Cursor* cursor, const QPoint &globalPos); bool init(drmModeConnector *connector); bool present(DrmBuffer *buffer); void pageFlipped(); diff --git a/plugins/platforms/wayland/wayland_backend.cpp b/plugins/platforms/wayland/wayland_backend.cpp index 2a6bde797b..bb5f4102ed 100644 --- a/plugins/platforms/wayland/wayland_backend.cpp +++ b/plugins/platforms/wayland/wayland_backend.cpp @@ -98,7 +98,7 @@ WaylandCursor::~WaylandCursor() void WaylandCursor::installImage() { - const QImage image = m_backend->softwareCursor(); + const QImage image = Cursors::self()->currentCursor()->image(); if (image.isNull() || image.size().isEmpty()) { doInstallImage(nullptr, QSize()); return; @@ -115,7 +115,7 @@ void WaylandCursor::doInstallImage(wl_buffer *image, const QSize &size) if (!pointer || !pointer->isValid()) { return; } - pointer->setCursor(m_surface, image ? m_backend->softwareCursorHotspot() : QPoint()); + pointer->setCursor(m_surface, image ? Cursors::self()->currentCursor()->hotspot() : QPoint()); drawSurface(image, size); } @@ -184,8 +184,7 @@ void WaylandSubSurfaceCursor::doInstallImage(wl_buffer *image, const QSize &size QPointF WaylandSubSurfaceCursor::absoluteToRelativePosition(const QPointF &position) { - auto ret = position - m_output->geometry().topLeft() - backend()->softwareCursorHotspot(); - return ret; + return position - m_output->geometry().topLeft() - Cursors::self()->currentCursor()->hotspot(); } void WaylandSubSurfaceCursor::move(const QPointF &globalPosition) @@ -204,7 +203,7 @@ void WaylandSubSurfaceCursor::move(const QPointF &globalPosition) return; } // place the sub-surface relative to the output it is on and factor in the hotspot - const auto relativePosition = globalPosition.toPoint() - backend()->softwareCursorHotspot() - m_output->geometry().topLeft(); + const auto relativePosition = globalPosition.toPoint() - Cursors::self()->currentCursor()->hotspot() - m_output->geometry().topLeft(); m_subSurface->setPosition(relativePosition); Compositor::self()->addRepaintFull(); } @@ -548,16 +547,17 @@ void WaylandBackend::init() if (!deviceIdentifier().isEmpty()) { m_connectionThreadObject->setSocketName(deviceIdentifier()); } - connect(this, &WaylandBackend::cursorChanged, this, + connect(Cursors::self(), &Cursors::currentCursorChanged, this, [this] { if (!m_seat) { return; } m_waylandCursor->installImage(); - markCursorAsRendered(); + auto c = Cursors::self()->currentCursor(); + c->rendered(c->geometry()); } ); - connect(this, &WaylandBackend::pointerLockChanged, this, [this](bool locked) { + connect(this, &WaylandBackend::pointerLockChanged, this, [this] (bool locked) { delete m_waylandCursor; if (locked) { Q_ASSERT(!m_relativePointer); diff --git a/plugins/platforms/x11/standalone/edge.cpp b/plugins/platforms/x11/standalone/edge.cpp index 700d086849..5bba214a92 100644 --- a/plugins/platforms/x11/standalone/edge.cpp +++ b/plugins/platforms/x11/standalone/edge.cpp @@ -109,7 +109,7 @@ void WindowBasedEdge::doStartApproaching() return; } m_approachWindow.unmap(); - Cursor *cursor = Cursor::self(); + Cursor *cursor = Cursors::self()->mouse(); #ifndef KWIN_UNIT_TEST m_cursorPollingConnection = connect(cursor, &Cursor::posChanged, this, &WindowBasedEdge::updateApproaching); #endif @@ -123,7 +123,7 @@ void WindowBasedEdge::doStopApproaching() } disconnect(m_cursorPollingConnection); m_cursorPollingConnection = QMetaObject::Connection(); - Cursor::self()->stopMousePolling(); + Cursors::self()->mouse()->stopMousePolling(); m_approachWindow.map(); } diff --git a/plugins/platforms/x11/standalone/effects_x11.cpp b/plugins/platforms/x11/standalone/effects_x11.cpp index 7a8134824d..17777726f4 100644 --- a/plugins/platforms/x11/standalone/effects_x11.cpp +++ b/plugins/platforms/x11/standalone/effects_x11.cpp @@ -107,7 +107,7 @@ void EffectsHandlerImplX11::doStopMouseInterception() void EffectsHandlerImplX11::defineCursor(Qt::CursorShape shape) { - const xcb_cursor_t c = Cursor::x11Cursor(shape); + const xcb_cursor_t c = Cursors::self()->mouse()->x11Cursor(shape); if (c != XCB_CURSOR_NONE) { m_mouseInterceptionWindow.defineCursor(c); } diff --git a/plugins/platforms/x11/standalone/windowselector.cpp b/plugins/platforms/x11/standalone/windowselector.cpp index f2a9c361df..35cc6cc446 100644 --- a/plugins/platforms/x11/standalone/windowselector.cpp +++ b/plugins/platforms/x11/standalone/windowselector.cpp @@ -110,9 +110,9 @@ bool WindowSelector::activate(const QByteArray &cursorName) xcb_cursor_t WindowSelector::createCursor(const QByteArray &cursorName) { if (cursorName.isEmpty()) { - return Cursor::x11Cursor(Qt::CrossCursor); + return Cursors::self()->mouse()->x11Cursor(Qt::CrossCursor); } - xcb_cursor_t cursor = Cursor::x11Cursor(cursorName); + xcb_cursor_t cursor = Cursors::self()->mouse()->x11Cursor(cursorName); if (cursor != XCB_CURSOR_NONE) { return cursor; } @@ -168,7 +168,7 @@ void WindowSelector::handleButtonRelease(xcb_button_t button, xcb_window_t windo if (m_callback) { selectWindowId(window); } else if (m_pointSelectionFallback) { - m_pointSelectionFallback(Cursor::pos()); + m_pointSelectionFallback(Cursors::self()->mouse()->pos()); } release(); return; @@ -199,12 +199,12 @@ void WindowSelector::handleKeyPress(xcb_keycode_t keycode, uint16_t state) mx /= 10; my /= 10; } - Cursor::setPos(Cursor::pos() + QPoint(mx, my)); + Cursors::self()->mouse()->setPos(Cursors::self()->mouse()->pos() + QPoint(mx, my)); if (returnPressed) { if (m_callback) { selectWindowUnderPointer(); } else if (m_pointSelectionFallback) { - m_pointSelectionFallback(Cursor::pos()); + m_pointSelectionFallback(Cursors::self()->mouse()->pos()); } } if (returnPressed || escapePressed) { diff --git a/plugins/platforms/x11/windowed/x11windowed_backend.cpp b/plugins/platforms/x11/windowed/x11windowed_backend.cpp index be48ca28c4..064dcab618 100644 --- a/plugins/platforms/x11/windowed/x11windowed_backend.cpp +++ b/plugins/platforms/x11/windowed/x11windowed_backend.cpp @@ -26,6 +26,8 @@ along with this program. If not, see . #include "egl_x11_backend.h" #include "outputscreens.h" #include +#include +#include // KDE #include #include @@ -94,9 +96,10 @@ void X11WindowedBackend::init() XRenderUtils::init(m_connection, m_screen->root); createOutputs(); connect(kwinApp(), &Application::workspaceCreated, this, &X11WindowedBackend::startEventReading); - connect(this, &X11WindowedBackend::cursorChanged, this, + connect(Cursors::self(), &Cursors::currentCursorChanged, this, [this] { - createCursor(softwareCursor(), softwareCursorHotspot()); + KWin::Cursor* c = KWin::Cursors::self()->currentCursor(); + createCursor(c->image(), c->hotspot()); } ); setReady(true); @@ -489,7 +492,7 @@ void X11WindowedBackend::createCursor(const QImage &srcImage, const QPoint &hots } m_cursor = cid; xcb_flush(m_connection); - markCursorAsRendered(); + Cursors::self()->currentCursor()->markAsRendered(); } xcb_window_t X11WindowedBackend::rootWindow() const diff --git a/plugins/qpa/platformcursor.cpp b/plugins/qpa/platformcursor.cpp index d56316547b..3a737b8ec5 100644 --- a/plugins/qpa/platformcursor.cpp +++ b/plugins/qpa/platformcursor.cpp @@ -34,12 +34,12 @@ PlatformCursor::~PlatformCursor() = default; QPoint PlatformCursor::pos() const { - return Cursor::pos(); + return Cursors::self()->mouse()->pos(); } void PlatformCursor::setPos(const QPoint &pos) { - Cursor::setPos(pos); + Cursors::self()->mouse()->setPos(pos); } void PlatformCursor::changeCursor(QCursor *windowCursor, QWindow *window) diff --git a/plugins/scenes/opengl/scene_opengl.cpp b/plugins/scenes/opengl/scene_opengl.cpp index d1f878de48..5493381d76 100644 --- a/plugins/scenes/opengl/scene_opengl.cpp +++ b/plugins/scenes/opengl/scene_opengl.cpp @@ -567,10 +567,12 @@ void SceneOpenGL::insertWait() */ void SceneOpenGL2::paintCursor() { + Cursor* cursor = Cursors::self()->currentCursor(); + // don't paint if we use hardware cursor or the cursor is hidden if (!kwinApp()->platform()->usesSoftwareCursor() || kwinApp()->platform()->isCursorHidden() || - kwinApp()->platform()->softwareCursor().isNull()) { + cursor->image().isNull()) { return; } @@ -578,7 +580,7 @@ void SceneOpenGL2::paintCursor() if (!m_cursorTexture) { auto updateCursorTexture = [this] { // don't paint if no image for cursor is set - const QImage img = kwinApp()->platform()->softwareCursor(); + const QImage img = Cursors::self()->currentCursor()->image(); if (img.isNull()) { return; } @@ -589,11 +591,11 @@ void SceneOpenGL2::paintCursor() updateCursorTexture(); // handle shape update on case cursor image changed - connect(kwinApp()->platform(), &Platform::cursorChanged, this, updateCursorTexture); + connect(Cursors::self(), &Cursors::currentCursorChanged, this, updateCursorTexture); } // get cursor position in projection coordinates - const QPoint cursorPos = Cursor::pos() - kwinApp()->platform()->softwareCursorHotspot(); + const QPoint cursorPos = cursor->pos() - cursor->hotspot(); const QRect cursorRect(0, 0, m_cursorTexture->width(), m_cursorTexture->height()); QMatrix4x4 mvp = m_projectionMatrix; mvp.translate(cursorPos.x(), cursorPos.y()); @@ -609,7 +611,7 @@ void SceneOpenGL2::paintCursor() m_cursorTexture->render(QRegion(cursorRect), cursorRect); m_cursorTexture->unbind(); - kwinApp()->platform()->markCursorAsRendered(); + cursor->markAsRendered(); glDisable(GL_BLEND); } diff --git a/plugins/scenes/qpainter/scene_qpainter.cpp b/plugins/scenes/qpainter/scene_qpainter.cpp index 677b83716d..54118a515f 100644 --- a/plugins/scenes/qpainter/scene_qpainter.cpp +++ b/plugins/scenes/qpainter/scene_qpainter.cpp @@ -167,14 +167,16 @@ void SceneQPainter::paintCursor() if (!kwinApp()->platform()->usesSoftwareCursor()) { return; } - const QImage img = kwinApp()->platform()->softwareCursor(); + + Cursor* cursor = Cursors::self()->currentCursor(); + const QImage img = cursor->image(); if (img.isNull()) { return; } - const QPoint cursorPos = Cursor::pos(); - const QPoint hotspot = kwinApp()->platform()->softwareCursorHotspot(); + const QPoint cursorPos = cursor->pos(); + const QPoint hotspot = cursor->hotspot(); m_painter->drawImage(cursorPos - hotspot, img); - kwinApp()->platform()->markCursorAsRendered(); + cursor->markAsRendered(); } void SceneQPainter::paintEffectQuickView(EffectQuickView *w) diff --git a/pointer_input.cpp b/pointer_input.cpp index 264132a7bf..edc81f8d39 100644 --- a/pointer_input.cpp +++ b/pointer_input.cpp @@ -130,9 +130,14 @@ void PointerInputRedirection::init() setInited(true); InputDeviceHandler::init(); - connect(m_cursor, &CursorImage::changed, kwinApp()->platform(), &Platform::cursorChanged); + connect(m_cursor, &CursorImage::changed, Cursors::self()->mouse(), [this] { + auto cursor = Cursors::self()->mouse(); + cursor->updateCursor(m_cursor->image(), m_cursor->hotSpot()); + }); emit m_cursor->changed(); + connect(Cursors::self()->mouse(), &Cursor::rendered, m_cursor, &CursorImage::markAsRendered); + connect(screens(), &Screens::changed, this, &PointerInputRedirection::updateAfterScreenChange); if (waylandServer()->hasScreenLockerIntegration()) { connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::lockStateChanged, this, @@ -894,30 +899,6 @@ void PointerInputRedirection::updateAfterScreenChange() processMotion(pos, waylandServer()->seat()->timestamp()); } -QImage PointerInputRedirection::cursorImage() const -{ - if (!inited()) { - return QImage(); - } - return m_cursor->image(); -} - -QPoint PointerInputRedirection::cursorHotSpot() const -{ - if (!inited()) { - return QPoint(); - } - return m_cursor->hotSpot(); -} - -void PointerInputRedirection::markCursorAsRendered() -{ - if (!inited()) { - return; - } - m_cursor->markAsRendered(); -} - QPointF PointerInputRedirection::position() const { return m_pos.toPoint(); @@ -988,19 +969,17 @@ CursorImage::CursorImage(PointerInputRedirection *parent) connect(workspace(), &Workspace::clientAdded, this, setupMoveResizeConnection); connect(waylandServer(), &WaylandServer::shellClientAdded, this, setupMoveResizeConnection); loadThemeCursor(Qt::ArrowCursor, &m_fallbackCursor); - if (m_cursorTheme) { - connect(m_cursorTheme, &WaylandCursorTheme::themeChanged, this, - [this] { - m_cursors.clear(); - m_cursorsByName.clear(); - loadThemeCursor(Qt::ArrowCursor, &m_fallbackCursor); - updateDecorationCursor(); - updateMoveResize(); - // TODO: update effects - } - ); - } + m_surfaceRenderedTimer.start(); + + connect(&m_waylandImage, &WaylandCursorImage::themeChanged, this, [this] { + m_cursors.clear(); + m_cursorsByName.clear(); + loadThemeCursor(Qt::ArrowCursor, &m_fallbackCursor); + updateDecorationCursor(); + updateMoveResize(); + // TODO: update effects + }); } CursorImage::~CursorImage() = default; @@ -1078,9 +1057,7 @@ void CursorImage::updateDecoration() void CursorImage::updateDecorationCursor() { - m_decorationCursor.image = QImage(); - m_decorationCursor.hotSpot = QPoint(); - + m_decorationCursor = {}; auto deco = m_pointer->decoration(); if (AbstractClient *c = deco.isNull() ? nullptr : deco->client()) { loadThemeCursor(c->cursor(), &m_decorationCursor); @@ -1093,8 +1070,7 @@ void CursorImage::updateDecorationCursor() void CursorImage::updateMoveResize() { - m_moveResizeCursor.image = QImage(); - m_moveResizeCursor.hotSpot = QPoint(); + m_moveResizeCursor = {}; if (AbstractClient *c = workspace()->moveResizeClient()) { loadThemeCursor(c->cursor(), &m_moveResizeCursor); if (m_currentSource == CursorSource::MoveResize) { @@ -1106,8 +1082,7 @@ void CursorImage::updateMoveResize() void CursorImage::updateServerCursor() { - m_serverCursor.image = QImage(); - m_serverCursor.hotSpot = QPoint(); + m_serverCursor.cursor = {}; reevaluteSource(); const bool needsEmit = m_currentSource == CursorSource::LockScreen || m_currentSource == CursorSource::PointerSurface; auto p = waylandServer()->seat()->focusedPointer(); @@ -1138,15 +1113,15 @@ void CursorImage::updateServerCursor() } return; } - m_serverCursor.hotSpot = c->hotspot(); - m_serverCursor.image = buffer->data().copy(); - m_serverCursor.image.setDevicePixelRatio(cursorSurface->scale()); + m_serverCursor.cursor.hotspot = c->hotspot(); + m_serverCursor.cursor.image = buffer->data().copy(); + m_serverCursor.cursor.image.setDevicePixelRatio(cursorSurface->scale()); if (needsEmit) { emit changed(); } } -void CursorImage::loadTheme() +void WaylandCursorImage::loadTheme() { if (m_cursorTheme) { return; @@ -1199,8 +1174,7 @@ void CursorImage::updateDrag() { using namespace KWayland::Server; disconnect(m_drag.connection); - m_drag.cursor.image = QImage(); - m_drag.cursor.hotSpot = QPoint(); + m_drag.cursor = {}; reevaluteSource(); if (auto p = waylandServer()->seat()->dragPointer()) { m_drag.connection = connect(p, &PointerInterface::cursorChanged, this, &CursorImage::updateDragCursor); @@ -1212,8 +1186,7 @@ void CursorImage::updateDrag() void CursorImage::updateDragCursor() { - m_drag.cursor.image = QImage(); - m_drag.cursor.hotSpot = QPoint(); + m_drag.cursor = {}; const bool needsEmit = m_currentSource == CursorSource::DragAndDrop; QImage additionalIcon; if (auto ddi = waylandServer()->seat()->dragSource()) { @@ -1252,7 +1225,7 @@ void CursorImage::updateDragCursor() } return; } - m_drag.cursor.hotSpot = c->hotspot(); + m_drag.cursor.hotspot = c->hotspot(); if (additionalIcon.isNull()) { m_drag.cursor.image = buffer->data().copy(); @@ -1260,15 +1233,15 @@ void CursorImage::updateDragCursor() QRect cursorRect = buffer->data().rect(); QRect iconRect = additionalIcon.rect(); - if (-m_drag.cursor.hotSpot.x() < additionalIcon.offset().x()) { - iconRect.moveLeft(m_drag.cursor.hotSpot.x() - additionalIcon.offset().x()); + if (-m_drag.cursor.hotspot.x() < additionalIcon.offset().x()) { + iconRect.moveLeft(m_drag.cursor.hotspot.x() - additionalIcon.offset().x()); } else { - cursorRect.moveLeft(-additionalIcon.offset().x() - m_drag.cursor.hotSpot.x()); + cursorRect.moveLeft(-additionalIcon.offset().x() - m_drag.cursor.hotspot.x()); } - if (-m_drag.cursor.hotSpot.y() < additionalIcon.offset().y()) { - iconRect.moveTop(m_drag.cursor.hotSpot.y() - additionalIcon.offset().y()); + if (-m_drag.cursor.hotspot.y() < additionalIcon.offset().y()) { + iconRect.moveTop(m_drag.cursor.hotspot.y() - additionalIcon.offset().y()); } else { - cursorRect.moveTop(-additionalIcon.offset().y() - m_drag.cursor.hotSpot.y()); + cursorRect.moveTop(-additionalIcon.offset().y() - m_drag.cursor.hotspot.y()); } m_drag.cursor.image = QImage(cursorRect.united(iconRect).size(), QImage::Format_ARGB32_Premultiplied); @@ -1285,50 +1258,57 @@ void CursorImage::updateDragCursor() // TODO: add the cursor image } -void CursorImage::loadThemeCursor(CursorShape shape, Image *image) +void CursorImage::loadThemeCursor(CursorShape shape, WaylandCursorImage::Image *image) { - loadThemeCursor(shape, m_cursors, image); + m_waylandImage.loadThemeCursor(shape, m_cursors, image); } -void CursorImage::loadThemeCursor(const QByteArray &shape, Image *image) +void CursorImage::loadThemeCursor(const QByteArray &shape, WaylandCursorImage::Image *image) { - loadThemeCursor(shape, m_cursorsByName, image); + m_waylandImage.loadThemeCursor(shape, m_cursorsByName, image); } template -void CursorImage::loadThemeCursor(const T &shape, QHash &cursors, Image *image) +void WaylandCursorImage::loadThemeCursor(const T &shape, Image *image) { loadTheme(); if (!m_cursorTheme) { return; } + + image->image = {}; + wl_cursor_image *cursor = m_cursorTheme->get(shape); + if (!cursor) { + qDebug() << "Could not find cursor" << shape; + return; + } + wl_buffer *b = wl_cursor_image_get_buffer(cursor); + if (!b) { + return; + } + waylandServer()->internalClientConection()->flush(); + waylandServer()->dispatch(); + auto buffer = KWayland::Server::BufferInterface::get(waylandServer()->internalConnection()->getResource(KWayland::Client::Buffer::getId(b))); + if (!buffer) { + return; + } + auto scale = screens()->maxScale(); + int hotSpotX = qRound(cursor->hotspot_x / scale); + int hotSpotY = qRound(cursor->hotspot_y / scale); + QImage img = buffer->data().copy(); + img.setDevicePixelRatio(scale); + *image = {img, QPoint(hotSpotX, hotSpotY)}; +} + +template +void WaylandCursorImage::loadThemeCursor(const T &shape, QHash &cursors, Image *image) +{ auto it = cursors.constFind(shape); if (it == cursors.constEnd()) { - image->image = QImage(); - image->hotSpot = QPoint(); - wl_cursor_image *cursor = m_cursorTheme->get(shape); - if (!cursor) { - return; - } - wl_buffer *b = wl_cursor_image_get_buffer(cursor); - if (!b) { - return; - } - waylandServer()->internalClientConection()->flush(); - waylandServer()->dispatch(); - auto buffer = KWayland::Server::BufferInterface::get(waylandServer()->internalConnection()->getResource(KWayland::Client::Buffer::getId(b))); - if (!buffer) { - return; - } - auto scale = screens()->maxScale(); - int hotSpotX = qRound(cursor->hotspot_x / scale); - int hotSpotY = qRound(cursor->hotspot_y / scale); - QImage img = buffer->data().copy(); - img.setDevicePixelRatio(scale); - it = decltype(it)(cursors.insert(shape, {img, QPoint(hotSpotX, hotSpotY)})); + loadThemeCursor(shape, image); + it = cursors.insert(shape, *image); } - image->hotSpot = it.value().hotSpot; - image->image = it.value().image; + *image = it.value(); } void CursorImage::reevaluteSource() @@ -1384,7 +1364,7 @@ QImage CursorImage::image() const case CursorSource::LockScreen: case CursorSource::PointerSurface: // lockscreen also uses server cursor image - return m_serverCursor.image; + return m_serverCursor.cursor.image; case CursorSource::Decoration: return m_decorationCursor.image; case CursorSource::DragAndDrop: @@ -1402,24 +1382,86 @@ QPoint CursorImage::hotSpot() const { switch (m_currentSource) { case CursorSource::EffectsOverride: - return m_effectsCursor.hotSpot; + return m_effectsCursor.hotspot; case CursorSource::MoveResize: - return m_moveResizeCursor.hotSpot; + return m_moveResizeCursor.hotspot; case CursorSource::LockScreen: case CursorSource::PointerSurface: // lockscreen also uses server cursor image - return m_serverCursor.hotSpot; + return m_serverCursor.cursor.hotspot; case CursorSource::Decoration: - return m_decorationCursor.hotSpot; + return m_decorationCursor.hotspot; case CursorSource::DragAndDrop: - return m_drag.cursor.hotSpot; + return m_drag.cursor.hotspot; case CursorSource::Fallback: - return m_fallbackCursor.hotSpot; + return m_fallbackCursor.hotspot; case CursorSource::WindowSelector: - return m_windowSelectionCursor.hotSpot; + return m_windowSelectionCursor.hotspot; default: Q_UNREACHABLE(); } } +InputRedirectionCursor::InputRedirectionCursor(QObject *parent) + : Cursor(parent) + , m_currentButtons(Qt::NoButton) +{ + Cursors::self()->setMouse(this); + connect(input(), SIGNAL(globalPointerChanged(QPointF)), SLOT(slotPosChanged(QPointF))); + connect(input(), SIGNAL(pointerButtonStateChanged(uint32_t,InputRedirection::PointerButtonState)), + SLOT(slotPointerButtonChanged())); +#ifndef KCMRULES + connect(input(), &InputRedirection::keyboardModifiersChanged, + this, &InputRedirectionCursor::slotModifiersChanged); +#endif +} + +InputRedirectionCursor::~InputRedirectionCursor() +{ +} + +void InputRedirectionCursor::doSetPos() +{ + if (input()->supportsPointerWarping()) { + input()->warpPointer(currentPos()); + } + slotPosChanged(input()->globalPointer()); + emit posChanged(currentPos()); +} + +void InputRedirectionCursor::slotPosChanged(const QPointF &pos) +{ + const QPoint oldPos = currentPos(); + updatePos(pos.toPoint()); + emit mouseChanged(pos.toPoint(), oldPos, m_currentButtons, m_currentButtons, + input()->keyboardModifiers(), input()->keyboardModifiers()); +} + +void InputRedirectionCursor::slotModifiersChanged(Qt::KeyboardModifiers mods, Qt::KeyboardModifiers oldMods) +{ + emit mouseChanged(currentPos(), currentPos(), m_currentButtons, m_currentButtons, mods, oldMods); +} + +void InputRedirectionCursor::slotPointerButtonChanged() +{ + const Qt::MouseButtons oldButtons = m_currentButtons; + m_currentButtons = input()->qtButtonStates(); + const QPoint pos = currentPos(); + emit mouseChanged(pos, pos, m_currentButtons, oldButtons, input()->keyboardModifiers(), input()->keyboardModifiers()); +} + +void InputRedirectionCursor::doStartCursorTracking() +{ +#ifndef KCMRULES +// connect(Cursors::self(), &Cursors::currentCursorChanged, this, &Cursor::cursorChanged); +#endif +} + +void InputRedirectionCursor::doStopCursorTracking() +{ +#ifndef KCMRULES +// disconnect(kwinApp()->platform(), &Platform::cursorChanged, this, &Cursor::cursorChanged); +#endif +} + } diff --git a/pointer_input.h b/pointer_input.h index b2ae58ca60..8c19b8caaa 100644 --- a/pointer_input.h +++ b/pointer_input.h @@ -23,6 +23,7 @@ along with this program. If not, see . #define KWIN_POINTER_INPUT_H #include "input.h" +#include "cursor.h" #include #include @@ -80,9 +81,6 @@ public: } bool areButtonsPressed() const; - QImage cursorImage() const; - QPoint cursorHotSpot() const; - void markCursorAsRendered(); void setEffectsOverrideCursor(Qt::CursorShape shape); void removeEffectsOverrideCursor(); void setWindowSelectionCursor(const QByteArray &shape); @@ -182,6 +180,28 @@ private: bool m_enableConstraints = true; }; +class WaylandCursorImage : public QObject +{ + Q_OBJECT +public: + void loadTheme(); + struct Image { + QImage image; + QPoint hotspot; + }; + template + void loadThemeCursor(const T &shape, Image *image); + + template + void loadThemeCursor(const T &shape, QHash &cursors, Image *image); + +Q_SIGNALS: + void themeChanged(); + +private: + WaylandCursorTheme *m_cursorTheme = nullptr; +}; + class CursorImage : public QObject { Q_OBJECT @@ -210,15 +230,9 @@ private: void updateMoveResize(); void updateDrag(); void updateDragCursor(); - void loadTheme(); - struct Image { - QImage image; - QPoint hotSpot; - }; - void loadThemeCursor(CursorShape shape, Image *image); - void loadThemeCursor(const QByteArray &shape, Image *image); - template - void loadThemeCursor(const T &shape, QHash &cursors, Image *image); + + void loadThemeCursor(CursorShape shape, WaylandCursorImage::Image *image); + void loadThemeCursor(const QByteArray &shape, WaylandCursorImage::Image *image); enum class CursorSource { LockScreen, @@ -234,26 +248,48 @@ private: PointerInputRedirection *m_pointer; CursorSource m_currentSource = CursorSource::Fallback; - WaylandCursorTheme *m_cursorTheme = nullptr; - struct { - QMetaObject::Connection connection; - QImage image; - QPoint hotSpot; - } m_serverCursor; + WaylandCursorImage m_waylandImage; - Image m_effectsCursor; - Image m_decorationCursor; + WaylandCursorImage::Image m_effectsCursor; + WaylandCursorImage::Image m_decorationCursor; QMetaObject::Connection m_decorationConnection; - Image m_fallbackCursor; - Image m_moveResizeCursor; - Image m_windowSelectionCursor; - QHash m_cursors; - QHash m_cursorsByName; + WaylandCursorImage::Image m_fallbackCursor; + WaylandCursorImage::Image m_moveResizeCursor; + WaylandCursorImage::Image m_windowSelectionCursor; + QHash m_cursors; + QHash m_cursorsByName; QElapsedTimer m_surfaceRenderedTimer; struct { - Image cursor; + WaylandCursorImage::Image cursor; QMetaObject::Connection connection; } m_drag; + struct { + QMetaObject::Connection connection; + WaylandCursorImage::Image cursor; + } m_serverCursor; +}; + +/** + * @brief Implementation using the InputRedirection framework to get pointer positions. + * + * Does not support warping of cursor. + */ +class InputRedirectionCursor : public KWin::Cursor +{ + Q_OBJECT +public: + explicit InputRedirectionCursor(QObject *parent); + ~InputRedirectionCursor() override; +protected: + void doSetPos() override; + void doStartCursorTracking() override; + void doStopCursorTracking() override; +private Q_SLOTS: + void slotPosChanged(const QPointF &pos); + void slotPointerButtonChanged(); + void slotModifiersChanged(Qt::KeyboardModifiers mods, Qt::KeyboardModifiers oldMods); +private: + Qt::MouseButtons m_currentButtons; }; } diff --git a/screenedge.cpp b/screenedge.cpp index edbf0d35ac..78a0af0189 100644 --- a/screenedge.cpp +++ b/screenedge.cpp @@ -446,7 +446,7 @@ void Edge::switchDesktop(const QPoint &cursorPos) vds->setCurrent(desktop); if (vds->current() != oldDesktop) { m_pushBackBlocked = true; - Cursor::setPos(pos); + Cursors::self()->mouse()->setPos(pos); QSharedPointer me(new QMetaObject::Connection); *me = QObject::connect(QCoreApplication::eventDispatcher(), &QAbstractEventDispatcher::aboutToBlock, this, @@ -478,7 +478,7 @@ void Edge::pushCursorBack(const QPoint &cursorPos) if (isBottom()) { y -= distance.height(); } - Cursor::setPos(x, y); + Cursors::self()->mouse()->setPos(x, y); } void Edge::setGeometry(const QRect &geometry) diff --git a/screens.cpp b/screens.cpp index 5dcb257a90..3e8d7e3c5b 100644 --- a/screens.cpp +++ b/screens.cpp @@ -176,7 +176,7 @@ void Screens::setCurrentFollowsMouse(bool follows) int Screens::current() const { if (m_currentFollowsMouse) { - return number(Cursor::pos()); + return number(Cursors::self()->mouse()->pos()); } AbstractClient *client = Workspace::self()->activeClient(); if (client && !client->isOnScreen(m_current)) { diff --git a/useractions.cpp b/useractions.cpp index 7ac429548b..3ec329325b 100644 --- a/useractions.cpp +++ b/useractions.cpp @@ -1049,21 +1049,21 @@ void Workspace::performWindowOperation(AbstractClient* c, Options::WindowOperati if (!c) return; if (op == Options::MoveOp || op == Options::UnrestrictedMoveOp) - Cursor::setPos(c->frameGeometry().center()); + Cursors::self()->mouse()->setPos(c->frameGeometry().center()); if (op == Options::ResizeOp || op == Options::UnrestrictedResizeOp) - Cursor::setPos(c->frameGeometry().bottomRight()); + Cursors::self()->mouse()->setPos(c->frameGeometry().bottomRight()); switch(op) { case Options::MoveOp: - c->performMouseCommand(Options::MouseMove, Cursor::pos()); + c->performMouseCommand(Options::MouseMove, Cursors::self()->mouse()->pos()); break; case Options::UnrestrictedMoveOp: - c->performMouseCommand(Options::MouseUnrestrictedMove, Cursor::pos()); + c->performMouseCommand(Options::MouseUnrestrictedMove, Cursors::self()->mouse()->pos()); break; case Options::ResizeOp: - c->performMouseCommand(Options::MouseResize, Cursor::pos()); + c->performMouseCommand(Options::MouseResize, Cursors::self()->mouse()->pos()); break; case Options::UnrestrictedResizeOp: - c->performMouseCommand(Options::MouseUnrestrictedResize, Cursor::pos()); + c->performMouseCommand(Options::MouseUnrestrictedResize, Cursors::self()->mouse()->pos()); break; case Options::CloseOp: QMetaObject::invokeMethod(c, "closeWindow", Qt::QueuedConnection); @@ -1085,7 +1085,7 @@ void Workspace::performWindowOperation(AbstractClient* c, Options::WindowOperati c->minimize(); break; case Options::ShadeOp: - c->performMouseCommand(Options::MouseShade, Cursor::pos()); + c->performMouseCommand(Options::MouseShade, Cursors::self()->mouse()->pos()); break; case Options::OnAllDesktopsOp: c->setOnAllDesktops(!c->isOnAllDesktops()); @@ -1113,7 +1113,7 @@ void Workspace::performWindowOperation(AbstractClient* c, Options::WindowOperati break; } case Options::OperationsOp: - c->performMouseCommand(Options::MouseShade, Cursor::pos()); + c->performMouseCommand(Options::MouseShade, Cursors::self()->mouse()->pos()); break; case Options::WindowRulesOp: RuleBook::self()->edit(c, false); diff --git a/wayland_cursor_theme.cpp b/wayland_cursor_theme.cpp index 9444c2f16b..4d539ccc37 100644 --- a/wayland_cursor_theme.cpp +++ b/wayland_cursor_theme.cpp @@ -51,7 +51,7 @@ void WaylandCursorTheme::loadTheme() if (!m_shm->isValid()) { return; } - Cursor *c = Cursor::self(); + Cursor *c = Cursors::self()->mouse(); int size = c->themeSize(); if (size == 0) { //set a default size @@ -99,7 +99,7 @@ wl_cursor_image *WaylandCursorTheme::get(const QByteArray &name) } wl_cursor *c = wl_cursor_theme_get_cursor(m_theme, name.constData()); if (!c || c->image_count <= 0) { - const auto &names = Cursor::self()->cursorAlternativeNames(name); + const auto &names = Cursors::self()->mouse()->cursorAlternativeNames(name); for (auto it = names.begin(), end = names.end(); it != end; it++) { c = wl_cursor_theme_get_cursor(m_theme, (*it).constData()); if (c && c->image_count > 0) { diff --git a/workspace.cpp b/workspace.cpp index 273c5a36a7..a5e991adf7 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -1011,7 +1011,7 @@ AbstractClient *Workspace::findClientToActivateOnDesktop(uint desktop) client->isOnCurrentActivity() && client->isOnActiveScreen())) continue; - if (client->frameGeometry().contains(Cursor::pos())) { + if (client->frameGeometry().contains(Cursors::self()->mouse()->pos())) { if (!client->isDesktop()) return client; break; // unconditional break - we do not pass the focus to some client below an unusable one diff --git a/x11client.cpp b/x11client.cpp index 3b51dcae3b..cdf05519a4 100644 --- a/x11client.cpp +++ b/x11client.cpp @@ -167,7 +167,7 @@ X11Client::X11Client() connect(options, &Options::condensedTitleChanged, this, &X11Client::updateCaption); connect(this, &X11Client::moveResizeCursorChanged, this, [this] (CursorShape cursor) { - xcb_cursor_t nativeCursor = Cursor::x11Cursor(cursor); + xcb_cursor_t nativeCursor = Cursors::self()->mouse()->x11Cursor(cursor); m_frame.defineCursor(nativeCursor); if (m_decoInputExtent.isValid()) m_decoInputExtent.defineCursor(nativeCursor); @@ -926,7 +926,7 @@ void X11Client::embedClient(xcb_window_t w, xcb_visualid_t visualid, xcb_colorma 0, // back_pixmap 0, // border_pixel colormap, // colormap - Cursor::x11Cursor(Qt::ArrowCursor) + Cursors::self()->mouse()->x11Cursor(Qt::ArrowCursor) }; const uint32_t cw_mask = XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | @@ -4353,7 +4353,7 @@ void X11Client::changeMaximize(bool horizontal, bool vertical, bool adjust) QRect clientArea; if (isElectricBorderMaximizing()) - clientArea = workspace()->clientArea(MaximizeArea, Cursor::pos(), desktop()); + clientArea = workspace()->clientArea(MaximizeArea, Cursors::self()->mouse()->pos(), desktop()); else clientArea = workspace()->clientArea(MaximizeArea, this); @@ -4549,7 +4549,7 @@ void X11Client::changeMaximize(bool horizontal, bool vertical, bool adjust) r.setSize(constrainFrameSize(r.size(), SizeModeMax)); if (r.size() != clientArea.size()) { // to avoid off-by-one errors... if (isElectricBorderMaximizing() && r.width() < clientArea.width()) { - r.moveLeft(qMax(clientArea.left(), Cursor::pos().x() - r.width()/2)); + r.moveLeft(qMax(clientArea.left(), Cursors::self()->mouse()->pos().x() - r.width()/2)); r.moveRight(qMin(clientArea.right(), r.right())); } else { r.moveCenter(clientArea.center()); @@ -4625,7 +4625,7 @@ void X11Client::setFullScreen(bool set, bool user) setShade(ShadeNone); if (wasFullscreen) { - workspace()->updateFocusMousePosition(Cursor::pos()); // may cause leave event + workspace()->updateFocusMousePosition(Cursors::self()->mouse()->pos()); // may cause leave event } else { geom_fs_restore = frameGeometry(); } @@ -4746,7 +4746,7 @@ bool X11Client::doStartMoveResize() const xcb_grab_pointer_cookie_t cookie = xcb_grab_pointer_unchecked(connection(), false, m_moveResizeGrabWindow, XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW, - XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, m_moveResizeGrabWindow, Cursor::x11Cursor(cursor()), xTime()); + XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, m_moveResizeGrabWindow, Cursors::self()->mouse()->x11Cursor(cursor()), xTime()); ScopedCPointer pointerGrab(xcb_grab_pointer_reply(connection(), cookie, nullptr)); if (!pointerGrab.isNull() && pointerGrab->status == XCB_GRAB_STATUS_SUCCESS) { has_grab = true; diff --git a/xdgshellclient.cpp b/xdgshellclient.cpp index 5cee6ac341..dcca4d8336 100644 --- a/xdgshellclient.cpp +++ b/xdgshellclient.cpp @@ -755,7 +755,7 @@ void XdgShellClient::changeMaximize(bool horizontal, bool vertical, bool adjust) } const QRect clientArea = isElectricBorderMaximizing() ? - workspace()->clientArea(MaximizeArea, Cursor::pos(), desktop()) : + workspace()->clientArea(MaximizeArea, Cursors::self()->mouse()->pos(), desktop()) : workspace()->clientArea(MaximizeArea, this); const MaximizeMode oldMode = m_requestedMaximizeMode; @@ -892,7 +892,7 @@ void XdgShellClient::setFullScreen(bool set, bool user) } if (wasFullscreen) { - workspace()->updateFocusMousePosition(Cursor::pos()); // may cause leave event + workspace()->updateFocusMousePosition(Cursors::self()->mouse()->pos()); // may cause leave event } else { m_geomFsRestore = frameGeometry(); } @@ -1181,7 +1181,7 @@ void XdgShellClient::handleMoveRequested(SeatInterface *seat, quint32 serial) // FIXME: Check the seat and serial. Q_UNUSED(seat) Q_UNUSED(serial) - performMouseCommand(Options::MouseMove, Cursor::pos()); + performMouseCommand(Options::MouseMove, Cursors::self()->mouse()->pos()); } void XdgShellClient::handleResizeRequested(SeatInterface *seat, quint32 serial, Qt::Edges edges) @@ -1196,7 +1196,7 @@ void XdgShellClient::handleResizeRequested(SeatInterface *seat, quint32 serial, finishMoveResize(false); } setMoveResizePointerButtonDown(true); - setMoveOffset(Cursor::pos() - pos()); // map from global + setMoveOffset(Cursors::self()->mouse()->pos() - pos()); // map from global setInvertedMoveOffset(rect().bottomRight() - moveOffset()); setUnrestrictedMoveResize(false); auto toPosition = [edges] { @@ -1222,7 +1222,7 @@ void XdgShellClient::handleResizeRequested(SeatInterface *seat, quint32 serial, void XdgShellClient::handleMinimizeRequested() { - performMouseCommand(Options::MouseMinimize, Cursor::pos()); + performMouseCommand(Options::MouseMinimize, Cursors::self()->mouse()->pos()); } void XdgShellClient::handleMaximizeRequested(bool maximized)