Make it possible to have a separate cursor for the tablet

Summary:
As is KWin only had 1 Cursor which was a singleton. This made it impossible for
us to properly implement the tablet (as in drawing tablets) support and show where
we're drawing.
This patch makes it possible to have different Cursors in KWin, it makes all the
current code still follow the mouse but the tablet can still render a cursor.

Test Plan: Tests pass, been using it and works as well as before but with beautiful tablet cursors.

Reviewers: #kwin, cblack, davidedmundson

Reviewed By: #kwin, cblack, davidedmundson

Subscribers: davidedmundson, cblack, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D28155
This commit is contained in:
Aleix Pol 2020-04-02 18:18:01 +02:00
parent 08a21ae7b6
commit 6abd23ed02
78 changed files with 831 additions and 705 deletions

View file

@ -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)

View file

@ -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;
}
}

View file

@ -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

View file

@ -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()

View file

@ -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()

View file

@ -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);

View file

@ -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()

View file

@ -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()

View file

@ -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)

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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);

View file

@ -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);

View file

@ -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()

View file

@ -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()

View file

@ -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);

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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> 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));

View file

@ -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()

View file

@ -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> surface(Test::createSurface());
QScopedPointer<XdgShellSurface> shellSurface(Test::createXdgShellStableSurface(surface.data()));

View file

@ -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);

View file

@ -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()

View file

@ -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));
}

View file

@ -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());

View file

@ -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<EffectsHandlerImpl*>(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<HelperEffect> 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<AbstractClient *>();
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());

View file

@ -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);

View file

@ -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());
}

View file

@ -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()

View file

@ -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

View file

@ -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

View file

@ -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()

View file

@ -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());

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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());
}

View file

@ -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());

View file

@ -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));

View file

@ -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<quint32>());
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<XdgShellSurface::States>();
@ -954,10 +954,10 @@ void TestXdgShellClientRules::testSizeRemember()
QVERIFY(states.testFlag(XdgShellSurface::State::Resizing));
shellSurface->ackConfigure(configureRequestedSpy->last().at(2).value<quint32>());
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<XdgShellSurface::States>();

View file

@ -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<XdgShellSurface::States>();
@ -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<XdgShellSurface::States>();

View file

@ -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));

View file

@ -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<ElectricBorder>(), ElectricLeft);
QCOMPARE(spy.last().first().value<ElectricBorder>(), 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<ElectricBorder>(), ElectricLeft);
QCOMPARE(spy.at(1).first().value<ElectricBorder>(), ElectricLeft);
QCOMPARE(spy.at(2).first().value<ElectricBorder>(), 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<ElectricBorder>(), 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<ElectricBorder>(), 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();

View file

@ -29,16 +29,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
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");
}

View file

@ -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()

View file

@ -39,7 +39,60 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
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

View file

@ -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<Cursor*> m_cursors;
};
inline const QPoint &Cursor::currentPos() const

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -55,6 +55,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <KWayland/Server/fakeinput_interface.h>
#include <KWayland/Server/relativepointer_interface.h>
#include <KWayland/Server/seat_interface.h>
#include <KWayland/Server/buffer_interface.h>
#include <KWayland/Server/surface_interface.h>
#include <KWayland/Server/tablet_interface.h>
#include <decorations/decoratedclient.h>
@ -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<KWayland::Server::TabletToolInterface*, Cursor*> m_cursorByTool;
};
class DragAndDropInputFilter : public InputEventFilter

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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.

View file

@ -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);
}
}

View file

@ -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();

View file

@ -24,6 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#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());
}

View file

@ -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();

View file

@ -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);

View file

@ -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();
}

View file

@ -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);
}

View file

@ -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) {

View file

@ -26,6 +26,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "egl_x11_backend.h"
#include "outputscreens.h"
#include <kwinxrenderutils.h>
#include <cursor.h>
#include <pointer_input.h>
// KDE
#include <KLocalizedString>
#include <QAbstractEventDispatcher>
@ -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

View file

@ -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)

View file

@ -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);
}

View file

@ -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)

View file

@ -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 <typename T>
void CursorImage::loadThemeCursor(const T &shape, QHash<T, Image> &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 <typename T>
void WaylandCursorImage::loadThemeCursor(const T &shape, QHash<T, Image> &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
}
}

View file

@ -23,6 +23,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define KWIN_POINTER_INPUT_H
#include "input.h"
#include "cursor.h"
#include <QElapsedTimer>
#include <QObject>
@ -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 <typename T>
void loadThemeCursor(const T &shape, Image *image);
template <typename T>
void loadThemeCursor(const T &shape, QHash<T, Image> &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 <typename T>
void loadThemeCursor(const T &shape, QHash<T, Image> &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<CursorShape, Image> m_cursors;
QHash<QByteArray, Image> m_cursorsByName;
WaylandCursorImage::Image m_fallbackCursor;
WaylandCursorImage::Image m_moveResizeCursor;
WaylandCursorImage::Image m_windowSelectionCursor;
QHash<CursorShape, WaylandCursorImage::Image> m_cursors;
QHash<QByteArray, WaylandCursorImage::Image> 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;
};
}

View file

@ -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<QMetaObject::Connection> 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)

View file

@ -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)) {

View file

@ -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);

View file

@ -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) {

View file

@ -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

View file

@ -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<xcb_grab_pointer_reply_t> pointerGrab(xcb_grab_pointer_reply(connection(), cookie, nullptr));
if (!pointerGrab.isNull() && pointerGrab->status == XCB_GRAB_STATUS_SUCCESS) {
has_grab = true;

View file

@ -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)