diff --git a/src/wayland/autotests/client/test_datadevice.cpp b/src/wayland/autotests/client/test_datadevice.cpp index 0fef6f96f9..12767ce8bc 100644 --- a/src/wayland/autotests/client/test_datadevice.cpp +++ b/src/wayland/autotests/client/test_datadevice.cpp @@ -194,11 +194,16 @@ void TestDataDevice::testCreate() QVERIFY(!deviceInterface->selection()); QVERIFY(deviceInterface->parentResource()); + QVERIFY(!m_seatInterface->selection()); + m_seatInterface->setSelection(deviceInterface); + QCOMPARE(m_seatInterface->selection(), deviceInterface); + // and destroy QSignalSpy destroyedSpy(deviceInterface, &QObject::destroyed); QVERIFY(destroyedSpy.isValid()); dataDevice.reset(); QVERIFY(destroyedSpy.wait()); + QVERIFY(!m_seatInterface->selection()); } void TestDataDevice::testDrag() diff --git a/src/wayland/autotests/client/test_wayland_seat.cpp b/src/wayland/autotests/client/test_wayland_seat.cpp index c8d50fed5d..e510be9e5d 100644 --- a/src/wayland/autotests/client/test_wayland_seat.cpp +++ b/src/wayland/autotests/client/test_wayland_seat.cpp @@ -1306,6 +1306,7 @@ void TestWaylandSeat::testSelection() QVERIFY(surface->isValid()); QVERIFY(surfaceCreatedSpy.wait()); auto serverSurface = surfaceCreatedSpy.first().first().value(); + QVERIFY(!m_seatInterface->selection()); m_seatInterface->setFocusedKeyboardSurface(serverSurface); QCOMPARE(m_seatInterface->focusedKeyboardSurface(), serverSurface); QVERIFY(!m_seatInterface->focusedKeyboard()); @@ -1314,6 +1315,7 @@ void TestWaylandSeat::testSelection() QCoreApplication::processEvents(); QVERIFY(selectionSpy.isEmpty()); QVERIFY(selectionClearedSpy.isEmpty()); + QVERIFY(!m_seatInterface->selection()); // now let's try to set a selection - we have keyboard focus, so it should be sent to us QScopedPointer ds(ddm->createDataSource()); @@ -1322,6 +1324,8 @@ void TestWaylandSeat::testSelection() dd1->setSelection(0, ds.data()); QVERIFY(selectionSpy.wait()); QCOMPARE(selectionSpy.count(), 1); + auto ddi = m_seatInterface->selection(); + QVERIFY(ddi); QVERIFY(selectionClearedSpy.isEmpty()); auto df = selectionSpy.first().first().value(); QCOMPARE(df->offeredMimeTypes().count(), 1); @@ -1347,6 +1351,21 @@ void TestWaylandSeat::testSelection() QCoreApplication::processEvents(); QCoreApplication::processEvents(); QCOMPARE(selectionSpy.count(), 1); + + // let's unset the selection on the seat + m_seatInterface->setSelection(nullptr); + // and pass focus back on our surface + m_seatInterface->setFocusedKeyboardSurface(serverSurface); + // we don't have a selection, so it should not send a selection + QVERIFY(!selectionSpy.wait(100)); + // now let's set it manually + m_seatInterface->setSelection(ddi); + QCOMPARE(m_seatInterface->selection(), ddi); + QVERIFY(selectionSpy.wait()); + QCOMPARE(selectionSpy.count(), 2); + // now clear it manully + m_seatInterface->setSelection(nullptr); + QVERIFY(selectionClearedSpy.wait()); } void TestWaylandSeat::testTouch() diff --git a/src/wayland/seat_interface.cpp b/src/wayland/seat_interface.cpp index 30cf8841fc..ca0c53ea53 100644 --- a/src/wayland/seat_interface.cpp +++ b/src/wayland/seat_interface.cpp @@ -1239,5 +1239,27 @@ TextInputInterface *SeatInterface::focusedTextInput() const return d->textInput.focus.textInput; } +DataDeviceInterface *SeatInterface::selection() const +{ + Q_D(); + return d->currentSelection; +} + +void SeatInterface::setSelection(DataDeviceInterface *dataDevice) +{ + Q_D(); + if (d->currentSelection == dataDevice) { + return; + } + d->currentSelection = dataDevice; + if (d->keys.focus.selection) { + if (dataDevice) { + d->keys.focus.selection->sendSelection(dataDevice); + } else { + d->keys.focus.selection->sendClearSelection(); + } + } +} + } } diff --git a/src/wayland/seat_interface.h b/src/wayland/seat_interface.h index 09d4e2b2b8..b5808f4d69 100644 --- a/src/wayland/seat_interface.h +++ b/src/wayland/seat_interface.h @@ -490,6 +490,26 @@ public: TextInputInterface *focusedTextInput() const; ///@} + /** + * @returns The DataDeviceInterface holding the current clipboard selection. + * @since 5.24 + * @see setSelection + **/ + DataDeviceInterface *selection() const; + /** + * This method allows to manually set the @p dataDevice for the current clipboard selection. + * The clipboard selection is handled automatically in SeatInterface. + * If a DataDeviceInterface belonging to the current focused KeyboardInterface + * sets a selection, the current clipboard selection will be updated automatically. + * With this method it's possible to override the automatic clipboard update for + * e.g. the case of a clipboard manager. + * + * @param dataDevice Sets the current clipboard selection. + * @see selection + * @since 5.24 + **/ + void setSelection(DataDeviceInterface *dataDevice); + static SeatInterface *get(wl_resource *native); Q_SIGNALS: