Rewrite wl_pointer implementation with new approach
With this design, a single PointerInterface manages multiple wl_pointer objects. This makes the API tidier and allows implementing things such as keyboard grabs more easier. In addition to that, the PointerInterface doesn't inject its own frame events anymore. It's up to the compositor to decide when it has to be sent. However, the PointerInterface may still send a frame event if the pointer focus changes. Besides re-writing the pointer interface, this change, unfortunately, also affects the implementation of pointer-gestures and relative-pointer protocols because previously they were coupled to individual instances of PointerInterface.
This commit is contained in:
parent
eb123a40b7
commit
178c5d0595
16 changed files with 854 additions and 884 deletions
|
@ -254,12 +254,14 @@ void TestDataDevice::testDrag()
|
|||
if (!hasGrab) {
|
||||
// in case we don't have grab, still generate a pointer serial to make it more interesting
|
||||
m_seatInterface->pointerButtonPressed(Qt::LeftButton);
|
||||
m_seatInterface->pointerFrame();
|
||||
}
|
||||
if (hasPointerFocus) {
|
||||
m_seatInterface->setFocusedPointerSurface(surfaceInterface);
|
||||
}
|
||||
if (hasGrab) {
|
||||
m_seatInterface->pointerButtonPressed(Qt::LeftButton);
|
||||
m_seatInterface->pointerFrame();
|
||||
}
|
||||
|
||||
// TODO: This test would be better, if it could also test that a client trying to guess
|
||||
|
@ -333,12 +335,14 @@ void TestDataDevice::testDragInternally()
|
|||
if (!hasGrab) {
|
||||
// in case we don't have grab, still generate a pointer serial to make it more interesting
|
||||
m_seatInterface->pointerButtonPressed(Qt::LeftButton);
|
||||
m_seatInterface->pointerFrame();
|
||||
}
|
||||
if (hasPointerFocus) {
|
||||
m_seatInterface->setFocusedPointerSurface(surfaceInterface);
|
||||
}
|
||||
if (hasGrab) {
|
||||
m_seatInterface->pointerButtonPressed(Qt::LeftButton);
|
||||
m_seatInterface->pointerFrame();
|
||||
}
|
||||
|
||||
// TODO: This test would be better, if it could also test that a client trying to guess
|
||||
|
|
|
@ -209,6 +209,7 @@ void TestDragAndDrop::testPointerDragAndDrop()
|
|||
m_seatInterface->setFocusedPointerSurface(serverSurface);
|
||||
m_seatInterface->setTimestamp(2);
|
||||
m_seatInterface->pointerButtonPressed(1);
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(buttonPressSpy.wait());
|
||||
QCOMPARE(buttonPressSpy.first().at(1).value<quint32>(), quint32(2));
|
||||
|
||||
|
@ -256,6 +257,7 @@ void TestDragAndDrop::testPointerDragAndDrop()
|
|||
// simulate motion
|
||||
m_seatInterface->setTimestamp(3);
|
||||
m_seatInterface->setPointerPos(QPointF(3, 3));
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(dragMotionSpy.wait());
|
||||
QCOMPARE(dragMotionSpy.count(), 1);
|
||||
QCOMPARE(dragMotionSpy.first().first().toPointF(), QPointF(3, 3));
|
||||
|
@ -268,6 +270,7 @@ void TestDragAndDrop::testPointerDragAndDrop()
|
|||
QVERIFY(droppedSpy.isValid());
|
||||
m_seatInterface->setTimestamp(4);
|
||||
m_seatInterface->pointerButtonReleased(1);
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(sourceDropSpy.isEmpty());
|
||||
QVERIFY(droppedSpy.wait());
|
||||
QCOMPARE(sourceDropSpy.count(), 1);
|
||||
|
@ -405,6 +408,7 @@ void TestDragAndDrop::testDragAndDropWithCancelByDestroyDataSource()
|
|||
m_seatInterface->setFocusedPointerSurface(serverSurface);
|
||||
m_seatInterface->setTimestamp(2);
|
||||
m_seatInterface->pointerButtonPressed(1);
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(buttonPressSpy.wait());
|
||||
QCOMPARE(buttonPressSpy.first().at(1).value<quint32>(), quint32(2));
|
||||
|
||||
|
@ -452,6 +456,7 @@ void TestDragAndDrop::testDragAndDropWithCancelByDestroyDataSource()
|
|||
// simulate motion
|
||||
m_seatInterface->setTimestamp(3);
|
||||
m_seatInterface->setPointerPos(QPointF(3, 3));
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(dragMotionSpy.wait());
|
||||
QCOMPARE(dragMotionSpy.count(), 1);
|
||||
QCOMPARE(dragMotionSpy.first().first().toPointF(), QPointF(3, 3));
|
||||
|
@ -472,6 +477,7 @@ void TestDragAndDrop::testDragAndDropWithCancelByDestroyDataSource()
|
|||
QVERIFY(droppedSpy.isValid());
|
||||
m_seatInterface->setTimestamp(4);
|
||||
m_seatInterface->pointerButtonReleased(1);
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(!droppedSpy.wait(500));
|
||||
|
||||
// verify that we did not get any further input events
|
||||
|
@ -511,7 +517,8 @@ void TestDragAndDrop::testPointerEventsIgnored()
|
|||
m_seatInterface->setTimestamp(timestamp++);
|
||||
m_seatInterface->setPointerPos(QPointF(10, 10));
|
||||
m_seatInterface->setTimestamp(timestamp++);
|
||||
m_seatInterface->pointerAxis(Qt::Vertical, 5);
|
||||
m_seatInterface->pointerAxis(Qt::Vertical, 5, 1, PointerAxisSource::Wheel);
|
||||
m_seatInterface->pointerFrame();
|
||||
// verify that we have those
|
||||
QVERIFY(axisSpy.wait());
|
||||
QCOMPARE(axisSpy.count(), 1);
|
||||
|
@ -523,6 +530,7 @@ void TestDragAndDrop::testPointerEventsIgnored()
|
|||
// let's start the drag
|
||||
m_seatInterface->setTimestamp(timestamp++);
|
||||
m_seatInterface->pointerButtonPressed(1);
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(buttonSpy.wait());
|
||||
QCOMPARE(buttonSpy.count(), 1);
|
||||
m_dataDevice->startDrag(buttonSpy.first().first().value<quint32>(), m_dataSource, s.data());
|
||||
|
@ -531,24 +539,32 @@ void TestDragAndDrop::testPointerEventsIgnored()
|
|||
// now simulate all the possible pointer interactions
|
||||
m_seatInterface->setTimestamp(timestamp++);
|
||||
m_seatInterface->pointerButtonPressed(2);
|
||||
m_seatInterface->pointerFrame();
|
||||
m_seatInterface->setTimestamp(timestamp++);
|
||||
m_seatInterface->pointerButtonReleased(2);
|
||||
m_seatInterface->pointerFrame();
|
||||
m_seatInterface->setTimestamp(timestamp++);
|
||||
m_seatInterface->pointerAxis(Qt::Vertical, 5);
|
||||
m_seatInterface->pointerAxis(Qt::Vertical, 5, 1, PointerAxisSource::Wheel);
|
||||
m_seatInterface->pointerFrame();
|
||||
m_seatInterface->setTimestamp(timestamp++);
|
||||
m_seatInterface->pointerAxis(Qt::Horizontal, 5);
|
||||
m_seatInterface->pointerAxis(Qt::Vertical, 5, 1, PointerAxisSource::Wheel);
|
||||
m_seatInterface->pointerFrame();
|
||||
m_seatInterface->setTimestamp(timestamp++);
|
||||
m_seatInterface->setFocusedPointerSurface(nullptr);
|
||||
m_seatInterface->pointerFrame();
|
||||
m_seatInterface->setTimestamp(timestamp++);
|
||||
m_seatInterface->setFocusedPointerSurface(serverSurface);
|
||||
m_seatInterface->pointerFrame();
|
||||
m_seatInterface->setTimestamp(timestamp++);
|
||||
m_seatInterface->setPointerPos(QPointF(50, 50));
|
||||
m_seatInterface->pointerFrame();
|
||||
|
||||
// last but not least, simulate the drop
|
||||
QSignalSpy cancelledSpy(m_dataSource, &DataSource::cancelled);
|
||||
QVERIFY(cancelledSpy.isValid());
|
||||
m_seatInterface->setTimestamp(timestamp++);
|
||||
m_seatInterface->pointerButtonReleased(1);
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(cancelledSpy.wait());
|
||||
|
||||
// all the changes should have been ignored
|
||||
|
|
|
@ -225,11 +225,13 @@ void TestPointerConstraints::testLockPointer()
|
|||
QSignalSpy pointerMotionSpy(m_pointer, &Pointer::motion);
|
||||
QVERIFY(pointerMotionSpy.isValid());
|
||||
m_seatInterface->setPointerPos(QPoint(0, 1));
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(pointerMotionSpy.wait());
|
||||
|
||||
serverLockedPointer->setLocked(true);
|
||||
QCOMPARE(serverLockedPointer->isLocked(), true);
|
||||
m_seatInterface->setPointerPos(QPoint(1, 1));
|
||||
m_seatInterface->pointerFrame();
|
||||
QCOMPARE(lockedChangedSpy.count(), 1);
|
||||
QCOMPARE(pointerMotionSpy.count(), 1);
|
||||
QVERIFY(lockedSpy.isEmpty());
|
||||
|
@ -257,6 +259,7 @@ void TestPointerConstraints::testLockPointer()
|
|||
|
||||
// now motion should work again
|
||||
m_seatInterface->setPointerPos(QPoint(0, 1));
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(pointerMotionSpy.wait());
|
||||
QCOMPARE(pointerMotionSpy.count(), 2);
|
||||
|
||||
|
|
|
@ -345,16 +345,16 @@ void TestWaylandSeat::testPointer()
|
|||
SurfaceInterface *serverSurface = surfaceCreatedSpy.first().first().value<KWaylandServer::SurfaceInterface*>();
|
||||
QVERIFY(serverSurface);
|
||||
|
||||
QSignalSpy focusedPointerChangedSpy(m_seatInterface, &SeatInterface::focusedPointerChanged);
|
||||
QVERIFY(focusedPointerChangedSpy.isValid());
|
||||
QImage image(QSize(100, 100), QImage::Format_ARGB32_Premultiplied);
|
||||
image.fill(Qt::black);
|
||||
s->attachBuffer(m_shm->createBuffer(image));
|
||||
s->damage(image.rect());
|
||||
s->commit(Surface::CommitFlag::None);
|
||||
QSignalSpy committedSpy(serverSurface, &KWaylandServer::SurfaceInterface::committed);
|
||||
QVERIFY(committedSpy.wait());
|
||||
|
||||
m_seatInterface->setPointerPos(QPoint(20, 18));
|
||||
m_seatInterface->setFocusedPointerSurface(serverSurface, QPoint(10, 15));
|
||||
QCOMPARE(focusedPointerChangedSpy.count(), 1);
|
||||
QVERIFY(!focusedPointerChangedSpy.first().first().value<PointerInterface*>());
|
||||
// no pointer yet
|
||||
QVERIFY(m_seatInterface->focusedPointerSurface());
|
||||
QVERIFY(!m_seatInterface->focusedPointer());
|
||||
|
||||
Pointer *p = m_seat->createPointer(m_seat);
|
||||
QSignalSpy frameSpy(p, &Pointer::frame);
|
||||
|
@ -363,20 +363,10 @@ void TestWaylandSeat::testPointer()
|
|||
QVERIFY(p->isValid());
|
||||
QScopedPointer<RelativePointer> relativePointer(m_relativePointerManager->createRelativePointer(p));
|
||||
QVERIFY(relativePointer->isValid());
|
||||
QSignalSpy pointerCreatedSpy(m_seatInterface, &KWaylandServer::SeatInterface::pointerCreated);
|
||||
QVERIFY(pointerCreatedSpy.isValid());
|
||||
// once the pointer is created it should be set as the focused pointer
|
||||
QVERIFY(pointerCreatedSpy.wait());
|
||||
QVERIFY(m_seatInterface->focusedPointer());
|
||||
QCOMPARE(pointerCreatedSpy.first().first().value<PointerInterface*>(), m_seatInterface->focusedPointer());
|
||||
QCOMPARE(focusedPointerChangedSpy.count(), 2);
|
||||
QCOMPARE(focusedPointerChangedSpy.last().first().value<PointerInterface*>(), m_seatInterface->focusedPointer());
|
||||
QVERIFY(frameSpy.wait());
|
||||
QCOMPARE(frameSpy.count(), 1);
|
||||
|
||||
m_seatInterface->setFocusedPointerSurface(nullptr);
|
||||
QCOMPARE(focusedPointerChangedSpy.count(), 3);
|
||||
QVERIFY(!focusedPointerChangedSpy.last().first().value<PointerInterface*>());
|
||||
serverSurface->client()->flush();
|
||||
QVERIFY(frameSpy.wait());
|
||||
QCOMPARE(frameSpy.count(), 2);
|
||||
|
@ -407,16 +397,13 @@ void TestWaylandSeat::testPointer()
|
|||
QCOMPARE(enteredSpy.first().first().value<quint32>(), m_display->serial());
|
||||
QCOMPARE(enteredSpy.first().last().toPoint(), QPoint(10, 3));
|
||||
QCOMPARE(frameSpy.count(), 3);
|
||||
PointerInterface *serverPointer = m_seatInterface->focusedPointer();
|
||||
QVERIFY(serverPointer);
|
||||
QCOMPARE(p->enteredSurface(), s);
|
||||
QCOMPARE(cp.enteredSurface(), s);
|
||||
QCOMPARE(focusedPointerChangedSpy.count(), 4);
|
||||
QCOMPARE(focusedPointerChangedSpy.last().first().value<PointerInterface*>(), serverPointer);
|
||||
|
||||
// test motion
|
||||
m_seatInterface->setTimestamp(1);
|
||||
m_seatInterface->setPointerPos(QPoint(10, 16));
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(motionSpy.wait());
|
||||
QCOMPARE(frameSpy.count(), 4);
|
||||
QCOMPARE(motionSpy.first().first().toPoint(), QPoint(0, 1));
|
||||
|
@ -424,6 +411,7 @@ void TestWaylandSeat::testPointer()
|
|||
|
||||
// test relative motion
|
||||
m_seatInterface->relativePointerMotion(QSizeF(1, 2), QSizeF(3, 4), quint64(-1));
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(relativeMotionSpy.wait());
|
||||
QCOMPARE(relativeMotionSpy.count(), 1);
|
||||
QCOMPARE(frameSpy.count(), 5);
|
||||
|
@ -433,11 +421,13 @@ void TestWaylandSeat::testPointer()
|
|||
|
||||
// test axis
|
||||
m_seatInterface->setTimestamp(2);
|
||||
m_seatInterface->pointerAxis(Qt::Horizontal, 10);
|
||||
m_seatInterface->pointerAxis(Qt::Horizontal, 10, 1, PointerAxisSource::Wheel);
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(axisSpy.wait());
|
||||
QCOMPARE(frameSpy.count(), 6);
|
||||
m_seatInterface->setTimestamp(3);
|
||||
m_seatInterface->pointerAxis(Qt::Vertical, 20);
|
||||
m_seatInterface->pointerAxis(Qt::Vertical, 20, 2, PointerAxisSource::Wheel);
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(axisSpy.wait());
|
||||
QCOMPARE(frameSpy.count(), 7);
|
||||
QCOMPARE(axisSpy.first().at(0).value<quint32>(), quint32(2));
|
||||
|
@ -451,21 +441,25 @@ void TestWaylandSeat::testPointer()
|
|||
// test button
|
||||
m_seatInterface->setTimestamp(4);
|
||||
m_seatInterface->pointerButtonPressed(1);
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(buttonSpy.wait());
|
||||
QCOMPARE(frameSpy.count(), 8);
|
||||
QCOMPARE(buttonSpy.at(0).at(0).value<quint32>(), m_display->serial());
|
||||
m_seatInterface->setTimestamp(5);
|
||||
m_seatInterface->pointerButtonPressed(2);
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(buttonSpy.wait());
|
||||
QCOMPARE(frameSpy.count(), 9);
|
||||
QCOMPARE(buttonSpy.at(1).at(0).value<quint32>(), m_display->serial());
|
||||
m_seatInterface->setTimestamp(6);
|
||||
m_seatInterface->pointerButtonReleased(2);
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(buttonSpy.wait());
|
||||
QCOMPARE(frameSpy.count(), 10);
|
||||
QCOMPARE(buttonSpy.at(2).at(0).value<quint32>(), m_display->serial());
|
||||
m_seatInterface->setTimestamp(7);
|
||||
m_seatInterface->pointerButtonReleased(1);
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(buttonSpy.wait());
|
||||
QCOMPARE(frameSpy.count(), 11);
|
||||
QCOMPARE(buttonSpy.count(), 4);
|
||||
|
@ -498,7 +492,6 @@ void TestWaylandSeat::testPointer()
|
|||
|
||||
// leave the surface
|
||||
m_seatInterface->setFocusedPointerSurface(nullptr);
|
||||
QCOMPARE(focusedPointerChangedSpy.count(), 5);
|
||||
QVERIFY(leftSpy.wait());
|
||||
QCOMPARE(frameSpy.count(), 12);
|
||||
QCOMPARE(leftSpy.first().first().value<quint32>(), m_display->serial());
|
||||
|
@ -511,7 +504,6 @@ void TestWaylandSeat::testPointer()
|
|||
|
||||
// enter it again
|
||||
m_seatInterface->setFocusedPointerSurface(serverSurface, QPoint(0, 0));
|
||||
QCOMPARE(focusedPointerChangedSpy.count(), 6);
|
||||
QVERIFY(enteredSpy.wait());
|
||||
QCOMPARE(frameSpy.count(), 13);
|
||||
QCOMPARE(p->enteredSurface(), s);
|
||||
|
@ -524,62 +516,6 @@ void TestWaylandSeat::testPointer()
|
|||
QCOMPARE(relativeMotionSpy.last().at(0).toSizeF(), QSizeF(4, 5));
|
||||
QCOMPARE(relativeMotionSpy.last().at(1).toSizeF(), QSizeF(6, 7));
|
||||
QCOMPARE(relativeMotionSpy.last().at(2).value<quint64>(), quint64(1));
|
||||
|
||||
// destroy the focused pointer
|
||||
QSignalSpy unboundSpy(serverPointer, &Resource::unbound);
|
||||
QVERIFY(unboundSpy.isValid());
|
||||
QSignalSpy destroyedSpy(serverPointer, &Resource::destroyed);
|
||||
QVERIFY(destroyedSpy.isValid());
|
||||
delete p;
|
||||
QVERIFY(unboundSpy.wait());
|
||||
QCOMPARE(unboundSpy.count(), 1);
|
||||
QCOMPARE(destroyedSpy.count(), 0);
|
||||
// now test that calling into the methods in Seat does not crash
|
||||
QCOMPARE(m_seatInterface->focusedPointer(), serverPointer);
|
||||
QCOMPARE(m_seatInterface->focusedPointerSurface(), serverSurface);
|
||||
m_seatInterface->setTimestamp(8);
|
||||
m_seatInterface->setPointerPos(QPoint(10, 15));
|
||||
m_seatInterface->setTimestamp(9);
|
||||
m_seatInterface->pointerButtonPressed(1);
|
||||
m_seatInterface->setTimestamp(10);
|
||||
m_seatInterface->pointerButtonReleased(1);
|
||||
m_seatInterface->setTimestamp(11);
|
||||
m_seatInterface->pointerAxis(Qt::Horizontal, 10);
|
||||
m_seatInterface->setTimestamp(12);
|
||||
m_seatInterface->pointerAxis(Qt::Vertical, 20);
|
||||
m_seatInterface->setFocusedPointerSurface(nullptr);
|
||||
QCOMPARE(focusedPointerChangedSpy.count(), 7);
|
||||
m_seatInterface->setFocusedPointerSurface(serverSurface);
|
||||
QCOMPARE(focusedPointerChangedSpy.count(), 8);
|
||||
QCOMPARE(m_seatInterface->focusedPointerSurface(), serverSurface);
|
||||
QVERIFY(!m_seatInterface->focusedPointer());
|
||||
|
||||
// and now destroy
|
||||
QVERIFY(destroyedSpy.wait());
|
||||
QCOMPARE(unboundSpy.count(), 1);
|
||||
QCOMPARE(destroyedSpy.count(), 1);
|
||||
QCOMPARE(m_seatInterface->focusedPointerSurface(), serverSurface);
|
||||
QVERIFY(!m_seatInterface->focusedPointer());
|
||||
|
||||
// create a pointer again
|
||||
p = m_seat->createPointer(m_seat);
|
||||
QVERIFY(focusedPointerChangedSpy.wait());
|
||||
QCOMPARE(focusedPointerChangedSpy.count(), 9);
|
||||
QCOMPARE(m_seatInterface->focusedPointerSurface(), serverSurface);
|
||||
serverPointer = m_seatInterface->focusedPointer();
|
||||
QVERIFY(serverPointer);
|
||||
|
||||
QSignalSpy entered2Spy(p, &Pointer::entered);
|
||||
QVERIFY(entered2Spy.wait());
|
||||
QCOMPARE(p->enteredSurface(), s);
|
||||
QSignalSpy leftSpy2(p, &Pointer::left);
|
||||
QVERIFY(leftSpy2.isValid());
|
||||
delete s;
|
||||
QVERIFY(!p->enteredSurface());
|
||||
QVERIFY(leftSpy2.wait());
|
||||
QCOMPARE(focusedPointerChangedSpy.count(), 10);
|
||||
QVERIFY(!m_seatInterface->focusedPointerSurface());
|
||||
QVERIFY(!m_seatInterface->focusedPointer());
|
||||
}
|
||||
|
||||
void TestWaylandSeat::testPointerTransformation_data()
|
||||
|
@ -618,23 +554,26 @@ void TestWaylandSeat::testPointerTransformation()
|
|||
SurfaceInterface *serverSurface = surfaceCreatedSpy.first().first().value<KWaylandServer::SurfaceInterface*>();
|
||||
QVERIFY(serverSurface);
|
||||
|
||||
QImage image(QSize(100, 100), QImage::Format_ARGB32_Premultiplied);
|
||||
image.fill(Qt::black);
|
||||
s->attachBuffer(m_shm->createBuffer(image));
|
||||
s->damage(image.rect());
|
||||
s->commit(Surface::CommitFlag::None);
|
||||
QSignalSpy committedSpy(serverSurface, &KWaylandServer::SurfaceInterface::committed);
|
||||
QVERIFY(committedSpy.wait());
|
||||
|
||||
m_seatInterface->setPointerPos(QPoint(20, 18));
|
||||
QFETCH(QMatrix4x4, enterTransformation);
|
||||
m_seatInterface->setFocusedPointerSurface(serverSurface, enterTransformation);
|
||||
QCOMPARE(m_seatInterface->focusedPointerSurfaceTransformation(), enterTransformation);
|
||||
// no pointer yet
|
||||
QVERIFY(m_seatInterface->focusedPointerSurface());
|
||||
QVERIFY(!m_seatInterface->focusedPointer());
|
||||
|
||||
Pointer *p = m_seat->createPointer(m_seat);
|
||||
const Pointer &cp = *p;
|
||||
QVERIFY(p->isValid());
|
||||
QSignalSpy pointerCreatedSpy(m_seatInterface, &SeatInterface::pointerCreated);
|
||||
QVERIFY(pointerCreatedSpy.isValid());
|
||||
// once the pointer is created it should be set as the focused pointer
|
||||
QVERIFY(pointerCreatedSpy.wait());
|
||||
QVERIFY(m_seatInterface->focusedPointer());
|
||||
QCOMPARE(pointerCreatedSpy.first().first().value<PointerInterface*>(), m_seatInterface->focusedPointer());
|
||||
QSignalSpy frameSpy(p, &Pointer::frame);
|
||||
QVERIFY(frameSpy.wait());
|
||||
const Pointer &cp = *p;
|
||||
|
||||
m_seatInterface->setFocusedPointerSurface(nullptr);
|
||||
serverSurface->client()->flush();
|
||||
|
@ -656,14 +595,13 @@ void TestWaylandSeat::testPointerTransformation()
|
|||
QVERIFY(enteredSpy.wait());
|
||||
QCOMPARE(enteredSpy.first().first().value<quint32>(), m_display->serial());
|
||||
QTEST(enteredSpy.first().last().toPointF(), "expectedEnterPoint");
|
||||
PointerInterface *serverPointer = m_seatInterface->focusedPointer();
|
||||
QVERIFY(serverPointer);
|
||||
QCOMPARE(p->enteredSurface(), s);
|
||||
QCOMPARE(cp.enteredSurface(), s);
|
||||
|
||||
// test motion
|
||||
m_seatInterface->setTimestamp(1);
|
||||
m_seatInterface->setPointerPos(QPoint(10, 16));
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(motionSpy.wait());
|
||||
QTEST(motionSpy.first().first().toPointF(), "expectedMovePoint");
|
||||
QCOMPARE(motionSpy.first().last().value<quint32>(), quint32(1));
|
||||
|
@ -730,11 +668,19 @@ void TestWaylandSeat::testPointerButton()
|
|||
|
||||
QSignalSpy surfaceCreatedSpy(m_compositorInterface, &KWaylandServer::CompositorInterface::surfaceCreated);
|
||||
QVERIFY(surfaceCreatedSpy.isValid());
|
||||
m_compositor->createSurface(m_compositor);
|
||||
KWayland::Client::Surface *s = m_compositor->createSurface(m_compositor);
|
||||
QVERIFY(surfaceCreatedSpy.wait());
|
||||
SurfaceInterface *serverSurface = surfaceCreatedSpy.first().first().value<KWaylandServer::SurfaceInterface*>();
|
||||
QVERIFY(serverSurface);
|
||||
|
||||
QImage image(QSize(100, 100), QImage::Format_ARGB32_Premultiplied);
|
||||
image.fill(Qt::black);
|
||||
s->attachBuffer(m_shm->createBuffer(image));
|
||||
s->damage(image.rect());
|
||||
s->commit(Surface::CommitFlag::None);
|
||||
QSignalSpy committedSpy(serverSurface, &KWaylandServer::SurfaceInterface::committed);
|
||||
QVERIFY(committedSpy.wait());
|
||||
|
||||
QScopedPointer<Pointer> p(m_seat->createPointer());
|
||||
QVERIFY(p->isValid());
|
||||
QSignalSpy buttonChangedSpy(p.data(), &KWayland::Client::Pointer::buttonStateChanged);
|
||||
|
@ -745,13 +691,10 @@ void TestWaylandSeat::testPointerButton()
|
|||
m_seatInterface->setPointerPos(QPoint(20, 18));
|
||||
m_seatInterface->setFocusedPointerSurface(serverSurface, QPoint(10, 15));
|
||||
QVERIFY(m_seatInterface->focusedPointerSurface());
|
||||
QVERIFY(m_seatInterface->focusedPointer());
|
||||
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
m_seatInterface->setFocusedPointerSurface(serverSurface, QPoint(10, 15));
|
||||
PointerInterface *serverPointer = m_seatInterface->focusedPointer();
|
||||
QVERIFY(serverPointer);
|
||||
QFETCH(Qt::MouseButton, qtButton);
|
||||
QFETCH(quint32, waylandButton);
|
||||
quint32 msec = QDateTime::currentMSecsSinceEpoch();
|
||||
|
@ -759,6 +702,7 @@ void TestWaylandSeat::testPointerButton()
|
|||
QCOMPARE(m_seatInterface->isPointerButtonPressed(qtButton), false);
|
||||
m_seatInterface->setTimestamp(msec);
|
||||
m_seatInterface->pointerButtonPressed(qtButton);
|
||||
m_seatInterface->pointerFrame();
|
||||
QCOMPARE(m_seatInterface->isPointerButtonPressed(waylandButton), true);
|
||||
QCOMPARE(m_seatInterface->isPointerButtonPressed(qtButton), true);
|
||||
QVERIFY(buttonChangedSpy.wait());
|
||||
|
@ -771,6 +715,7 @@ void TestWaylandSeat::testPointerButton()
|
|||
msec = QDateTime::currentMSecsSinceEpoch();
|
||||
m_seatInterface->setTimestamp(QDateTime::currentMSecsSinceEpoch());
|
||||
m_seatInterface->pointerButtonReleased(qtButton);
|
||||
m_seatInterface->pointerFrame();
|
||||
QCOMPARE(m_seatInterface->isPointerButtonPressed(waylandButton), false);
|
||||
QCOMPARE(m_seatInterface->isPointerButtonPressed(qtButton), false);
|
||||
QVERIFY(buttonChangedSpy.wait());
|
||||
|
@ -847,6 +792,7 @@ void TestWaylandSeat::testPointerSubSurfaceTree()
|
|||
// a motion on grandchild2
|
||||
m_seatInterface->setTimestamp(timestamp++);
|
||||
m_seatInterface->setPointerPos(QPointF(25, 60));
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(motionSpy.wait());
|
||||
QCOMPARE(enteredSpy.count(), 1);
|
||||
QCOMPARE(leftSpy.count(), 0);
|
||||
|
@ -855,10 +801,11 @@ void TestWaylandSeat::testPointerSubSurfaceTree()
|
|||
// motion which changes to childSurface
|
||||
m_seatInterface->setTimestamp(timestamp++);
|
||||
m_seatInterface->setPointerPos(QPointF(25, 80));
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(enteredSpy.wait());
|
||||
QCOMPARE(enteredSpy.count(), 2);
|
||||
QCOMPARE(leftSpy.count(), 1);
|
||||
QCOMPARE(motionSpy.count(), 1);
|
||||
QCOMPARE(motionSpy.count(), 2);
|
||||
QCOMPARE(enteredSpy.last().last().toPointF(), QPointF(25, 80));
|
||||
QCOMPARE(pointer->enteredSurface(), childSurface.data());
|
||||
// a leave for the whole surface
|
||||
|
@ -867,7 +814,7 @@ void TestWaylandSeat::testPointerSubSurfaceTree()
|
|||
QVERIFY(leftSpy.wait());
|
||||
QCOMPARE(enteredSpy.count(), 2);
|
||||
QCOMPARE(leftSpy.count(), 2);
|
||||
QCOMPARE(motionSpy.count(), 1);
|
||||
QCOMPARE(motionSpy.count(), 2);
|
||||
// a new enter on the main surface
|
||||
m_seatInterface->setTimestamp(timestamp++);
|
||||
m_seatInterface->setPointerPos(QPointF(75, 50));
|
||||
|
@ -875,7 +822,7 @@ void TestWaylandSeat::testPointerSubSurfaceTree()
|
|||
QVERIFY(enteredSpy.wait());
|
||||
QCOMPARE(enteredSpy.count(), 3);
|
||||
QCOMPARE(leftSpy.count(), 2);
|
||||
QCOMPARE(motionSpy.count(), 1);
|
||||
QCOMPARE(motionSpy.count(), 2);
|
||||
QCOMPARE(enteredSpy.last().last().toPointF(), QPointF(75, 50));
|
||||
QCOMPARE(pointer->enteredSurface(), parentSurface.data());
|
||||
}
|
||||
|
@ -923,9 +870,18 @@ void TestWaylandSeat::testPointerSwipeGesture()
|
|||
QVERIFY(surfaceCreatedSpy.wait());
|
||||
auto serverSurface = surfaceCreatedSpy.first().first().value<SurfaceInterface*>();
|
||||
QVERIFY(serverSurface);
|
||||
|
||||
QImage image(QSize(100, 100), QImage::Format_ARGB32_Premultiplied);
|
||||
image.fill(Qt::black);
|
||||
surface->attachBuffer(m_shm->createBuffer(image));
|
||||
surface->damage(image.rect());
|
||||
surface->commit(Surface::CommitFlag::None);
|
||||
QSignalSpy committedSpy(serverSurface, &KWaylandServer::SurfaceInterface::committed);
|
||||
QVERIFY(committedSpy.wait());
|
||||
|
||||
m_seatInterface->setFocusedPointerSurface(serverSurface);
|
||||
QCOMPARE(m_seatInterface->focusedPointerSurface(), serverSurface);
|
||||
QVERIFY(m_seatInterface->focusedPointer());
|
||||
QVERIFY(m_seatInterface->pointer());
|
||||
|
||||
// send in the start
|
||||
quint32 timestamp = 1;
|
||||
|
@ -1039,9 +995,18 @@ void TestWaylandSeat::testPointerPinchGesture()
|
|||
QVERIFY(surfaceCreatedSpy.wait());
|
||||
auto serverSurface = surfaceCreatedSpy.first().first().value<SurfaceInterface*>();
|
||||
QVERIFY(serverSurface);
|
||||
|
||||
QImage image(QSize(100, 100), QImage::Format_ARGB32_Premultiplied);
|
||||
image.fill(Qt::black);
|
||||
surface->attachBuffer(m_shm->createBuffer(image));
|
||||
surface->damage(image.rect());
|
||||
surface->commit(Surface::CommitFlag::None);
|
||||
QSignalSpy committedSpy(serverSurface, &KWaylandServer::SurfaceInterface::committed);
|
||||
QVERIFY(committedSpy.wait());
|
||||
|
||||
m_seatInterface->setFocusedPointerSurface(serverSurface);
|
||||
QCOMPARE(m_seatInterface->focusedPointerSurface(), serverSurface);
|
||||
QVERIFY(m_seatInterface->focusedPointer());
|
||||
QVERIFY(m_seatInterface->pointer());
|
||||
|
||||
// send in the start
|
||||
quint32 timestamp = 1;
|
||||
|
@ -1136,9 +1101,17 @@ void TestWaylandSeat::testPointerAxis()
|
|||
QVERIFY(surfaceCreatedSpy.wait());
|
||||
auto serverSurface = surfaceCreatedSpy.first().first().value<SurfaceInterface*>();
|
||||
QVERIFY(serverSurface);
|
||||
|
||||
QImage image(QSize(100, 100), QImage::Format_ARGB32_Premultiplied);
|
||||
image.fill(Qt::black);
|
||||
surface->attachBuffer(m_shm->createBuffer(image));
|
||||
surface->damage(image.rect());
|
||||
surface->commit(Surface::CommitFlag::None);
|
||||
QSignalSpy committedSpy(serverSurface, &KWaylandServer::SurfaceInterface::committed);
|
||||
QVERIFY(committedSpy.wait());
|
||||
|
||||
m_seatInterface->setFocusedPointerSurface(serverSurface);
|
||||
QCOMPARE(m_seatInterface->focusedPointerSurface(), serverSurface);
|
||||
QVERIFY(m_seatInterface->focusedPointer());
|
||||
QSignalSpy frameSpy(pointer.data(), &Pointer::frame);
|
||||
QVERIFY(frameSpy.isValid());
|
||||
QVERIFY(frameSpy.wait());
|
||||
|
@ -1156,7 +1129,8 @@ void TestWaylandSeat::testPointerAxis()
|
|||
|
||||
quint32 timestamp = 1;
|
||||
m_seatInterface->setTimestamp(timestamp++);
|
||||
m_seatInterface->pointerAxisV5(Qt::Vertical, 10, 1, PointerAxisSource::Wheel);
|
||||
m_seatInterface->pointerAxis(Qt::Vertical, 10, 1, PointerAxisSource::Wheel);
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(frameSpy.wait());
|
||||
QCOMPARE(frameSpy.count(), 2);
|
||||
QCOMPARE(axisSourceSpy.count(), 1);
|
||||
|
@ -1172,7 +1146,8 @@ void TestWaylandSeat::testPointerAxis()
|
|||
|
||||
// let's scroll using fingers
|
||||
m_seatInterface->setTimestamp(timestamp++);
|
||||
m_seatInterface->pointerAxisV5(Qt::Horizontal, 42, 0, PointerAxisSource::Finger);
|
||||
m_seatInterface->pointerAxis(Qt::Horizontal, 42, 0, PointerAxisSource::Finger);
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(frameSpy.wait());
|
||||
QCOMPARE(frameSpy.count(), 3);
|
||||
QCOMPARE(axisSourceSpy.count(), 2);
|
||||
|
@ -1186,7 +1161,8 @@ void TestWaylandSeat::testPointerAxis()
|
|||
|
||||
// lift the fingers off the device
|
||||
m_seatInterface->setTimestamp(timestamp++);
|
||||
m_seatInterface->pointerAxisV5(Qt::Horizontal, 0, 0, PointerAxisSource::Finger);
|
||||
m_seatInterface->pointerAxis(Qt::Horizontal, 0, 0, PointerAxisSource::Finger);
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(frameSpy.wait());
|
||||
QCOMPARE(frameSpy.count(), 4);
|
||||
QCOMPARE(axisSourceSpy.count(), 3);
|
||||
|
@ -1199,7 +1175,8 @@ void TestWaylandSeat::testPointerAxis()
|
|||
|
||||
// if the device is unknown, no axis_source event should be sent
|
||||
m_seatInterface->setTimestamp(timestamp++);
|
||||
m_seatInterface->pointerAxisV5(Qt::Horizontal, 42, 1, PointerAxisSource::Unknown);
|
||||
m_seatInterface->pointerAxis(Qt::Horizontal, 42, 1, PointerAxisSource::Unknown);
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(frameSpy.wait());
|
||||
QCOMPARE(frameSpy.count(), 5);
|
||||
QCOMPARE(axisSourceSpy.count(), 3);
|
||||
|
@ -1291,8 +1268,10 @@ void TestWaylandSeat::testKeyboardSubSurfaceTreeFromPointer()
|
|||
// let's click
|
||||
m_seatInterface->setTimestamp(timestamp++);
|
||||
m_seatInterface->pointerButtonPressed(Qt::LeftButton);
|
||||
m_seatInterface->pointerFrame();
|
||||
m_seatInterface->setTimestamp(timestamp++);
|
||||
m_seatInterface->pointerButtonReleased(Qt::LeftButton);
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(enterSpy.wait());
|
||||
QCOMPARE(enterSpy.count(), 2);
|
||||
QCOMPARE(leftSpy.count(), 1);
|
||||
|
@ -1301,8 +1280,10 @@ void TestWaylandSeat::testKeyboardSubSurfaceTreeFromPointer()
|
|||
// click on same surface should not trigger another enter
|
||||
m_seatInterface->setTimestamp(timestamp++);
|
||||
m_seatInterface->pointerButtonPressed(Qt::LeftButton);
|
||||
m_seatInterface->pointerFrame();
|
||||
m_seatInterface->setTimestamp(timestamp++);
|
||||
m_seatInterface->pointerButtonReleased(Qt::LeftButton);
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(!enterSpy.wait(200));
|
||||
QCOMPARE(enterSpy.count(), 2);
|
||||
QCOMPARE(leftSpy.count(), 1);
|
||||
|
@ -1310,6 +1291,7 @@ void TestWaylandSeat::testKeyboardSubSurfaceTreeFromPointer()
|
|||
|
||||
// unfocus keyboard
|
||||
m_seatInterface->setFocusedKeyboardSurface(nullptr);
|
||||
m_seatInterface->pointerFrame();
|
||||
QVERIFY(leftSpy.wait());
|
||||
QCOMPARE(enterSpy.count(), 2);
|
||||
QCOMPARE(leftSpy.count(), 2);
|
||||
|
@ -1327,11 +1309,19 @@ void TestWaylandSeat::testCursor()
|
|||
|
||||
QSignalSpy surfaceCreatedSpy(m_compositorInterface, &KWaylandServer::CompositorInterface::surfaceCreated);
|
||||
QVERIFY(surfaceCreatedSpy.isValid());
|
||||
m_compositor->createSurface(m_compositor);
|
||||
KWayland::Client::Surface *surface = m_compositor->createSurface(m_compositor);
|
||||
QVERIFY(surfaceCreatedSpy.wait());
|
||||
SurfaceInterface *serverSurface = surfaceCreatedSpy.first().first().value<KWaylandServer::SurfaceInterface*>();
|
||||
QVERIFY(serverSurface);
|
||||
|
||||
QImage image(QSize(100, 100), QImage::Format_ARGB32_Premultiplied);
|
||||
image.fill(Qt::black);
|
||||
surface->attachBuffer(m_shm->createBuffer(image));
|
||||
surface->damage(image.rect());
|
||||
surface->commit(Surface::CommitFlag::None);
|
||||
QSignalSpy committedSpy(serverSurface, &KWaylandServer::SurfaceInterface::committed);
|
||||
QVERIFY(committedSpy.wait());
|
||||
|
||||
QScopedPointer<Pointer> p(m_seat->createPointer());
|
||||
QVERIFY(p->isValid());
|
||||
wl_display_flush(m_connection->display());
|
||||
|
@ -1346,21 +1336,20 @@ void TestWaylandSeat::testCursor()
|
|||
QVERIFY(enteredSpy.wait());
|
||||
QCOMPARE(enteredSpy.first().first().value<quint32>(), serial);
|
||||
QVERIFY(m_seatInterface->focusedPointerSurface());
|
||||
QVERIFY(m_seatInterface->focusedPointer());
|
||||
QVERIFY(!m_seatInterface->focusedPointer()->cursor());
|
||||
QVERIFY(!m_seatInterface->pointer()->cursor());
|
||||
|
||||
QSignalSpy cursorChangedSpy(m_seatInterface->focusedPointer(), &KWaylandServer::PointerInterface::cursorChanged);
|
||||
QSignalSpy cursorChangedSpy(m_seatInterface->pointer(), &KWaylandServer::PointerInterface::cursorChanged);
|
||||
QVERIFY(cursorChangedSpy.isValid());
|
||||
// just remove the pointer
|
||||
p->setCursor(nullptr);
|
||||
QVERIFY(cursorChangedSpy.wait());
|
||||
QCOMPARE(cursorChangedSpy.count(), 1);
|
||||
auto cursor = m_seatInterface->focusedPointer()->cursor();
|
||||
auto cursor = m_seatInterface->pointer()->cursor();
|
||||
QVERIFY(cursor);
|
||||
QVERIFY(!cursor->surface());
|
||||
QCOMPARE(cursor->hotspot(), QPoint());
|
||||
QCOMPARE(cursor->enteredSerial(), serial);
|
||||
QCOMPARE(cursor->pointer(), m_seatInterface->focusedPointer());
|
||||
QCOMPARE(cursor->pointer(), m_seatInterface->pointer());
|
||||
|
||||
QSignalSpy hotspotChangedSpy(cursor, &KWaylandServer::Cursor::hotspotChanged);
|
||||
QVERIFY(hotspotChangedSpy.isValid());
|
||||
|
@ -1443,17 +1432,25 @@ void TestWaylandSeat::testCursorDamage()
|
|||
// create surface
|
||||
QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
|
||||
QVERIFY(surfaceCreatedSpy.isValid());
|
||||
m_compositor->createSurface(m_compositor);
|
||||
KWayland::Client::Surface *surface = m_compositor->createSurface(m_compositor);
|
||||
QVERIFY(surfaceCreatedSpy.wait());
|
||||
SurfaceInterface *serverSurface = surfaceCreatedSpy.first().first().value<KWaylandServer::SurfaceInterface*>();
|
||||
QVERIFY(serverSurface);
|
||||
|
||||
QImage image(QSize(100, 100), QImage::Format_ARGB32_Premultiplied);
|
||||
image.fill(Qt::black);
|
||||
surface->attachBuffer(m_shm->createBuffer(image));
|
||||
surface->damage(image.rect());
|
||||
surface->commit(Surface::CommitFlag::None);
|
||||
QSignalSpy committedSpy(serverSurface, &KWaylandServer::SurfaceInterface::committed);
|
||||
QVERIFY(committedSpy.wait());
|
||||
|
||||
// send enter to the surface
|
||||
m_seatInterface->setFocusedPointerSurface(serverSurface);
|
||||
QVERIFY(enteredSpy.wait());
|
||||
|
||||
// create a signal spy for the cursor changed signal
|
||||
auto pointer = m_seatInterface->focusedPointer();
|
||||
auto pointer = m_seatInterface->pointer();
|
||||
QSignalSpy cursorChangedSpy(pointer, &PointerInterface::cursorChanged);
|
||||
QVERIFY(cursorChangedSpy.isValid());
|
||||
|
||||
|
@ -2167,14 +2164,11 @@ void TestWaylandSeat::testDisconnect()
|
|||
using namespace KWaylandServer;
|
||||
QSignalSpy keyboardCreatedSpy(m_seatInterface, &SeatInterface::keyboardCreated);
|
||||
QVERIFY(keyboardCreatedSpy.isValid());
|
||||
QSignalSpy pointerCreatedSpy(m_seatInterface, &SeatInterface::pointerCreated);
|
||||
QVERIFY(pointerCreatedSpy.isValid());
|
||||
QSignalSpy touchCreatedSpy(m_seatInterface, &SeatInterface::touchCreated);
|
||||
QVERIFY(touchCreatedSpy.isValid());
|
||||
|
||||
// create the things we need
|
||||
m_seatInterface->setHasKeyboard(true);
|
||||
m_seatInterface->setHasPointer(true);
|
||||
m_seatInterface->setHasTouch(true);
|
||||
QSignalSpy touchSpy(m_seat, &Seat::hasTouchChanged);
|
||||
QVERIFY(touchSpy.isValid());
|
||||
|
@ -2186,12 +2180,6 @@ void TestWaylandSeat::testDisconnect()
|
|||
auto serverKeyboard = keyboardCreatedSpy.first().first().value<KeyboardInterface*>();
|
||||
QVERIFY(serverKeyboard);
|
||||
|
||||
QScopedPointer<Pointer> pointer(m_seat->createPointer());
|
||||
QVERIFY(!pointer.isNull());
|
||||
QVERIFY(pointerCreatedSpy.wait());
|
||||
auto serverPointer = pointerCreatedSpy.first().first().value<PointerInterface*>();
|
||||
QVERIFY(serverPointer);
|
||||
|
||||
QScopedPointer<Touch> touch(m_seat->createTouch());
|
||||
QVERIFY(!touch.isNull());
|
||||
QVERIFY(touchCreatedSpy.wait());
|
||||
|
@ -2201,8 +2189,6 @@ void TestWaylandSeat::testDisconnect()
|
|||
// setup destroys
|
||||
QSignalSpy keyboardDestroyedSpy(serverKeyboard, &QObject::destroyed);
|
||||
QVERIFY(keyboardDestroyedSpy.isValid());
|
||||
QSignalSpy pointerDestroyedSpy(serverPointer, &QObject::destroyed);
|
||||
QVERIFY(pointerDestroyedSpy.isValid());
|
||||
QSignalSpy touchDestroyedSpy(serverTouch, &QObject::destroyed);
|
||||
QVERIFY(touchDestroyedSpy.isValid());
|
||||
|
||||
|
@ -2212,7 +2198,6 @@ void TestWaylandSeat::testDisconnect()
|
|||
}
|
||||
|
||||
keyboard->destroy();
|
||||
pointer->destroy();
|
||||
touch->destroy();
|
||||
m_relativePointerManager->destroy();
|
||||
m_pointerGestures->destroy();
|
||||
|
|
|
@ -102,8 +102,7 @@ void TestWaylandServerSeat::testPointerButton()
|
|||
display.addSocketName(s_socketName);
|
||||
display.start();
|
||||
SeatInterface *seat = new SeatInterface(&display);
|
||||
PointerInterface *pointer = seat->focusedPointer();
|
||||
QVERIFY(!pointer);
|
||||
seat->setHasPointer(true);
|
||||
|
||||
// no button pressed yet, should be released and no serial
|
||||
QVERIFY(!seat->isPointerButtonPressed(0));
|
||||
|
@ -113,6 +112,7 @@ void TestWaylandServerSeat::testPointerButton()
|
|||
|
||||
// mark the button as pressed
|
||||
seat->pointerButtonPressed(0);
|
||||
seat->pointerFrame();
|
||||
QVERIFY(seat->isPointerButtonPressed(0));
|
||||
QCOMPARE(seat->pointerButtonSerial(0), display.serial());
|
||||
|
||||
|
@ -122,6 +122,7 @@ void TestWaylandServerSeat::testPointerButton()
|
|||
|
||||
// release it again
|
||||
seat->pointerButtonReleased(0);
|
||||
seat->pointerFrame();
|
||||
QVERIFY(!seat->isPointerButtonPressed(0));
|
||||
QCOMPARE(seat->pointerButtonSerial(0), display.serial());
|
||||
}
|
||||
|
@ -132,22 +133,24 @@ void TestWaylandServerSeat::testPointerPos()
|
|||
display.addSocketName(s_socketName);
|
||||
display.start();
|
||||
SeatInterface *seat = new SeatInterface(&display);
|
||||
seat->setHasPointer(true);
|
||||
QSignalSpy seatPosSpy(seat, SIGNAL(pointerPosChanged(QPointF)));
|
||||
QVERIFY(seatPosSpy.isValid());
|
||||
PointerInterface *pointer = seat->focusedPointer();
|
||||
QVERIFY(!pointer);
|
||||
|
||||
QCOMPARE(seat->pointerPos(), QPointF());
|
||||
|
||||
seat->setPointerPos(QPointF(10, 15));
|
||||
seat->pointerFrame();
|
||||
QCOMPARE(seat->pointerPos(), QPointF(10, 15));
|
||||
QCOMPARE(seatPosSpy.count(), 1);
|
||||
QCOMPARE(seatPosSpy.first().first().toPointF(), QPointF(10, 15));
|
||||
|
||||
seat->setPointerPos(QPointF(10, 15));
|
||||
seat->pointerFrame();
|
||||
QCOMPARE(seatPosSpy.count(), 1);
|
||||
|
||||
seat->setPointerPos(QPointF(5, 7));
|
||||
seat->pointerFrame();
|
||||
QCOMPARE(seat->pointerPos(), QPointF(5, 7));
|
||||
QCOMPARE(seatPosSpy.count(), 2);
|
||||
QCOMPARE(seatPosSpy.first().first().toPointF(), QPointF(10, 15));
|
||||
|
|
|
@ -1,411 +1,315 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
|
||||
SPDX-FileCopyrightText: 2020 Adrien Faveraux <ad1rie3@hotmail.fr>
|
||||
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||
*/
|
||||
|
||||
#include "pointer_interface.h"
|
||||
#include "clientconnection.h"
|
||||
#include "display.h"
|
||||
#include "logging.h"
|
||||
#include "pointer_interface_p.h"
|
||||
#include "pointerconstraints_v1_interface.h"
|
||||
#include "pointergestures_v1_interface_p.h"
|
||||
#include "resource_p.h"
|
||||
#include "relativepointer_v1_interface_p.h"
|
||||
#include "seat_interface.h"
|
||||
#include "display.h"
|
||||
#include "subcompositor_interface.h"
|
||||
#include "surface_interface.h"
|
||||
#include "datadevice_interface.h"
|
||||
// Wayland
|
||||
#include <wayland-server.h>
|
||||
#include "surfacerole_p.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace KWaylandServer
|
||||
{
|
||||
|
||||
class Cursor::Private
|
||||
class CursorPrivate
|
||||
{
|
||||
public:
|
||||
Private(Cursor *q, PointerInterface *pointer);
|
||||
CursorPrivate(Cursor *q, PointerInterface *pointer);
|
||||
|
||||
Cursor *q;
|
||||
PointerInterface *pointer;
|
||||
quint32 enteredSerial = 0;
|
||||
QPoint hotspot;
|
||||
QPointer<SurfaceInterface> surface;
|
||||
|
||||
void update(const QPointer<SurfaceInterface> &surface, quint32 serial, const QPoint &hotspot);
|
||||
|
||||
private:
|
||||
Cursor *q;
|
||||
void update(SurfaceInterface *surface, quint32 serial, const QPoint &hotspot);
|
||||
};
|
||||
|
||||
PointerInterface::Private::Private(SeatInterface *parent, wl_resource *parentResource, PointerInterface *q)
|
||||
: Resource::Private(q, parent, parentResource, &wl_pointer_interface, &s_interface)
|
||||
, seat(parent)
|
||||
PointerInterfacePrivate *PointerInterfacePrivate::get(PointerInterface *pointer)
|
||||
{
|
||||
return pointer->d.data();
|
||||
}
|
||||
|
||||
PointerInterfacePrivate::PointerInterfacePrivate(PointerInterface *q, SeatInterface *seat)
|
||||
: q(q)
|
||||
, seat(seat)
|
||||
, relativePointersV1(new RelativePointerV1Interface(q))
|
||||
, swipeGesturesV1(new PointerSwipeGestureV1Interface(q))
|
||||
, pinchGesturesV1(new PointerPinchGestureV1Interface(q))
|
||||
{
|
||||
}
|
||||
|
||||
void PointerInterface::Private::setCursor(quint32 serial, SurfaceInterface *surface, const QPoint &hotspot)
|
||||
PointerInterfacePrivate::~PointerInterfacePrivate()
|
||||
{
|
||||
if (!cursor) {
|
||||
Q_Q(PointerInterface);
|
||||
}
|
||||
|
||||
QList<PointerInterfacePrivate::Resource *> PointerInterfacePrivate::pointersForClient(ClientConnection *client) const
|
||||
{
|
||||
return resourceMap().values(client->client());
|
||||
}
|
||||
|
||||
void PointerInterfacePrivate::pointer_set_cursor(Resource *resource, uint32_t serial,
|
||||
::wl_resource *surface_resource,
|
||||
int32_t hotspot_x, int32_t hotspot_y)
|
||||
{
|
||||
SurfaceInterface *surface = nullptr;
|
||||
|
||||
if (!focusedSurface) {
|
||||
return;
|
||||
}
|
||||
if (focusedSurface->client()->client() != resource->client()) {
|
||||
qCDebug(KWAYLAND_SERVER, "Denied set_cursor request from unfocused client");
|
||||
return;
|
||||
}
|
||||
|
||||
if (surface_resource) {
|
||||
surface = SurfaceInterface::get(surface_resource);
|
||||
if (!surface) {
|
||||
wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"invalid surface");
|
||||
return;
|
||||
}
|
||||
|
||||
const SurfaceRole *surfaceRole = SurfaceRole::get(surface);
|
||||
if (surfaceRole) {
|
||||
wl_resource_post_error(resource->handle, error_role,
|
||||
"the wl_surface already has a role assigned %s",
|
||||
surfaceRole->name().constData());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cursor) { // TODO: Assign the cursor surface role.
|
||||
cursor = new Cursor(q);
|
||||
cursor->d->update(QPointer<SurfaceInterface>(surface), serial, hotspot);
|
||||
cursor->d->update(surface, serial, QPoint(hotspot_x, hotspot_y));
|
||||
QObject::connect(cursor, &Cursor::changed, q, &PointerInterface::cursorChanged);
|
||||
emit q->cursorChanged();
|
||||
} else {
|
||||
cursor->d->update(QPointer<SurfaceInterface>(surface), serial, hotspot);
|
||||
cursor->d->update(surface, serial, QPoint(hotspot_x, hotspot_y));
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInterface::Private::sendLeave(SurfaceInterface *surface, quint32 serial)
|
||||
void PointerInterfacePrivate::pointer_release(Resource *resource)
|
||||
{
|
||||
if (!surface) {
|
||||
return;
|
||||
}
|
||||
if (resource && surface->resource()) {
|
||||
wl_pointer_send_leave(resource, serial, surface->resource());
|
||||
}
|
||||
wl_resource_destroy(resource->handle);
|
||||
}
|
||||
|
||||
void PointerInterface::Private::registerRelativePointerV1(RelativePointerV1Interface *relativePointer)
|
||||
void PointerInterfacePrivate::pointer_bind_resource(Resource *resource)
|
||||
{
|
||||
Q_ASSERT(!relativePointersV1.contains(relativePointer));
|
||||
relativePointersV1.append(relativePointer);
|
||||
}
|
||||
const ClientConnection *focusedClient = focusedSurface ? focusedSurface->client() : nullptr;
|
||||
|
||||
void PointerInterface::Private::unregisterRelativePointerV1(RelativePointerV1Interface *relativePointer)
|
||||
{
|
||||
Q_ASSERT(relativePointersV1.contains(relativePointer));
|
||||
relativePointersV1.removeOne(relativePointer);
|
||||
}
|
||||
|
||||
void PointerInterface::Private::registerSwipeGestureV1(PointerSwipeGestureV1Interface *gesture)
|
||||
{
|
||||
Q_ASSERT(!swipeGesturesV1.contains(gesture));
|
||||
swipeGesturesV1.append(gesture);
|
||||
}
|
||||
|
||||
void PointerInterface::Private::unregisterSwipeGestureV1(PointerSwipeGestureV1Interface *gesture)
|
||||
{
|
||||
Q_ASSERT(swipeGesturesV1.contains(gesture));
|
||||
swipeGesturesV1.removeOne(gesture);
|
||||
}
|
||||
|
||||
void PointerInterface::Private::registerPinchGestureV1(PointerPinchGestureV1Interface *gesture)
|
||||
{
|
||||
Q_ASSERT(!pinchGesturesV1.contains(gesture));
|
||||
pinchGesturesV1.append(gesture);
|
||||
}
|
||||
|
||||
void PointerInterface::Private::unregisterPinchGestureV1(PointerPinchGestureV1Interface *gesture)
|
||||
{
|
||||
Q_ASSERT(pinchGesturesV1.contains(gesture));
|
||||
pinchGesturesV1.removeOne(gesture);
|
||||
}
|
||||
|
||||
namespace {
|
||||
static QPointF surfacePosition(SurfaceInterface *surface) {
|
||||
if (surface && surface->subSurface()) {
|
||||
return surface->subSurface()->position() + surfacePosition(surface->subSurface()->parentSurface());
|
||||
}
|
||||
return QPointF();
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInterface::Private::sendEnter(SurfaceInterface *surface, const QPointF &parentSurfacePosition, quint32 serial)
|
||||
{
|
||||
if (!surface || !surface->resource()) {
|
||||
return;
|
||||
}
|
||||
const QPointF adjustedPos = parentSurfacePosition - surfacePosition(surface);
|
||||
wl_pointer_send_enter(resource, serial,
|
||||
surface->resource(),
|
||||
wl_fixed_from_double(adjustedPos.x()), wl_fixed_from_double(adjustedPos.y()));
|
||||
}
|
||||
|
||||
void PointerInterface::Private::startSwipeGesture(quint32 serial, quint32 fingerCount)
|
||||
{
|
||||
if (!focusedSurface) {
|
||||
return;
|
||||
}
|
||||
for (PointerSwipeGestureV1Interface *gesture : qAsConst(swipeGesturesV1)) {
|
||||
gesture->send_begin(serial, seat->timestamp(), focusedSurface->resource(), fingerCount);
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInterface::Private::updateSwipeGesture(const QSizeF &delta)
|
||||
{
|
||||
for (PointerSwipeGestureV1Interface *gesture : qAsConst(swipeGesturesV1)) {
|
||||
gesture->send_update(seat->timestamp(),
|
||||
wl_fixed_from_double(delta.width()),
|
||||
wl_fixed_from_double(delta.height()));
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInterface::Private::endSwipeGesture(quint32 serial)
|
||||
{
|
||||
for (PointerSwipeGestureV1Interface *gesture : qAsConst(swipeGesturesV1)) {
|
||||
gesture->send_end(serial, seat->timestamp(), false);
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInterface::Private::cancelSwipeGesture(quint32 serial)
|
||||
{
|
||||
for (PointerSwipeGestureV1Interface *gesture : qAsConst(swipeGesturesV1)) {
|
||||
gesture->send_end(serial, seat->timestamp(), true);
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInterface::Private::startPinchGesture(quint32 serial, quint32 fingerCount)
|
||||
{
|
||||
if (!focusedSurface) {
|
||||
return;
|
||||
}
|
||||
for (PointerPinchGestureV1Interface *gesture : qAsConst(pinchGesturesV1)) {
|
||||
gesture->send_begin(serial, seat->timestamp(), focusedSurface->resource(), fingerCount);
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInterface::Private::updatePinchGesture(const QSizeF &delta, qreal scale, qreal rotation)
|
||||
{
|
||||
for (PointerPinchGestureV1Interface *gesture : qAsConst(pinchGesturesV1)) {
|
||||
gesture->send_update(seat->timestamp(),
|
||||
wl_fixed_from_double(delta.width()),
|
||||
wl_fixed_from_double(delta.height()),
|
||||
wl_fixed_from_double(scale),
|
||||
wl_fixed_from_double(rotation));
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInterface::Private::endPinchGesture(quint32 serial)
|
||||
{
|
||||
for (PointerPinchGestureV1Interface *gesture : qAsConst(pinchGesturesV1)) {
|
||||
gesture->send_end(serial, seat->timestamp(), false);
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInterface::Private::cancelPinchGesture(quint32 serial)
|
||||
{
|
||||
for (PointerPinchGestureV1Interface *gesture : qAsConst(pinchGesturesV1)) {
|
||||
gesture->send_end(serial, seat->timestamp(), true);
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInterface::Private::sendFrame()
|
||||
{
|
||||
if (!resource || wl_resource_get_version(resource) < WL_POINTER_FRAME_SINCE_VERSION) {
|
||||
return;
|
||||
}
|
||||
wl_pointer_send_frame(resource);
|
||||
}
|
||||
|
||||
#ifndef K_DOXYGEN
|
||||
const struct wl_pointer_interface PointerInterface::Private::s_interface = {
|
||||
setCursorCallback,
|
||||
resourceDestroyedCallback
|
||||
};
|
||||
#endif
|
||||
|
||||
PointerInterface::PointerInterface(SeatInterface *parent, wl_resource *parentResource)
|
||||
: Resource(new Private(parent, parentResource, this))
|
||||
{
|
||||
// TODO: handle touch
|
||||
connect(parent, &SeatInterface::pointerPosChanged, this, [this] {
|
||||
Q_D();
|
||||
if (!d->focusedSurface || !d->resource) {
|
||||
return;
|
||||
if (focusedClient && focusedClient->client() == resource->client()) {
|
||||
const quint32 serial = seat->display()->nextSerial();
|
||||
send_enter(resource->handle, serial, focusedSurface->resource(),
|
||||
wl_fixed_from_double(lastPosition.x()), wl_fixed_from_double(lastPosition.y()));
|
||||
if (resource->version() >= WL_POINTER_FRAME_SINCE_VERSION) {
|
||||
send_frame(resource->handle);
|
||||
}
|
||||
if (d->seat->isDragPointer()) {
|
||||
const auto *originSurface = d->seat->dragSource()->origin();
|
||||
const bool proxyRemoteFocused = originSurface->dataProxy() && originSurface == d->focusedSurface;
|
||||
if (!proxyRemoteFocused) {
|
||||
// handled by DataDevice
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInterfacePrivate::sendLeave(quint32 serial)
|
||||
{
|
||||
const QList<Resource *> pointerResources = pointersForClient(focusedSurface->client());
|
||||
for (Resource *resource : pointerResources) {
|
||||
send_leave(resource->handle, serial, focusedSurface->resource());
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInterfacePrivate::sendEnter(const QPointF &position, quint32 serial)
|
||||
{
|
||||
const QList<Resource *> pointerResources = pointersForClient(focusedSurface->client());
|
||||
for (Resource *resource : pointerResources) {
|
||||
send_enter(resource->handle, serial, focusedSurface->resource(),
|
||||
wl_fixed_from_double(position.x()), wl_fixed_from_double(position.y()));
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInterfacePrivate::sendFrame()
|
||||
{
|
||||
const QList<Resource *> pointerResources = pointersForClient(focusedSurface->client());
|
||||
for (Resource *resource : pointerResources) {
|
||||
if (resource->version() >= WL_POINTER_FRAME_SINCE_VERSION) {
|
||||
send_frame(resource->handle);
|
||||
}
|
||||
if (d->focusedSurface->lockedPointer() && d->focusedSurface->lockedPointer()->isLocked()) {
|
||||
return;
|
||||
}
|
||||
const QPointF pos = d->seat->focusedPointerSurfaceTransformation().map(d->seat->pointerPos());
|
||||
auto targetSurface = d->focusedSurface->inputSurfaceAt(pos);
|
||||
if (!targetSurface) {
|
||||
targetSurface = d->focusedSurface;
|
||||
}
|
||||
if (targetSurface != d->focusedChildSurface.data()) {
|
||||
const quint32 serial = d->seat->display()->nextSerial();
|
||||
d->sendLeave(d->focusedChildSurface.data(), serial);
|
||||
d->focusedChildSurface = QPointer<SurfaceInterface>(targetSurface);
|
||||
d->sendEnter(targetSurface, pos, serial);
|
||||
d->sendFrame();
|
||||
d->client->flush();
|
||||
} else {
|
||||
const QPointF adjustedPos = pos - surfacePosition(d->focusedChildSurface);
|
||||
wl_pointer_send_motion(d->resource, d->seat->timestamp(),
|
||||
wl_fixed_from_double(adjustedPos.x()), wl_fixed_from_double(adjustedPos.y()));
|
||||
}
|
||||
}
|
||||
|
||||
PointerInterface::PointerInterface(SeatInterface *seat)
|
||||
: d(new PointerInterfacePrivate(this, seat))
|
||||
{
|
||||
}
|
||||
|
||||
PointerInterface::~PointerInterface()
|
||||
{
|
||||
}
|
||||
|
||||
SurfaceInterface *PointerInterface::focusedSurface() const
|
||||
{
|
||||
return d->focusedSurface;
|
||||
}
|
||||
|
||||
void PointerInterface::setFocusedSurface(SurfaceInterface *surface, const QPointF &position, quint32 serial)
|
||||
{
|
||||
if (d->focusedSurface == surface) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (d->focusedSurface) {
|
||||
d->sendLeave(serial);
|
||||
if (!surface || d->focusedSurface->client() != surface->client()) {
|
||||
d->sendFrame();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
PointerInterface::~PointerInterface() = default;
|
||||
|
||||
void PointerInterface::setFocusedSurface(SurfaceInterface *surface, quint32 serial)
|
||||
{
|
||||
Q_D();
|
||||
d->sendLeave(d->focusedChildSurface.data(), serial);
|
||||
disconnect(d->destroyConnection);
|
||||
if (!surface) {
|
||||
d->focusedSurface = nullptr;
|
||||
d->focusedChildSurface.clear();
|
||||
return;
|
||||
disconnect(d->destroyConnection);
|
||||
}
|
||||
|
||||
d->focusedSurface = surface;
|
||||
d->destroyConnection = connect(d->focusedSurface, &SurfaceInterface::aboutToBeDestroyed, this,
|
||||
[this] {
|
||||
Q_D();
|
||||
d->sendLeave(d->focusedChildSurface.data(), d->global->display()->nextSerial());
|
||||
|
||||
if (d->focusedSurface) {
|
||||
d->destroyConnection = connect(d->focusedSurface, &SurfaceInterface::aboutToBeDestroyed, this, [this]() {
|
||||
d->sendLeave(d->seat->display()->nextSerial());
|
||||
d->sendFrame();
|
||||
d->focusedSurface = nullptr;
|
||||
d->focusedChildSurface.clear();
|
||||
emit focusedSurfaceChanged();
|
||||
});
|
||||
d->sendEnter(position, serial);
|
||||
d->sendFrame();
|
||||
d->lastPosition = position;
|
||||
}
|
||||
|
||||
emit focusedSurfaceChanged();
|
||||
}
|
||||
|
||||
void PointerInterface::sendPressed(quint32 button, quint32 serial)
|
||||
{
|
||||
if (!d->focusedSurface) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto pointerResources = d->pointersForClient(d->focusedSurface->client());
|
||||
for (PointerInterfacePrivate::Resource *resource : pointerResources) {
|
||||
d->send_button(resource->handle, serial, d->seat->timestamp(), button,
|
||||
PointerInterfacePrivate::button_state_pressed);
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInterface::sendReleased(quint32 button, quint32 serial)
|
||||
{
|
||||
if (!d->focusedSurface) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto pointerResources = d->pointersForClient(d->focusedSurface->client());
|
||||
for (PointerInterfacePrivate::Resource *resource : pointerResources) {
|
||||
d->send_button(resource->handle, serial, d->seat->timestamp(), button,
|
||||
PointerInterfacePrivate::button_state_released);
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInterface::sendAxis(Qt::Orientation orientation, qreal delta, qint32 discreteDelta, PointerAxisSource source)
|
||||
{
|
||||
if (!d->focusedSurface) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto pointerResources = d->pointersForClient(d->focusedSurface->client());
|
||||
for (PointerInterfacePrivate::Resource *resource : pointerResources) {
|
||||
const quint32 version = resource->version();
|
||||
|
||||
const auto wlOrientation = (orientation == Qt::Vertical)
|
||||
? PointerInterfacePrivate::axis_vertical_scroll
|
||||
: PointerInterfacePrivate::axis_horizontal_scroll;
|
||||
|
||||
if (source != PointerAxisSource::Unknown && version >= WL_POINTER_AXIS_SOURCE_SINCE_VERSION) {
|
||||
PointerInterfacePrivate::axis_source wlSource;
|
||||
switch (source) {
|
||||
case PointerAxisSource::Wheel:
|
||||
wlSource = PointerInterfacePrivate::axis_source_wheel;
|
||||
break;
|
||||
case PointerAxisSource::Finger:
|
||||
wlSource = PointerInterfacePrivate::axis_source_finger;
|
||||
break;
|
||||
case PointerAxisSource::Continuous:
|
||||
wlSource = PointerInterfacePrivate::axis_source_continuous;
|
||||
break;
|
||||
case PointerAxisSource::WheelTilt:
|
||||
wlSource = PointerInterfacePrivate::axis_source_wheel_tilt;
|
||||
break;
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
d->send_axis_source(resource->handle, wlSource);
|
||||
}
|
||||
);
|
||||
|
||||
const QPointF pos = d->seat->focusedPointerSurfaceTransformation().map(d->seat->pointerPos());
|
||||
d->focusedChildSurface = QPointer<SurfaceInterface>(d->focusedSurface->inputSurfaceAt(pos));
|
||||
if (!d->focusedChildSurface) {
|
||||
d->focusedChildSurface = QPointer<SurfaceInterface>(d->focusedSurface);
|
||||
}
|
||||
d->sendEnter(d->focusedChildSurface.data(), pos, serial);
|
||||
d->client->flush();
|
||||
}
|
||||
|
||||
void PointerInterface::buttonPressed(quint32 button, quint32 serial)
|
||||
{
|
||||
Q_D();
|
||||
Q_ASSERT(d->focusedSurface);
|
||||
if (!d->resource) {
|
||||
return;
|
||||
}
|
||||
wl_pointer_send_button(d->resource, serial, d->seat->timestamp(), button, WL_POINTER_BUTTON_STATE_PRESSED);
|
||||
d->sendFrame();
|
||||
}
|
||||
|
||||
void PointerInterface::buttonReleased(quint32 button, quint32 serial)
|
||||
{
|
||||
Q_D();
|
||||
Q_ASSERT(d->focusedSurface);
|
||||
if (!d->resource) {
|
||||
return;
|
||||
}
|
||||
wl_pointer_send_button(d->resource, serial, d->seat->timestamp(), button, WL_POINTER_BUTTON_STATE_RELEASED);
|
||||
d->sendFrame();
|
||||
}
|
||||
|
||||
void PointerInterface::axis(Qt::Orientation orientation, qreal delta, qint32 discreteDelta, PointerAxisSource source)
|
||||
{
|
||||
Q_D();
|
||||
Q_ASSERT(d->focusedSurface);
|
||||
if (!d->resource) {
|
||||
return;
|
||||
}
|
||||
|
||||
const quint32 version = wl_resource_get_version(d->resource);
|
||||
|
||||
const auto wlOrientation = (orientation == Qt::Vertical)
|
||||
? WL_POINTER_AXIS_VERTICAL_SCROLL
|
||||
: WL_POINTER_AXIS_HORIZONTAL_SCROLL;
|
||||
|
||||
if (source != PointerAxisSource::Unknown && version >= WL_POINTER_AXIS_SOURCE_SINCE_VERSION) {
|
||||
wl_pointer_axis_source wlSource;
|
||||
switch (source) {
|
||||
case PointerAxisSource::Wheel:
|
||||
wlSource = WL_POINTER_AXIS_SOURCE_WHEEL;
|
||||
break;
|
||||
case PointerAxisSource::Finger:
|
||||
wlSource = WL_POINTER_AXIS_SOURCE_FINGER;
|
||||
break;
|
||||
case PointerAxisSource::Continuous:
|
||||
wlSource = WL_POINTER_AXIS_SOURCE_CONTINUOUS;
|
||||
break;
|
||||
case PointerAxisSource::WheelTilt:
|
||||
wlSource = WL_POINTER_AXIS_SOURCE_WHEEL_TILT;
|
||||
break;
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
break;
|
||||
if (delta != 0.0) {
|
||||
if (discreteDelta && version >= WL_POINTER_AXIS_DISCRETE_SINCE_VERSION) {
|
||||
d->send_axis_discrete(resource->handle, wlOrientation, discreteDelta);
|
||||
}
|
||||
d->send_axis(resource->handle, d->seat->timestamp(), wlOrientation, wl_fixed_from_double(delta));
|
||||
} else if (version >= WL_POINTER_AXIS_STOP_SINCE_VERSION) {
|
||||
d->send_axis_stop(resource->handle, d->seat->timestamp(), wlOrientation);
|
||||
}
|
||||
wl_pointer_send_axis_source(d->resource, wlSource);
|
||||
}
|
||||
|
||||
if (delta != 0.0) {
|
||||
if (discreteDelta && version >= WL_POINTER_AXIS_DISCRETE_SINCE_VERSION) {
|
||||
wl_pointer_send_axis_discrete(d->resource, wlOrientation, discreteDelta);
|
||||
}
|
||||
wl_pointer_send_axis(d->resource, d->seat->timestamp(), wlOrientation, wl_fixed_from_double(delta));
|
||||
} else if (version >= WL_POINTER_AXIS_STOP_SINCE_VERSION) {
|
||||
wl_pointer_send_axis_stop(d->resource, d->seat->timestamp(), wlOrientation);
|
||||
}
|
||||
|
||||
d->sendFrame();
|
||||
}
|
||||
|
||||
void PointerInterface::axis(Qt::Orientation orientation, quint32 delta)
|
||||
void PointerInterface::sendMotion(const QPointF &position)
|
||||
{
|
||||
Q_D();
|
||||
Q_ASSERT(d->focusedSurface);
|
||||
if (!d->resource) {
|
||||
d->lastPosition = position;
|
||||
|
||||
if (!d->focusedSurface) {
|
||||
return;
|
||||
}
|
||||
wl_pointer_send_axis(d->resource, d->seat->timestamp(),
|
||||
(orientation == Qt::Vertical) ? WL_POINTER_AXIS_VERTICAL_SCROLL : WL_POINTER_AXIS_HORIZONTAL_SCROLL,
|
||||
wl_fixed_from_int(delta));
|
||||
d->sendFrame();
|
||||
|
||||
const auto pointerResources = d->pointersForClient(d->focusedSurface->client());
|
||||
for (PointerInterfacePrivate::Resource *resource : pointerResources) {
|
||||
d->send_motion(resource->handle, d->seat->timestamp(),
|
||||
wl_fixed_from_double(position.x()), wl_fixed_from_double(position.y()));
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInterface::Private::setCursorCallback(wl_client *client, wl_resource *resource, uint32_t serial,
|
||||
wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y)
|
||||
void PointerInterface::sendFrame()
|
||||
{
|
||||
auto p = cast<Private>(resource);
|
||||
Q_ASSERT(p->client->client() == client);
|
||||
p->setCursor(serial, SurfaceInterface::get(surface), QPoint(hotspot_x, hotspot_y));
|
||||
if (d->focusedSurface) {
|
||||
d->sendFrame();
|
||||
}
|
||||
}
|
||||
|
||||
Cursor *PointerInterface::cursor() const
|
||||
{
|
||||
Q_D();
|
||||
return d->cursor;
|
||||
}
|
||||
|
||||
void PointerInterface::relativeMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint64 microseconds)
|
||||
SeatInterface *PointerInterface::seat() const
|
||||
{
|
||||
Q_D();
|
||||
if (d->relativePointersV1.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (RelativePointerV1Interface *relativePointer : qAsConst(d->relativePointersV1)) {
|
||||
relativePointer->send_relative_motion(microseconds >> 32, microseconds & 0xffffffff,
|
||||
wl_fixed_from_double(delta.width()),
|
||||
wl_fixed_from_double(delta.height()),
|
||||
wl_fixed_from_double(deltaNonAccelerated.width()),
|
||||
wl_fixed_from_double(deltaNonAccelerated.height()));
|
||||
}
|
||||
d->sendFrame();
|
||||
}
|
||||
|
||||
PointerInterface::Private *PointerInterface::d_func() const
|
||||
{
|
||||
return reinterpret_cast<Private*>(d.data());
|
||||
return d->seat;
|
||||
}
|
||||
|
||||
PointerInterface *PointerInterface::get(wl_resource *native)
|
||||
{
|
||||
return Private::get<PointerInterface>(native);
|
||||
if (PointerInterfacePrivate *pointerPrivate = resource_cast<PointerInterfacePrivate *>(native)) {
|
||||
return pointerPrivate->q;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Cursor::Private::Private(Cursor *q, PointerInterface *pointer)
|
||||
: pointer(pointer)
|
||||
, q(q)
|
||||
CursorPrivate::CursorPrivate(Cursor *q, PointerInterface *pointer)
|
||||
: q(q)
|
||||
, pointer(pointer)
|
||||
{
|
||||
}
|
||||
|
||||
void Cursor::Private::update(const QPointer< SurfaceInterface > &s, quint32 serial, const QPoint &p)
|
||||
void CursorPrivate::update(SurfaceInterface *s, quint32 serial, const QPoint &p)
|
||||
{
|
||||
bool emitChanged = false;
|
||||
if (enteredSerial != serial) {
|
||||
|
@ -436,11 +340,13 @@ void Cursor::Private::update(const QPointer< SurfaceInterface > &s, quint32 seri
|
|||
|
||||
Cursor::Cursor(PointerInterface *parent)
|
||||
: QObject(parent)
|
||||
, d(new Private(this, parent))
|
||||
, d(new CursorPrivate(this, parent))
|
||||
{
|
||||
}
|
||||
|
||||
Cursor::~Cursor() = default;
|
||||
Cursor::~Cursor()
|
||||
{
|
||||
}
|
||||
|
||||
quint32 Cursor::enteredSerial() const
|
||||
{
|
||||
|
@ -457,7 +363,7 @@ PointerInterface *Cursor::pointer() const
|
|||
return d->pointer;
|
||||
}
|
||||
|
||||
QPointer< SurfaceInterface > Cursor::surface() const
|
||||
SurfaceInterface *Cursor::surface() const
|
||||
{
|
||||
return d->surface;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
|
||||
SPDX-FileCopyrightText: 2020 Adrien Faveraux <ad1rie3@hotmail.fr>
|
||||
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||
*/
|
||||
|
@ -8,93 +10,106 @@
|
|||
|
||||
#include <KWaylandServer/kwaylandserver_export.h>
|
||||
|
||||
#include "resource.h"
|
||||
#include <QObject>
|
||||
|
||||
struct wl_resource;
|
||||
|
||||
namespace KWaylandServer
|
||||
{
|
||||
|
||||
class CursorPrivate;
|
||||
class Cursor;
|
||||
class PointerInterfacePrivate;
|
||||
class SeatInterface;
|
||||
class SurfaceInterface;
|
||||
|
||||
enum class PointerAxisSource;
|
||||
|
||||
/**
|
||||
* @brief Resource for the wl_pointer interface.
|
||||
*
|
||||
* @see SeatInterface
|
||||
**/
|
||||
class KWAYLANDSERVER_EXPORT PointerInterface : public Resource
|
||||
* The PointerInterface class represents one or more input devices such as mice, which control
|
||||
* the pointer location. It corresponds to the Wayland interface @c wl_pointer.
|
||||
*/
|
||||
class KWAYLANDSERVER_EXPORT PointerInterface : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
virtual ~PointerInterface();
|
||||
~PointerInterface() override;
|
||||
|
||||
/**
|
||||
* @returns the focused SurfaceInterface on this pointer resource, if any.
|
||||
**/
|
||||
* Returns the focused pointer surface. Note that the returned value may be different
|
||||
* from SurfaceInterface::focusedSurfacePointerSurface() because this function returns
|
||||
* the effective focused surface.
|
||||
*/
|
||||
SurfaceInterface *focusedSurface() const;
|
||||
|
||||
/**
|
||||
* The Cursor set on this PointerInterface. Might be @c null.
|
||||
* @since 5.3
|
||||
**/
|
||||
* Sets the effective focused pointer surface to @a surface. The @a position indicates
|
||||
* where the pointer has entered the surface.
|
||||
*/
|
||||
void setFocusedSurface(SurfaceInterface *surface, const QPointF &position, quint32 serial);
|
||||
|
||||
Cursor *cursor() const;
|
||||
|
||||
/**
|
||||
* Returns the seat to which this pointer belongs to.
|
||||
*/
|
||||
SeatInterface *seat() const;
|
||||
|
||||
/**
|
||||
* @returns The PointerInterface for the @p native resource.
|
||||
* @since 5.28
|
||||
**/
|
||||
*/
|
||||
static PointerInterface *get(wl_resource *native);
|
||||
|
||||
void sendPressed(quint32 button, quint32 serial);
|
||||
void sendReleased(quint32 button, quint32 serial);
|
||||
void sendAxis(Qt::Orientation orientation, qreal delta, qint32 discreteDelta, PointerAxisSource source);
|
||||
void sendMotion(const QPointF &position);
|
||||
void sendFrame();
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* Signal emitted whenever the Cursor changes.
|
||||
**/
|
||||
* This signal is emitted whenever the cursor surface changes. As long as there is no
|
||||
* any focused surface, the cursor cannot be changed.
|
||||
*/
|
||||
void cursorChanged();
|
||||
/**
|
||||
* This signal is emitted whenever the focused pointer surface changes.
|
||||
*/
|
||||
void focusedSurfaceChanged();
|
||||
|
||||
private:
|
||||
void setFocusedSurface(SurfaceInterface *surface, quint32 serial);
|
||||
void buttonPressed(quint32 button, quint32 serial);
|
||||
void buttonReleased(quint32 button, quint32 serial);
|
||||
void axis(Qt::Orientation orientation, qreal delta, qint32 discreteDelta, PointerAxisSource source);
|
||||
void axis(Qt::Orientation orientation, quint32 delta);
|
||||
void relativeMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint64 microseconds);
|
||||
explicit PointerInterface(SeatInterface *seat);
|
||||
QScopedPointer<PointerInterfacePrivate> d;
|
||||
|
||||
friend class SeatInterface;
|
||||
friend class RelativePointerV1Interface;
|
||||
friend class PointerPinchGestureV1Interface;
|
||||
friend class PointerSwipeGestureV1Interface;
|
||||
explicit PointerInterface(SeatInterface *parent, wl_resource *parentResource);
|
||||
class Private;
|
||||
Private *d_func() const;
|
||||
friend class PointerInterfacePrivate;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Class encapsulating a Cursor image.
|
||||
*
|
||||
* @since 5.3
|
||||
**/
|
||||
*/
|
||||
class KWAYLANDSERVER_EXPORT Cursor : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
virtual ~Cursor();
|
||||
/**
|
||||
* The hotspot of the cursor image in surface-relative coordinates.
|
||||
**/
|
||||
*/
|
||||
QPoint hotspot() const;
|
||||
/**
|
||||
* The entered serial when the Cursor got set.
|
||||
**/
|
||||
*/
|
||||
quint32 enteredSerial() const;
|
||||
/**
|
||||
* The PointerInterface this Cursor belongs to.
|
||||
**/
|
||||
*/
|
||||
PointerInterface *pointer() const;
|
||||
/**
|
||||
* The SurfaceInterface for the image content of the Cursor.
|
||||
**/
|
||||
QPointer<SurfaceInterface> surface() const;
|
||||
*/
|
||||
SurfaceInterface *surface() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void hotspotChanged();
|
||||
|
@ -103,14 +118,11 @@ Q_SIGNALS:
|
|||
void changed();
|
||||
|
||||
private:
|
||||
friend class PointerInterface;
|
||||
Cursor(PointerInterface *parent);
|
||||
class Private;
|
||||
const QScopedPointer<Private> d;
|
||||
QScopedPointer<CursorPrivate> d;
|
||||
friend class PointerInterfacePrivate;
|
||||
explicit Cursor(PointerInterface *parent);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(KWaylandServer::PointerInterface*)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,68 +1,58 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
|
||||
SPDX-FileCopyrightText: 2020 Adrien Faveraux <ad1rie3@hotmail.fr>
|
||||
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||
*/
|
||||
#ifndef WAYLAND_SERVER_POINTER_INTERFACE_P_H
|
||||
#define WAYLAND_SERVER_POINTER_INTERFACE_P_H
|
||||
#include "pointer_interface.h"
|
||||
#include "resource_p.h"
|
||||
|
||||
#include <QPointF>
|
||||
#include <QPointer>
|
||||
#include <QVector>
|
||||
|
||||
#include "qwayland-server-wayland.h"
|
||||
|
||||
namespace KWaylandServer
|
||||
{
|
||||
|
||||
class ClientConnection;
|
||||
class PointerPinchGestureV1Interface;
|
||||
class PointerSwipeGestureV1Interface;
|
||||
class RelativePointerV1Interface;
|
||||
|
||||
class PointerInterface::Private : public Resource::Private
|
||||
class PointerInterfacePrivate : public QtWaylandServer::wl_pointer
|
||||
{
|
||||
public:
|
||||
Private(SeatInterface *parent, wl_resource *parentResource, PointerInterface *q);
|
||||
static PointerInterfacePrivate *get(PointerInterface *pointer);
|
||||
|
||||
PointerInterfacePrivate(PointerInterface *q, SeatInterface *seat);
|
||||
~PointerInterfacePrivate() override;
|
||||
|
||||
QList<Resource *> pointersForClient(ClientConnection *client) const;
|
||||
|
||||
PointerInterface *q;
|
||||
SeatInterface *seat;
|
||||
SurfaceInterface *focusedSurface = nullptr;
|
||||
QPointer<SurfaceInterface> focusedChildSurface;
|
||||
QMetaObject::Connection destroyConnection;
|
||||
Cursor *cursor = nullptr;
|
||||
QVector<RelativePointerV1Interface *> relativePointersV1;
|
||||
QVector<PointerSwipeGestureV1Interface *> swipeGesturesV1;
|
||||
QVector<PointerPinchGestureV1Interface *> pinchGesturesV1;
|
||||
QScopedPointer<RelativePointerV1Interface> relativePointersV1;
|
||||
QScopedPointer<PointerSwipeGestureV1Interface> swipeGesturesV1;
|
||||
QScopedPointer<PointerPinchGestureV1Interface> pinchGesturesV1;
|
||||
QPointF lastPosition;
|
||||
|
||||
void sendLeave(SurfaceInterface *surface, quint32 serial);
|
||||
void sendEnter(SurfaceInterface *surface, const QPointF &parentSurfacePosition, quint32 serial);
|
||||
void sendLeave(quint32 serial);
|
||||
void sendEnter(const QPointF &parentSurfacePosition, quint32 serial);
|
||||
void sendFrame();
|
||||
|
||||
void registerRelativePointerV1(RelativePointerV1Interface *relativePointer);
|
||||
void registerSwipeGestureV1(PointerSwipeGestureV1Interface *gesture);
|
||||
void registerPinchGestureV1(PointerPinchGestureV1Interface *gesture);
|
||||
|
||||
void unregisterRelativePointerV1(RelativePointerV1Interface *relativePointer);
|
||||
void unregisterSwipeGestureV1(PointerSwipeGestureV1Interface *gesture);
|
||||
void unregisterPinchGestureV1(PointerPinchGestureV1Interface *gesture);
|
||||
|
||||
void startSwipeGesture(quint32 serial, quint32 fingerCount);
|
||||
void updateSwipeGesture(const QSizeF &delta);
|
||||
void endSwipeGesture(quint32 serial);
|
||||
void cancelSwipeGesture(quint32 serial);
|
||||
|
||||
void startPinchGesture(quint32 serial, quint32 fingerCount);
|
||||
void updatePinchGesture(const QSizeF &delta, qreal scale, qreal rotation);
|
||||
void endPinchGesture(quint32 serial);
|
||||
void cancelPinchGesture(quint32 serial);
|
||||
|
||||
private:
|
||||
PointerInterface *q_func() {
|
||||
return reinterpret_cast<PointerInterface *>(q);
|
||||
}
|
||||
void setCursor(quint32 serial, SurfaceInterface *surface, const QPoint &hotspot);
|
||||
// interface
|
||||
static void setCursorCallback(wl_client *client, wl_resource *resource, uint32_t serial,
|
||||
wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y);
|
||||
|
||||
static const struct wl_pointer_interface s_interface;
|
||||
protected:
|
||||
void pointer_set_cursor(Resource *resource, uint32_t serial,
|
||||
::wl_resource *surface_resource,
|
||||
int32_t hotspot_x, int32_t hotspot_y) override;
|
||||
void pointer_release(Resource *resource) override;
|
||||
void pointer_bind_resource(Resource *resource) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -6,14 +6,17 @@
|
|||
*/
|
||||
|
||||
#include "pointergestures_v1_interface.h"
|
||||
#include "clientconnection.h"
|
||||
#include "display.h"
|
||||
#include "pointer_interface_p.h"
|
||||
#include "pointergestures_v1_interface_p.h"
|
||||
#include "seat_interface.h"
|
||||
#include "surface_interface.h"
|
||||
|
||||
namespace KWaylandServer
|
||||
{
|
||||
|
||||
static const int s_version = 1;
|
||||
static const int s_version = 2;
|
||||
|
||||
PointerGesturesV1InterfacePrivate::PointerGesturesV1InterfacePrivate(Display *display)
|
||||
: QtWaylandServer::zwp_pointer_gestures_v1(*display, s_version)
|
||||
|
@ -29,14 +32,8 @@ void PointerGesturesV1InterfacePrivate::zwp_pointer_gestures_v1_get_swipe_gestur
|
|||
return;
|
||||
}
|
||||
|
||||
wl_resource *swipeResource = wl_resource_create(resource->client(), &zwp_pointer_gesture_swipe_v1_interface,
|
||||
resource->version(), id);
|
||||
if (!swipeResource) {
|
||||
wl_resource_post_no_memory(resource->handle);
|
||||
return;
|
||||
}
|
||||
|
||||
new PointerSwipeGestureV1Interface(pointer, swipeResource);
|
||||
PointerSwipeGestureV1Interface *swipeGesture = PointerSwipeGestureV1Interface::get(pointer);
|
||||
swipeGesture->add(resource->client(), id, resource->version());
|
||||
}
|
||||
|
||||
void PointerGesturesV1InterfacePrivate::zwp_pointer_gestures_v1_get_pinch_gesture(Resource *resource, uint32_t id, struct ::wl_resource *pointer_resource)
|
||||
|
@ -48,14 +45,8 @@ void PointerGesturesV1InterfacePrivate::zwp_pointer_gestures_v1_get_pinch_gestur
|
|||
return;
|
||||
}
|
||||
|
||||
wl_resource *pinchResource = wl_resource_create(resource->client(), &zwp_pointer_gesture_pinch_v1_interface,
|
||||
resource->version(), id);
|
||||
if (!pinchResource) {
|
||||
wl_resource_post_no_memory(resource->handle);
|
||||
return;
|
||||
}
|
||||
|
||||
new PointerPinchGestureV1Interface(pointer, pinchResource);
|
||||
PointerPinchGestureV1Interface *pinchGesture = PointerPinchGestureV1Interface::get(pointer);
|
||||
pinchGesture->add(resource->client(), id, resource->version());
|
||||
}
|
||||
|
||||
void PointerGesturesV1InterfacePrivate::zwp_pointer_gestures_v1_release(Resource *resource)
|
||||
|
@ -73,25 +64,18 @@ PointerGesturesV1Interface::~PointerGesturesV1Interface()
|
|||
{
|
||||
}
|
||||
|
||||
PointerSwipeGestureV1Interface::PointerSwipeGestureV1Interface(PointerInterface *pointer,
|
||||
::wl_resource *resource)
|
||||
: QtWaylandServer::zwp_pointer_gesture_swipe_v1(resource)
|
||||
, pointer(pointer)
|
||||
PointerSwipeGestureV1Interface::PointerSwipeGestureV1Interface(PointerInterface *pointer)
|
||||
: pointer(pointer)
|
||||
{
|
||||
pointer->d_func()->registerSwipeGestureV1(this);
|
||||
}
|
||||
|
||||
PointerSwipeGestureV1Interface::~PointerSwipeGestureV1Interface()
|
||||
PointerSwipeGestureV1Interface *PointerSwipeGestureV1Interface::get(PointerInterface *pointer)
|
||||
{
|
||||
if (pointer) {
|
||||
pointer->d_func()->unregisterSwipeGestureV1(this);
|
||||
PointerInterfacePrivate *pointerPrivate = PointerInterfacePrivate::get(pointer);
|
||||
return pointerPrivate->swipeGesturesV1.data();
|
||||
}
|
||||
}
|
||||
|
||||
void PointerSwipeGestureV1Interface::zwp_pointer_gesture_swipe_v1_destroy_resource(Resource *resource)
|
||||
{
|
||||
Q_UNUSED(resource)
|
||||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void PointerSwipeGestureV1Interface::zwp_pointer_gesture_swipe_v1_destroy(Resource *resource)
|
||||
|
@ -99,25 +83,94 @@ void PointerSwipeGestureV1Interface::zwp_pointer_gesture_swipe_v1_destroy(Resour
|
|||
wl_resource_destroy(resource->handle);
|
||||
}
|
||||
|
||||
PointerPinchGestureV1Interface::PointerPinchGestureV1Interface(PointerInterface *pointer,
|
||||
::wl_resource *resource)
|
||||
: QtWaylandServer::zwp_pointer_gesture_pinch_v1(resource)
|
||||
, pointer(pointer)
|
||||
void PointerSwipeGestureV1Interface::sendBegin(quint32 serial, quint32 fingerCount)
|
||||
{
|
||||
pointer->d_func()->registerPinchGestureV1(this);
|
||||
}
|
||||
if (focusedClient) {
|
||||
return;
|
||||
}
|
||||
if (!pointer->focusedSurface()) {
|
||||
return;
|
||||
}
|
||||
|
||||
PointerPinchGestureV1Interface::~PointerPinchGestureV1Interface()
|
||||
{
|
||||
if (pointer) {
|
||||
pointer->d_func()->unregisterPinchGestureV1(this);
|
||||
const SurfaceInterface *focusedSurface = pointer->focusedSurface();
|
||||
focusedClient = focusedSurface->client();
|
||||
SeatInterface *seat = pointer->seat();
|
||||
|
||||
const QList<Resource *> swipeResources = resourceMap().values(focusedClient->client());
|
||||
for (Resource *swipeResource : swipeResources) {
|
||||
if (swipeResource->client() == focusedClient->client()) {
|
||||
send_begin(swipeResource->handle, serial, seat->timestamp(), focusedSurface->resource(), fingerCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PointerPinchGestureV1Interface::zwp_pointer_gesture_pinch_v1_destroy_resource(Resource *resource)
|
||||
void PointerSwipeGestureV1Interface::sendUpdate(const QSizeF &delta)
|
||||
{
|
||||
Q_UNUSED(resource)
|
||||
delete this;
|
||||
if (!focusedClient) {
|
||||
return;
|
||||
}
|
||||
|
||||
SeatInterface *seat = pointer->seat();
|
||||
|
||||
const QList<Resource *> swipeResources = resourceMap().values(focusedClient->client());
|
||||
for (Resource *swipeResource : swipeResources) {
|
||||
if (swipeResource->client() == focusedClient->client()) {
|
||||
send_update(swipeResource->handle, seat->timestamp(),
|
||||
wl_fixed_from_double(delta.width()), wl_fixed_from_double(delta.height()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PointerSwipeGestureV1Interface::sendEnd(quint32 serial)
|
||||
{
|
||||
if (!focusedClient) {
|
||||
return;
|
||||
}
|
||||
|
||||
SeatInterface *seat = pointer->seat();
|
||||
|
||||
const QList<Resource *> swipeResources = resourceMap().values(focusedClient->client());
|
||||
for (Resource *swipeResource : swipeResources) {
|
||||
if (swipeResource->client() == focusedClient->client()) {
|
||||
send_end(swipeResource->handle, serial, seat->timestamp(), false);
|
||||
}
|
||||
}
|
||||
|
||||
// The gesture session has been just finished, reset the cached focused client.
|
||||
focusedClient = nullptr;
|
||||
}
|
||||
|
||||
void PointerSwipeGestureV1Interface::sendCancel(quint32 serial)
|
||||
{
|
||||
if (!focusedClient) {
|
||||
return;
|
||||
}
|
||||
|
||||
SeatInterface *seat = pointer->seat();
|
||||
|
||||
const QList<Resource *> swipeResources = resourceMap().values(focusedClient->client());
|
||||
for (Resource *swipeResource : swipeResources) {
|
||||
if (swipeResource->client() == focusedClient->client()) {
|
||||
send_end(swipeResource->handle, serial, seat->timestamp(), true);
|
||||
}
|
||||
}
|
||||
|
||||
// The gesture session has been just finished, reset the cached focused client.
|
||||
focusedClient = nullptr;
|
||||
}
|
||||
|
||||
PointerPinchGestureV1Interface::PointerPinchGestureV1Interface(PointerInterface *pointer)
|
||||
: pointer(pointer)
|
||||
{
|
||||
}
|
||||
|
||||
PointerPinchGestureV1Interface *PointerPinchGestureV1Interface::get(PointerInterface *pointer)
|
||||
{
|
||||
if (pointer) {
|
||||
PointerInterfacePrivate *pointerPrivate = PointerInterfacePrivate::get(pointer);
|
||||
return pointerPrivate->pinchGesturesV1.data();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void PointerPinchGestureV1Interface::zwp_pointer_gesture_pinch_v1_destroy(Resource *resource)
|
||||
|
@ -125,4 +178,81 @@ void PointerPinchGestureV1Interface::zwp_pointer_gesture_pinch_v1_destroy(Resour
|
|||
wl_resource_destroy(resource->handle);
|
||||
}
|
||||
|
||||
void PointerPinchGestureV1Interface::sendBegin(quint32 serial, quint32 fingerCount)
|
||||
{
|
||||
if (focusedClient) {
|
||||
return; // gesture is already active
|
||||
}
|
||||
if (!pointer->focusedSurface()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const SurfaceInterface *focusedSurface = pointer->focusedSurface();
|
||||
focusedClient = focusedSurface->client();
|
||||
SeatInterface *seat = pointer->seat();
|
||||
|
||||
const QList<Resource *> pinchResources = resourceMap().values(*focusedClient);
|
||||
for (Resource *pinchResource : pinchResources) {
|
||||
if (pinchResource->client() == focusedClient->client()) {
|
||||
send_begin(pinchResource->handle, serial, seat->timestamp(), focusedSurface->resource(), fingerCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PointerPinchGestureV1Interface::sendUpdate(const QSizeF &delta, qreal scale, qreal rotation)
|
||||
{
|
||||
if (!focusedClient) {
|
||||
return;
|
||||
}
|
||||
|
||||
SeatInterface *seat = pointer->seat();
|
||||
|
||||
const QList<Resource *> pinchResources = resourceMap().values(*focusedClient);
|
||||
for (Resource *pinchResource : pinchResources) {
|
||||
if (pinchResource->client() == focusedClient->client()) {
|
||||
send_update(pinchResource->handle, seat->timestamp(),
|
||||
wl_fixed_from_double(delta.width()), wl_fixed_from_double(delta.height()),
|
||||
wl_fixed_from_double(scale), wl_fixed_from_double(rotation));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PointerPinchGestureV1Interface::sendEnd(quint32 serial)
|
||||
{
|
||||
if (!focusedClient) {
|
||||
return;
|
||||
}
|
||||
|
||||
SeatInterface *seat = pointer->seat();
|
||||
|
||||
const QList<Resource *> pinchResources = resourceMap().values(*focusedClient);
|
||||
for (Resource *pinchResource : pinchResources) {
|
||||
if (pinchResource->client() == focusedClient->client()) {
|
||||
send_end(pinchResource->handle, serial, seat->timestamp(), false);
|
||||
}
|
||||
}
|
||||
|
||||
// The gesture session has been just finished, reset the cached focused client.
|
||||
focusedClient = nullptr;
|
||||
}
|
||||
|
||||
void PointerPinchGestureV1Interface::sendCancel(quint32 serial)
|
||||
{
|
||||
if (!focusedClient) {
|
||||
return;
|
||||
}
|
||||
|
||||
SeatInterface *seat = pointer->seat();
|
||||
|
||||
const QList<Resource *> pinchResources = resourceMap().values(*focusedClient);
|
||||
for (Resource *pinchResource : pinchResources) {
|
||||
if (pinchResource->client() == focusedClient->client()) {
|
||||
send_end(pinchResource->handle, serial, seat->timestamp(), true);
|
||||
}
|
||||
}
|
||||
|
||||
// The gesture session has been just finished, reset the cached focused client.
|
||||
focusedClient = nullptr;
|
||||
}
|
||||
|
||||
} // namespace KWaylandServer
|
||||
|
|
|
@ -14,8 +14,10 @@
|
|||
namespace KWaylandServer
|
||||
{
|
||||
|
||||
class ClientConnection;
|
||||
class Display;
|
||||
class PointerInterface;
|
||||
class SurfaceInterface;
|
||||
|
||||
class PointerGesturesV1InterfacePrivate : public QtWaylandServer::zwp_pointer_gestures_v1
|
||||
{
|
||||
|
@ -33,27 +35,41 @@ protected:
|
|||
class PointerSwipeGestureV1Interface : public QtWaylandServer::zwp_pointer_gesture_swipe_v1
|
||||
{
|
||||
public:
|
||||
PointerSwipeGestureV1Interface(PointerInterface *pointer, ::wl_resource *resource);
|
||||
~PointerSwipeGestureV1Interface() override;
|
||||
explicit PointerSwipeGestureV1Interface(PointerInterface *pointer);
|
||||
|
||||
QPointer<PointerInterface> pointer;
|
||||
static PointerSwipeGestureV1Interface *get(PointerInterface *pointer);
|
||||
|
||||
void sendBegin(quint32 serial, quint32 fingerCount);
|
||||
void sendUpdate(const QSizeF &delta);
|
||||
void sendEnd(quint32 serial);
|
||||
void sendCancel(quint32 serial);
|
||||
|
||||
protected:
|
||||
void zwp_pointer_gesture_swipe_v1_destroy_resource(Resource *resource) override;
|
||||
void zwp_pointer_gesture_swipe_v1_destroy(Resource *resource) override;
|
||||
|
||||
private:
|
||||
PointerInterface *pointer;
|
||||
QPointer<ClientConnection> focusedClient;
|
||||
};
|
||||
|
||||
class PointerPinchGestureV1Interface : public QtWaylandServer::zwp_pointer_gesture_pinch_v1
|
||||
{
|
||||
public:
|
||||
PointerPinchGestureV1Interface(PointerInterface *pointer, ::wl_resource *resource);
|
||||
~PointerPinchGestureV1Interface() override;
|
||||
explicit PointerPinchGestureV1Interface(PointerInterface *pointer);
|
||||
|
||||
QPointer<PointerInterface> pointer;
|
||||
static PointerPinchGestureV1Interface *get(PointerInterface *pointer);
|
||||
|
||||
void sendBegin(quint32 serial, quint32 fingerCount);
|
||||
void sendUpdate(const QSizeF &delta, qreal scale, qreal rotation);
|
||||
void sendEnd(quint32 serial);
|
||||
void sendCancel(quint32 serial);
|
||||
|
||||
protected:
|
||||
void zwp_pointer_gesture_pinch_v1_destroy_resource(Resource *resource) override;
|
||||
void zwp_pointer_gesture_pinch_v1_destroy(Resource *resource) override;
|
||||
|
||||
private:
|
||||
PointerInterface *pointer;
|
||||
QPointer<ClientConnection> focusedClient;
|
||||
};
|
||||
|
||||
} // namespace KWaylandServer
|
||||
|
|
|
@ -6,9 +6,12 @@
|
|||
*/
|
||||
|
||||
#include "relativepointer_v1_interface.h"
|
||||
#include "clientconnection.h"
|
||||
#include "display.h"
|
||||
#include "pointer_interface_p.h"
|
||||
#include "relativepointer_v1_interface_p.h"
|
||||
#include "seat_interface.h"
|
||||
#include "surface_interface.h"
|
||||
|
||||
namespace KWaylandServer
|
||||
{
|
||||
|
@ -34,15 +37,8 @@ void RelativePointerManagerV1InterfacePrivate::zwp_relative_pointer_manager_v1_g
|
|||
return;
|
||||
}
|
||||
|
||||
wl_resource *relativePointerResource = wl_resource_create(resource->client(),
|
||||
&zwp_relative_pointer_v1_interface,
|
||||
resource->version(), id);
|
||||
if (!relativePointerResource) {
|
||||
wl_resource_post_no_memory(resource->handle);
|
||||
return;
|
||||
}
|
||||
|
||||
new RelativePointerV1Interface(pointer, relativePointerResource);
|
||||
RelativePointerV1Interface *relativePointer = RelativePointerV1Interface::get(pointer);
|
||||
relativePointer->add(resource->client(), id, resource->version());
|
||||
}
|
||||
|
||||
RelativePointerManagerV1Interface::RelativePointerManagerV1Interface(Display *display, QObject *parent)
|
||||
|
@ -55,24 +51,18 @@ RelativePointerManagerV1Interface::~RelativePointerManagerV1Interface()
|
|||
{
|
||||
}
|
||||
|
||||
RelativePointerV1Interface::RelativePointerV1Interface(PointerInterface *pointer, ::wl_resource *resource)
|
||||
: QtWaylandServer::zwp_relative_pointer_v1(resource)
|
||||
, pointer(pointer)
|
||||
RelativePointerV1Interface::RelativePointerV1Interface(PointerInterface *pointer)
|
||||
: pointer(pointer)
|
||||
{
|
||||
pointer->d_func()->registerRelativePointerV1(this);
|
||||
}
|
||||
|
||||
RelativePointerV1Interface::~RelativePointerV1Interface()
|
||||
RelativePointerV1Interface *RelativePointerV1Interface::get(PointerInterface *pointer)
|
||||
{
|
||||
if (pointer) {
|
||||
pointer->d_func()->unregisterRelativePointerV1(this);
|
||||
PointerInterfacePrivate *pointerPrivate = PointerInterfacePrivate::get(pointer);
|
||||
return pointerPrivate->relativePointersV1.data();
|
||||
}
|
||||
}
|
||||
|
||||
void RelativePointerV1Interface::zwp_relative_pointer_v1_destroy_resource(Resource *resource)
|
||||
{
|
||||
Q_UNUSED(resource)
|
||||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void RelativePointerV1Interface::zwp_relative_pointer_v1_destroy(Resource *resource)
|
||||
|
@ -80,4 +70,24 @@ void RelativePointerV1Interface::zwp_relative_pointer_v1_destroy(Resource *resou
|
|||
wl_resource_destroy(resource->handle);
|
||||
}
|
||||
|
||||
void RelativePointerV1Interface::sendRelativeMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint64 microseconds)
|
||||
{
|
||||
if (!pointer->focusedSurface()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ClientConnection *focusedClient = pointer->focusedSurface()->client();
|
||||
const QList<Resource *> pointerResources = resourceMap().values(focusedClient->client());
|
||||
for (Resource *pointerResource : pointerResources) {
|
||||
if (pointerResource->client() == focusedClient->client()) {
|
||||
send_relative_motion(pointerResource->handle, microseconds >> 32, microseconds & 0xffffffff,
|
||||
wl_fixed_from_double(delta.width()),
|
||||
wl_fixed_from_double(delta.height()),
|
||||
wl_fixed_from_double(deltaNonAccelerated.width()),
|
||||
wl_fixed_from_double(deltaNonAccelerated.height()));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace KWaylandServer
|
||||
|
|
|
@ -9,11 +9,10 @@
|
|||
|
||||
#include "qwayland-server-relative-pointer-unstable-v1.h"
|
||||
|
||||
#include <QPointer>
|
||||
|
||||
namespace KWaylandServer
|
||||
{
|
||||
|
||||
class ClientConnection;
|
||||
class Display;
|
||||
class PointerInterface;
|
||||
|
||||
|
@ -31,14 +30,16 @@ protected:
|
|||
class RelativePointerV1Interface : public QtWaylandServer::zwp_relative_pointer_v1
|
||||
{
|
||||
public:
|
||||
RelativePointerV1Interface(PointerInterface *pointer, ::wl_resource *resource);
|
||||
~RelativePointerV1Interface() override;
|
||||
explicit RelativePointerV1Interface(PointerInterface *pointer);
|
||||
|
||||
QPointer<PointerInterface> pointer;
|
||||
static RelativePointerV1Interface *get(PointerInterface *pointer);
|
||||
void sendRelativeMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint64 microseconds);
|
||||
|
||||
protected:
|
||||
void zwp_relative_pointer_v1_destroy_resource(Resource *resource) override;
|
||||
void zwp_relative_pointer_v1_destroy(Resource *resource) override;
|
||||
|
||||
private:
|
||||
PointerInterface *pointer;
|
||||
};
|
||||
|
||||
} // namespace KWaylandServer
|
||||
|
|
|
@ -17,10 +17,13 @@
|
|||
#include "keyboard_interface.h"
|
||||
#include "keyboard_interface_p.h"
|
||||
#include "logging.h"
|
||||
#include "pointerconstraints_v1_interface.h"
|
||||
#include "pointergestures_v1_interface_p.h"
|
||||
#include "pointer_interface.h"
|
||||
#include "pointer_interface_p.h"
|
||||
#include "primaryselectiondevice_v1_interface.h"
|
||||
#include "primaryselectionsource_v1_interface.h"
|
||||
#include "relativepointer_v1_interface_p.h"
|
||||
#include "surface_interface.h"
|
||||
#include "textinput_v2_interface_p.h"
|
||||
#include "textinput_v3_interface_p.h"
|
||||
|
@ -233,11 +236,6 @@ bool forEachInterface(SurfaceInterface *surface, const QVector<T*> &interfaces,
|
|||
|
||||
}
|
||||
|
||||
QVector<PointerInterface *> SeatInterface::Private::pointersForSurface(SurfaceInterface *surface) const
|
||||
{
|
||||
return interfacesForSurface(surface, pointers);
|
||||
}
|
||||
|
||||
QVector<TouchInterface *> SeatInterface::Private::touchsForSurface(SurfaceInterface *surface) const
|
||||
{
|
||||
return interfacesForSurface(surface, touchs);
|
||||
|
@ -282,7 +280,6 @@ void SeatInterface::Private::registerDataDevice(DataDeviceInterface *dataDevice)
|
|||
auto *dragSurface = dataDevice->origin();
|
||||
if (q->hasImplicitPointerGrab(dragSerial)) {
|
||||
drag.mode = Drag::Mode::Pointer;
|
||||
drag.sourcePointer = interfaceForSurface(dragSurface, pointers);
|
||||
drag.transformation = globalPointer.focus.transformation;
|
||||
} else if (q->hasImplicitTouchGrab(dragSerial)) {
|
||||
drag.mode = Drag::Mode::Touch;
|
||||
|
@ -302,7 +299,6 @@ void SeatInterface::Private::registerDataDevice(DataDeviceInterface *dataDevice)
|
|||
drag.transformation = globalPointer.focus.transformation;
|
||||
}
|
||||
drag.source = dataDevice;
|
||||
drag.sourcePointer = interfaceForSurface(originSurface, pointers);
|
||||
drag.destroyConnection = QObject::connect(dataDevice, &DataDeviceInterface::aboutToBeDestroyed, q,
|
||||
[this] {
|
||||
cancelDrag(display->nextSerial());
|
||||
|
@ -479,10 +475,15 @@ void SeatInterface::setHasKeyboard(bool has)
|
|||
void SeatInterface::setHasPointer(bool has)
|
||||
{
|
||||
Q_D();
|
||||
if (d->pointer == has) {
|
||||
if (d->pointer.isNull() != has) {
|
||||
return;
|
||||
}
|
||||
d->pointer = has;
|
||||
if (has) {
|
||||
d->pointer.reset(new PointerInterface(this));
|
||||
} else {
|
||||
d->pointer.reset();
|
||||
}
|
||||
|
||||
emit hasPointerChanged(d->pointer);
|
||||
}
|
||||
|
||||
|
@ -513,37 +514,10 @@ void SeatInterface::Private::getPointerCallback(wl_client *client, wl_resource *
|
|||
|
||||
void SeatInterface::Private::getPointer(wl_client *client, wl_resource *resource, uint32_t id)
|
||||
{
|
||||
// TODO: only create if seat has pointer?
|
||||
PointerInterface *pointer = new PointerInterface(q, resource);
|
||||
auto clientConnection = display->getConnection(client);
|
||||
pointer->create(clientConnection, qMin(wl_resource_get_version(resource), s_pointerVersion), id);
|
||||
if (!pointer->resource()) {
|
||||
wl_resource_post_no_memory(resource);
|
||||
delete pointer;
|
||||
return;
|
||||
if (pointer) {
|
||||
PointerInterfacePrivate *pointerPrivate = PointerInterfacePrivate::get(pointer.data());
|
||||
pointerPrivate->add(client, id, wl_resource_get_version(resource));
|
||||
}
|
||||
pointers << pointer;
|
||||
if (globalPointer.focus.surface && globalPointer.focus.surface->client() == clientConnection) {
|
||||
// this is a pointer for the currently focused pointer surface
|
||||
globalPointer.focus.pointers << pointer;
|
||||
pointer->setFocusedSurface(globalPointer.focus.surface, globalPointer.focus.serial);
|
||||
pointer->d_func()->sendFrame();
|
||||
if (globalPointer.focus.pointers.count() == 1) {
|
||||
// got a new pointer
|
||||
emit q->focusedPointerChanged(pointer);
|
||||
}
|
||||
}
|
||||
QObject::connect(pointer, &QObject::destroyed, q,
|
||||
[pointer,this] {
|
||||
pointers.removeAt(pointers.indexOf(pointer));
|
||||
if (globalPointer.focus.pointers.removeOne(pointer)) {
|
||||
if (globalPointer.focus.pointers.isEmpty()) {
|
||||
emit q->focusedPointerChanged(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
emit q->pointerCreated(pointer);
|
||||
}
|
||||
|
||||
void SeatInterface::Private::getKeyboardCallback(wl_client *client, wl_resource *resource, uint32_t id)
|
||||
|
@ -642,6 +616,37 @@ void SeatInterface::setPointerPos(const QPointF &pos)
|
|||
}
|
||||
d->globalPointer.pos = pos;
|
||||
emit pointerPosChanged(pos);
|
||||
|
||||
SurfaceInterface *focusedSurface = focusedPointerSurface();
|
||||
if (!focusedSurface) {
|
||||
return;
|
||||
}
|
||||
if (isDragPointer()) {
|
||||
const auto *originSurface = dragSource()->origin();
|
||||
const bool proxyRemoteFocused = originSurface->dataProxy() && originSurface == focusedSurface;
|
||||
if (!proxyRemoteFocused) {
|
||||
// handled by DataDevice
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (focusedSurface->lockedPointer() && focusedSurface->lockedPointer()->isLocked()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QPointF localPosition = focusedPointerSurfaceTransformation().map(pos);
|
||||
SurfaceInterface *effectiveFocusedSurface = focusedSurface->inputSurfaceAt(localPosition);
|
||||
if (!effectiveFocusedSurface) {
|
||||
effectiveFocusedSurface = focusedSurface;
|
||||
}
|
||||
if (focusedSurface != effectiveFocusedSurface) {
|
||||
localPosition = focusedSurface->mapToChild(effectiveFocusedSurface, localPosition);
|
||||
}
|
||||
|
||||
if (d->pointer->focusedSurface() != effectiveFocusedSurface) {
|
||||
d->pointer->setFocusedSurface(effectiveFocusedSurface, localPosition, display()->nextSerial());
|
||||
}
|
||||
|
||||
d->pointer->sendMotion(localPosition);
|
||||
}
|
||||
|
||||
quint32 SeatInterface::timestamp() const
|
||||
|
@ -683,6 +688,7 @@ void SeatInterface::setDragTarget(SurfaceInterface *surface, const QPointF &glob
|
|||
|
||||
if (d->drag.mode == Private::Drag::Mode::Pointer) {
|
||||
setPointerPos(globalPosition);
|
||||
pointerFrame();
|
||||
} else if (d->drag.mode == Private::Drag::Mode::Touch &&
|
||||
d->globalTouch.focus.firstTouchPos != globalPosition) {
|
||||
touchMove(d->globalTouch.ids.first(), globalPosition);
|
||||
|
@ -734,58 +740,37 @@ void SeatInterface::setFocusedPointerSurface(SurfaceInterface *surface, const QM
|
|||
// ignore
|
||||
return;
|
||||
}
|
||||
|
||||
const quint32 serial = d->display->nextSerial();
|
||||
QSet<PointerInterface *> framePointers;
|
||||
for (auto it = d->globalPointer.focus.pointers.constBegin(), end = d->globalPointer.focus.pointers.constEnd(); it != end; ++it) {
|
||||
(*it)->setFocusedSurface(nullptr, serial);
|
||||
framePointers << *it;
|
||||
}
|
||||
|
||||
if (d->globalPointer.focus.surface) {
|
||||
disconnect(d->globalPointer.focus.destroyConnection);
|
||||
}
|
||||
d->globalPointer.focus = Private::Pointer::Focus();
|
||||
d->globalPointer.focus.surface = surface;
|
||||
auto p = d->pointersForSurface(surface);
|
||||
d->globalPointer.focus.pointers = p;
|
||||
if (d->globalPointer.focus.surface) {
|
||||
d->globalPointer.focus.destroyConnection = connect(surface, &QObject::destroyed, this,
|
||||
[this] {
|
||||
Q_D();
|
||||
d->globalPointer.focus = Private::Pointer::Focus();
|
||||
emit focusedPointerChanged(nullptr);
|
||||
}
|
||||
);
|
||||
d->globalPointer.focus.offset = QPointF();
|
||||
d->globalPointer.focus.transformation = transformation;
|
||||
d->globalPointer.focus.destroyConnection = connect(surface, &QObject::destroyed, this, [this] {
|
||||
Q_D();
|
||||
d->globalPointer.focus = Private::Pointer::Focus();
|
||||
});
|
||||
d->globalPointer.focus.serial = serial;
|
||||
d->globalPointer.focus.transformation = transformation;
|
||||
d->globalPointer.focus.offset = QPointF();
|
||||
}
|
||||
if (p.isEmpty()) {
|
||||
emit focusedPointerChanged(nullptr);
|
||||
for (auto p : qAsConst(framePointers))
|
||||
{
|
||||
p->d_func()->sendFrame();
|
||||
}
|
||||
return;
|
||||
}
|
||||
// TODO: signal with all pointers
|
||||
emit focusedPointerChanged(p.first());
|
||||
for (auto it = p.constBegin(), end = p.constEnd(); it != end; ++it) {
|
||||
(*it)->setFocusedSurface(surface, serial);
|
||||
framePointers << *it;
|
||||
}
|
||||
for (auto p : qAsConst(framePointers))
|
||||
{
|
||||
p->d_func()->sendFrame();
|
||||
}
|
||||
}
|
||||
|
||||
PointerInterface *SeatInterface::focusedPointer() const
|
||||
{
|
||||
Q_D();
|
||||
if (d->globalPointer.focus.pointers.isEmpty()) {
|
||||
return nullptr;
|
||||
if (surface) {
|
||||
QPointF localPosition = focusedPointerSurfaceTransformation().map(pointerPos());
|
||||
SurfaceInterface *effectiveFocusedSurface = surface->inputSurfaceAt(localPosition);
|
||||
if (!effectiveFocusedSurface) {
|
||||
effectiveFocusedSurface = surface;
|
||||
}
|
||||
if (surface != effectiveFocusedSurface) {
|
||||
localPosition = surface->mapToChild(effectiveFocusedSurface, localPosition);
|
||||
}
|
||||
d->pointer->setFocusedSurface(effectiveFocusedSurface, localPosition, serial);
|
||||
} else {
|
||||
d->pointer->setFocusedSurface(nullptr, QPointF(), serial);
|
||||
}
|
||||
return d->globalPointer.focus.pointers.first();
|
||||
}
|
||||
|
||||
void SeatInterface::setFocusedPointerSurfacePosition(const QPointF &surfacePosition)
|
||||
|
@ -818,6 +803,12 @@ QMatrix4x4 SeatInterface::focusedPointerSurfaceTransformation() const
|
|||
return d->globalPointer.focus.transformation;
|
||||
}
|
||||
|
||||
PointerInterface *SeatInterface::pointer() const
|
||||
{
|
||||
Q_D();
|
||||
return d->pointer.data();
|
||||
}
|
||||
|
||||
namespace {
|
||||
static quint32 qtToWaylandButton(Qt::MouseButton button)
|
||||
{
|
||||
|
@ -863,32 +854,15 @@ bool SeatInterface::isPointerButtonPressed(quint32 button) const
|
|||
return it.value() == Private::Pointer::State::Pressed ? true : false;
|
||||
}
|
||||
|
||||
void SeatInterface::pointerAxisV5(Qt::Orientation orientation, qreal delta, qint32 discreteDelta, PointerAxisSource source)
|
||||
void SeatInterface::pointerAxis(Qt::Orientation orientation, qreal delta, qint32 discreteDelta, PointerAxisSource source)
|
||||
{
|
||||
Q_D();
|
||||
Q_ASSERT(d->pointer);
|
||||
if (d->drag.mode == Private::Drag::Mode::Pointer) {
|
||||
// ignore
|
||||
return;
|
||||
}
|
||||
if (d->globalPointer.focus.surface) {
|
||||
for (auto it = d->globalPointer.focus.pointers.constBegin(), end = d->globalPointer.focus.pointers.constEnd(); it != end; ++it) {
|
||||
(*it)->axis(orientation, delta, discreteDelta, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SeatInterface::pointerAxis(Qt::Orientation orientation, quint32 delta)
|
||||
{
|
||||
Q_D();
|
||||
if (d->drag.mode == Private::Drag::Mode::Pointer) {
|
||||
// ignore
|
||||
return;
|
||||
}
|
||||
if (d->globalPointer.focus.surface) {
|
||||
for (auto it = d->globalPointer.focus.pointers.constBegin(), end = d->globalPointer.focus.pointers.constEnd(); it != end; ++it) {
|
||||
(*it)->axis(orientation, delta);
|
||||
}
|
||||
}
|
||||
d->pointer->sendAxis(orientation, delta, discreteDelta, source);
|
||||
}
|
||||
|
||||
void SeatInterface::pointerButtonPressed(Qt::MouseButton button)
|
||||
|
@ -903,6 +877,7 @@ void SeatInterface::pointerButtonPressed(Qt::MouseButton button)
|
|||
void SeatInterface::pointerButtonPressed(quint32 button)
|
||||
{
|
||||
Q_D();
|
||||
Q_ASSERT(d->pointer);
|
||||
const quint32 serial = d->display->nextSerial();
|
||||
d->updatePointerButtonSerial(button, serial);
|
||||
d->updatePointerButtonState(button, Private::Pointer::State::Pressed);
|
||||
|
@ -910,16 +885,11 @@ void SeatInterface::pointerButtonPressed(quint32 button)
|
|||
// ignore
|
||||
return;
|
||||
}
|
||||
if (auto *focusSurface = d->globalPointer.focus.surface) {
|
||||
for (auto it = d->globalPointer.focus.pointers.constBegin(), end = d->globalPointer.focus.pointers.constEnd(); it != end; ++it) {
|
||||
(*it)->buttonPressed(button, serial);
|
||||
}
|
||||
if (focusSurface == d->globalKeyboard.focus.surface) {
|
||||
// update the focused child surface
|
||||
auto p = focusedPointer();
|
||||
if (p && d->keyboard) {
|
||||
d->keyboard->d->focusChildSurface(p->d_func()->focusedChildSurface, serial);
|
||||
}
|
||||
d->pointer->sendPressed(button, serial);
|
||||
|
||||
if (focusedPointerSurface() == focusedKeyboardSurface()) {
|
||||
if (d->keyboard) {
|
||||
d->keyboard->setFocusedSurface(d->pointer->focusedSurface(), serial);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -936,6 +906,7 @@ void SeatInterface::pointerButtonReleased(Qt::MouseButton button)
|
|||
void SeatInterface::pointerButtonReleased(quint32 button)
|
||||
{
|
||||
Q_D();
|
||||
Q_ASSERT(d->pointer);
|
||||
const quint32 serial = d->display->nextSerial();
|
||||
const quint32 currentButtonSerial = pointerButtonSerial(button);
|
||||
d->updatePointerButtonSerial(button, serial);
|
||||
|
@ -948,11 +919,14 @@ void SeatInterface::pointerButtonReleased(quint32 button)
|
|||
d->endDrag(serial);
|
||||
return;
|
||||
}
|
||||
if (d->globalPointer.focus.surface) {
|
||||
for (auto it = d->globalPointer.focus.pointers.constBegin(), end = d->globalPointer.focus.pointers.constEnd(); it != end; ++it) {
|
||||
(*it)->buttonReleased(button, serial);
|
||||
}
|
||||
}
|
||||
d->pointer->sendReleased(button, serial);
|
||||
}
|
||||
|
||||
void SeatInterface::pointerFrame()
|
||||
{
|
||||
Q_D();
|
||||
Q_ASSERT(d->pointer);
|
||||
d->pointer->sendFrame();
|
||||
}
|
||||
|
||||
quint32 SeatInterface::pointerButtonSerial(Qt::MouseButton button) const
|
||||
|
@ -973,133 +947,100 @@ quint32 SeatInterface::pointerButtonSerial(quint32 button) const
|
|||
void SeatInterface::relativePointerMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint64 microseconds)
|
||||
{
|
||||
Q_D();
|
||||
if (d->globalPointer.focus.surface) {
|
||||
for (auto it = d->globalPointer.focus.pointers.constBegin(), end = d->globalPointer.focus.pointers.constEnd(); it != end; ++it) {
|
||||
(*it)->relativeMotion(delta, deltaNonAccelerated, microseconds);
|
||||
}
|
||||
Q_ASSERT(d->pointer);
|
||||
|
||||
auto relativePointer = RelativePointerV1Interface::get(pointer());
|
||||
if (relativePointer) {
|
||||
relativePointer->sendRelativeMotion(delta, deltaNonAccelerated, microseconds);
|
||||
}
|
||||
}
|
||||
|
||||
void SeatInterface::startPointerSwipeGesture(quint32 fingerCount)
|
||||
{
|
||||
Q_D();
|
||||
if (!d->globalPointer.gestureSurface.isNull()) {
|
||||
return;
|
||||
Q_ASSERT(d->pointer);
|
||||
|
||||
auto swipeGesture = PointerSwipeGestureV1Interface::get(pointer());
|
||||
if (swipeGesture) {
|
||||
swipeGesture->sendBegin(d->display->nextSerial(), fingerCount);
|
||||
}
|
||||
d->globalPointer.gestureSurface = QPointer<SurfaceInterface>(d->globalPointer.focus.surface);
|
||||
if (d->globalPointer.gestureSurface.isNull()) {
|
||||
return;
|
||||
}
|
||||
const quint32 serial = d->display->nextSerial();
|
||||
forEachInterface<PointerInterface>(d->globalPointer.gestureSurface.data(), d->pointers,
|
||||
[serial, fingerCount] (PointerInterface *p) {
|
||||
p->d_func()->startSwipeGesture(serial, fingerCount);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void SeatInterface::updatePointerSwipeGesture(const QSizeF &delta)
|
||||
{
|
||||
Q_D();
|
||||
if (d->globalPointer.gestureSurface.isNull()) {
|
||||
return;
|
||||
Q_ASSERT(d->pointer);
|
||||
|
||||
auto swipeGesture = PointerSwipeGestureV1Interface::get(pointer());
|
||||
if (swipeGesture) {
|
||||
swipeGesture->sendUpdate(delta);
|
||||
}
|
||||
forEachInterface<PointerInterface>(d->globalPointer.gestureSurface.data(), d->pointers,
|
||||
[delta] (PointerInterface *p) {
|
||||
p->d_func()->updateSwipeGesture(delta);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void SeatInterface::endPointerSwipeGesture()
|
||||
{
|
||||
Q_D();
|
||||
if (d->globalPointer.gestureSurface.isNull()) {
|
||||
return;
|
||||
Q_ASSERT(d->pointer);
|
||||
|
||||
auto swipeGesture = PointerSwipeGestureV1Interface::get(pointer());
|
||||
if (swipeGesture) {
|
||||
swipeGesture->sendEnd(d->display->nextSerial());
|
||||
}
|
||||
const quint32 serial = d->display->nextSerial();
|
||||
forEachInterface<PointerInterface>(d->globalPointer.gestureSurface.data(), d->pointers,
|
||||
[serial] (PointerInterface *p) {
|
||||
p->d_func()->endSwipeGesture(serial);
|
||||
}
|
||||
);
|
||||
d->globalPointer.gestureSurface.clear();
|
||||
}
|
||||
|
||||
void SeatInterface::cancelPointerSwipeGesture()
|
||||
{
|
||||
Q_D();
|
||||
if (d->globalPointer.gestureSurface.isNull()) {
|
||||
return;
|
||||
Q_ASSERT(d->pointer);
|
||||
|
||||
auto swipeGesture = PointerSwipeGestureV1Interface::get(pointer());
|
||||
if (swipeGesture) {
|
||||
swipeGesture->sendCancel(d->display->nextSerial());
|
||||
}
|
||||
const quint32 serial = d->display->nextSerial();
|
||||
forEachInterface<PointerInterface>(d->globalPointer.gestureSurface.data(), d->pointers,
|
||||
[serial] (PointerInterface *p) {
|
||||
p->d_func()->cancelSwipeGesture(serial);
|
||||
}
|
||||
);
|
||||
d->globalPointer.gestureSurface.clear();
|
||||
}
|
||||
|
||||
void SeatInterface::startPointerPinchGesture(quint32 fingerCount)
|
||||
{
|
||||
Q_D();
|
||||
if (!d->globalPointer.gestureSurface.isNull()) {
|
||||
return;
|
||||
Q_ASSERT(d->pointer);
|
||||
|
||||
auto pinchGesture = PointerPinchGestureV1Interface::get(pointer());
|
||||
if (pinchGesture) {
|
||||
pinchGesture->sendBegin(d->display->nextSerial(), fingerCount);
|
||||
}
|
||||
d->globalPointer.gestureSurface = QPointer<SurfaceInterface>(d->globalPointer.focus.surface);
|
||||
if (d->globalPointer.gestureSurface.isNull()) {
|
||||
return;
|
||||
}
|
||||
const quint32 serial = d->display->nextSerial();
|
||||
forEachInterface<PointerInterface>(d->globalPointer.gestureSurface.data(), d->pointers,
|
||||
[serial, fingerCount] (PointerInterface *p) {
|
||||
p->d_func()->startPinchGesture(serial, fingerCount);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void SeatInterface::updatePointerPinchGesture(const QSizeF &delta, qreal scale, qreal rotation)
|
||||
{
|
||||
Q_D();
|
||||
if (d->globalPointer.gestureSurface.isNull()) {
|
||||
return;
|
||||
Q_ASSERT(d->pointer);
|
||||
|
||||
auto pinchGesture = PointerPinchGestureV1Interface::get(pointer());
|
||||
if (pinchGesture) {
|
||||
pinchGesture->sendUpdate(delta, scale, rotation);
|
||||
}
|
||||
forEachInterface<PointerInterface>(d->globalPointer.gestureSurface.data(), d->pointers,
|
||||
[delta, scale, rotation] (PointerInterface *p) {
|
||||
p->d_func()->updatePinchGesture(delta, scale, rotation);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void SeatInterface::endPointerPinchGesture()
|
||||
{
|
||||
Q_D();
|
||||
if (d->globalPointer.gestureSurface.isNull()) {
|
||||
return;
|
||||
Q_ASSERT(d->pointer);
|
||||
|
||||
auto pinchGesture = PointerPinchGestureV1Interface::get(pointer());
|
||||
if (pinchGesture) {
|
||||
pinchGesture->sendEnd(d->display->nextSerial());
|
||||
}
|
||||
const quint32 serial = d->display->nextSerial();
|
||||
forEachInterface<PointerInterface>(d->globalPointer.gestureSurface.data(), d->pointers,
|
||||
[serial] (PointerInterface *p) {
|
||||
p->d_func()->endPinchGesture(serial);
|
||||
}
|
||||
);
|
||||
d->globalPointer.gestureSurface.clear();
|
||||
}
|
||||
|
||||
void SeatInterface::cancelPointerPinchGesture()
|
||||
{
|
||||
Q_D();
|
||||
if (d->globalPointer.gestureSurface.isNull()) {
|
||||
return;
|
||||
Q_ASSERT(d->pointer);
|
||||
|
||||
auto pinchGesture = PointerPinchGestureV1Interface::get(pointer());
|
||||
if (pinchGesture) {
|
||||
pinchGesture->sendCancel(d->display->nextSerial());
|
||||
}
|
||||
const quint32 serial = d->display->nextSerial();
|
||||
forEachInterface<PointerInterface>(d->globalPointer.gestureSurface.data(), d->pointers,
|
||||
[serial] (PointerInterface *p) {
|
||||
p->d_func()->cancelPinchGesture(serial);
|
||||
}
|
||||
);
|
||||
d->globalPointer.gestureSurface.clear();
|
||||
}
|
||||
|
||||
SurfaceInterface *SeatInterface::focusedKeyboardSurface() const
|
||||
|
@ -1267,18 +1208,9 @@ void SeatInterface::touchDown(qint32 id, const QPointF &globalPosition)
|
|||
if (id == 0 && d->globalTouch.focus.touchs.isEmpty()) {
|
||||
// If the client did not bind the touch interface fall back
|
||||
// to at least emulating touch through pointer events.
|
||||
forEachInterface<PointerInterface>(focusedTouchSurface(), d->pointers,
|
||||
[this, pos, serial] (PointerInterface *p) {
|
||||
wl_pointer_send_enter(p->resource(), serial,
|
||||
focusedTouchSurface()->resource(),
|
||||
wl_fixed_from_double(pos.x()), wl_fixed_from_double(pos.y()));
|
||||
wl_pointer_send_motion(p->resource(), timestamp(),
|
||||
wl_fixed_from_double(pos.x()), wl_fixed_from_double(pos.y()));
|
||||
|
||||
wl_pointer_send_button(p->resource(), serial, timestamp(), BTN_LEFT, WL_POINTER_BUTTON_STATE_PRESSED);
|
||||
p->d_func()->sendFrame();
|
||||
}
|
||||
);
|
||||
d->pointer->setFocusedSurface(focusedTouchSurface(), pos, serial);
|
||||
d->pointer->sendMotion(pos);
|
||||
d->pointer->sendFrame();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1300,13 +1232,8 @@ void SeatInterface::touchMove(qint32 id, const QPointF &globalPosition)
|
|||
|
||||
if (id == 0 && d->globalTouch.focus.touchs.isEmpty()) {
|
||||
// Client did not bind touch, fall back to emulating with pointer events.
|
||||
forEachInterface<PointerInterface>(focusedTouchSurface(), d->pointers,
|
||||
[this, pos] (PointerInterface *p) {
|
||||
wl_pointer_send_motion(p->resource(), timestamp(),
|
||||
wl_fixed_from_double(pos.x()), wl_fixed_from_double(pos.y()));
|
||||
p->d_func()->sendFrame();
|
||||
}
|
||||
);
|
||||
d->pointer->sendMotion(pos);
|
||||
d->pointer->sendFrame();
|
||||
}
|
||||
emit touchMoved(id, d->globalTouch.ids[id], globalPosition);
|
||||
}
|
||||
|
@ -1329,12 +1256,8 @@ void SeatInterface::touchUp(qint32 id)
|
|||
if (id == 0 && d->globalTouch.focus.touchs.isEmpty()) {
|
||||
// Client did not bind touch, fall back to emulating with pointer events.
|
||||
const quint32 serial = display()->nextSerial();
|
||||
forEachInterface<PointerInterface>(focusedTouchSurface(), d->pointers,
|
||||
[this, serial] (PointerInterface *p) {
|
||||
wl_pointer_send_button(p->resource(), serial, timestamp(), BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED);
|
||||
p->d_func()->sendFrame();
|
||||
}
|
||||
);
|
||||
d->pointer->sendReleased(BTN_LEFT, serial);
|
||||
d->pointer->sendFrame();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1401,16 +1324,6 @@ SurfaceInterface *SeatInterface::dragSurface() const
|
|||
return d->drag.surface;
|
||||
}
|
||||
|
||||
PointerInterface *SeatInterface::dragPointer() const
|
||||
{
|
||||
Q_D();
|
||||
if (d->drag.mode != Private::Drag::Mode::Pointer) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return d->drag.sourcePointer;
|
||||
}
|
||||
|
||||
DataDeviceInterface *SeatInterface::dragSource() const
|
||||
{
|
||||
Q_D();
|
||||
|
|
|
@ -90,10 +90,13 @@ enum class PointerAxisSource {
|
|||
* seat->setFocusedPointerSurface(surface, QPointF(100, 200)); // surface at it's global position
|
||||
* seat->setTimestamp(100);
|
||||
* seat->setPointerPos(QPointF(350, 210)); // global pos, local pos in surface: 250,10
|
||||
* seat->pointerFrame();
|
||||
* seat->setTimestamp(110);
|
||||
* seat->pointerButtonPressed(Qt::LeftButton);
|
||||
* seat->pointerFrame();
|
||||
* seat->setTimestamp(120);
|
||||
* seat->pointerButtonReleased(Qt::LeftButton);
|
||||
* seat->pointerFrame();
|
||||
* @endcode
|
||||
*
|
||||
* @see KeyboardInterface
|
||||
|
@ -190,12 +193,6 @@ public:
|
|||
* @see dragSurfaceChanged
|
||||
**/
|
||||
SurfaceInterface *dragSurface() const;
|
||||
/**
|
||||
* @returns The PointerInterface which triggered the drag operation
|
||||
* @since 5.6
|
||||
* @see isDragPointer
|
||||
**/
|
||||
PointerInterface *dragPointer() const;
|
||||
/**
|
||||
* @returns The DataDeviceInterface which started the drag and drop operation.
|
||||
* @see isDrag
|
||||
|
@ -291,11 +288,7 @@ public:
|
|||
* @see setFocusedPointerSurface
|
||||
**/
|
||||
SurfaceInterface *focusedPointerSurface() const;
|
||||
/**
|
||||
* @returns The PointerInterface belonging to the focused pointer surface, if any.
|
||||
* @see setFocusedPointerSurface
|
||||
**/
|
||||
PointerInterface *focusedPointer() const;
|
||||
PointerInterface *pointer() const;
|
||||
/**
|
||||
* Updates the global position of the currently focused pointer surface.
|
||||
*
|
||||
|
@ -348,6 +341,7 @@ public:
|
|||
* @overload
|
||||
**/
|
||||
void pointerButtonPressed(Qt::MouseButton button);
|
||||
void pointerFrame();
|
||||
/**
|
||||
* Marks the @p button as released.
|
||||
*
|
||||
|
@ -384,13 +378,8 @@ public:
|
|||
* @param discreteDelta The number of discrete steps, e.g. mouse wheel clicks.
|
||||
* @param source Describes how the axis event was physically generated.
|
||||
* @since 5.59
|
||||
* @todo Drop V5 suffix with KF6.
|
||||
**/
|
||||
void pointerAxisV5(Qt::Orientation orientation, qreal delta, qint32 discreteDelta, PointerAxisSource source);
|
||||
/**
|
||||
* @see pointerAxisV5
|
||||
**/
|
||||
void pointerAxis(Qt::Orientation orientation, quint32 delta);
|
||||
void pointerAxis(Qt::Orientation orientation, qreal delta, qint32 discreteDelta, PointerAxisSource source);
|
||||
/**
|
||||
* @returns true if there is a pressed button with the given @p serial
|
||||
* @since 5.6
|
||||
|
@ -664,16 +653,9 @@ Q_SIGNALS:
|
|||
void touchMoved(qint32 id, quint32 serial, const QPointF &globalPosition);
|
||||
void timestampChanged(quint32);
|
||||
|
||||
void pointerCreated(KWaylandServer::PointerInterface*);
|
||||
void keyboardCreated(KWaylandServer::KeyboardInterface*);
|
||||
void touchCreated(KWaylandServer::TouchInterface*);
|
||||
|
||||
/**
|
||||
* Emitted whenever the focused pointer changes
|
||||
* @since 5.6
|
||||
**/
|
||||
void focusedPointerChanged(KWaylandServer::PointerInterface*);
|
||||
|
||||
/**
|
||||
* Emitted whenever the selection changes
|
||||
* @since 5.56
|
||||
|
|
|
@ -34,7 +34,6 @@ public:
|
|||
void bind(wl_client *client, uint32_t version, uint32_t id) override;
|
||||
void sendCapabilities(wl_resource *r);
|
||||
void sendName(wl_resource *r);
|
||||
QVector<PointerInterface *> pointersForSurface(SurfaceInterface *surface) const;
|
||||
QVector<TouchInterface *> touchsForSurface(SurfaceInterface *surface) const;
|
||||
QVector<DataDeviceInterface *> dataDevicesForSurface(SurfaceInterface *surface) const;
|
||||
void registerPrimarySelectionDevice(PrimarySelectionDeviceV1Interface *primarySelectionDevice);
|
||||
|
@ -45,12 +44,11 @@ public:
|
|||
quint32 nextSerial() const;
|
||||
|
||||
QString name;
|
||||
bool pointer = false;
|
||||
bool touch = false;
|
||||
QList<wl_resource*> resources;
|
||||
quint32 timestamp = 0;
|
||||
QVector<PointerInterface*> pointers;
|
||||
QScopedPointer<KeyboardInterface> keyboard;
|
||||
QScopedPointer<PointerInterface> pointer;
|
||||
QVector<TouchInterface*> touchs;
|
||||
QVector<DataDeviceInterface*> dataDevices;
|
||||
QVector<PrimarySelectionDeviceV1Interface*> primarySelectionDevices;
|
||||
|
@ -78,14 +76,12 @@ public:
|
|||
QPointF pos;
|
||||
struct Focus {
|
||||
SurfaceInterface *surface = nullptr;
|
||||
QVector<PointerInterface *> pointers;
|
||||
QMetaObject::Connection destroyConnection;
|
||||
QPointF offset = QPointF();
|
||||
QMatrix4x4 transformation;
|
||||
quint32 serial = 0;
|
||||
};
|
||||
Focus focus;
|
||||
QPointer<SurfaceInterface> gestureSurface;
|
||||
};
|
||||
Pointer globalPointer;
|
||||
void updatePointerButtonSerial(quint32 button, quint32 serial);
|
||||
|
@ -128,7 +124,6 @@ public:
|
|||
DataDeviceInterface *source = nullptr;
|
||||
QPointer<DataDeviceInterface> target;
|
||||
SurfaceInterface *surface = nullptr;
|
||||
PointerInterface *sourcePointer = nullptr;
|
||||
TouchInterface *sourceTouch = nullptr;
|
||||
QMatrix4x4 transformation;
|
||||
QMetaObject::Connection destroyConnection;
|
||||
|
|
|
@ -191,6 +191,7 @@ void CompositorWindow::mouseMoveEvent(QMouseEvent *event)
|
|||
}
|
||||
m_seat->setTimestamp(event->timestamp());
|
||||
m_seat->setPointerPos(event->localPos().toPoint());
|
||||
m_seat->pointerFrame();
|
||||
}
|
||||
|
||||
void CompositorWindow::mousePressEvent(QMouseEvent *event)
|
||||
|
@ -203,6 +204,7 @@ void CompositorWindow::mousePressEvent(QMouseEvent *event)
|
|||
}
|
||||
m_seat->setTimestamp(event->timestamp());
|
||||
m_seat->pointerButtonPressed(event->button());
|
||||
m_seat->pointerFrame();
|
||||
}
|
||||
|
||||
void CompositorWindow::mouseReleaseEvent(QMouseEvent *event)
|
||||
|
@ -210,6 +212,7 @@ void CompositorWindow::mouseReleaseEvent(QMouseEvent *event)
|
|||
QWidget::mouseReleaseEvent(event);
|
||||
m_seat->setTimestamp(event->timestamp());
|
||||
m_seat->pointerButtonReleased(event->button());
|
||||
m_seat->pointerFrame();
|
||||
}
|
||||
|
||||
void CompositorWindow::wheelEvent(QWheelEvent *event)
|
||||
|
@ -218,11 +221,12 @@ void CompositorWindow::wheelEvent(QWheelEvent *event)
|
|||
m_seat->setTimestamp(event->timestamp());
|
||||
const QPoint &angle = event->angleDelta() / (8 * 15);
|
||||
if (angle.x() != 0) {
|
||||
m_seat->pointerAxis(Qt::Horizontal, angle.x());
|
||||
m_seat->pointerAxis(Qt::Horizontal, angle.x(), 1, KWaylandServer::PointerAxisSource::Wheel);
|
||||
}
|
||||
if (angle.y() != 0) {
|
||||
m_seat->pointerAxis(Qt::Vertical, angle.y());
|
||||
m_seat->pointerAxis(Qt::Vertical, angle.y(), 1, KWaylandServer::PointerAxisSource::Wheel);
|
||||
}
|
||||
m_seat->pointerFrame();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
|
Loading…
Reference in a new issue