[server] Add support for setting the clipboard selection DataDeviceInterface manually

Summary:
So far SeatInterface handled automatically which DataDeviceInterface
holds the current clipboard selection. While this works fine and is
correct it doesn't support use cases like a clipboard manager where
the clipboard is hold by a different ClientConnection than the one
from the focused keyboard.

This change allows to manually set the selected DataDeviceInterface
to override the automatic selection, though the automatic selection
is still in place. Thus the next update of a selection will override
the manually set selection again.

Reviewers: #plasma_on_wayland

Subscribers: plasma-devel

Tags: #plasma_on_wayland

Differential Revision: https://phabricator.kde.org/D1972
This commit is contained in:
Martin Gräßlin 2016-06-21 11:14:46 +02:00
parent db602b8188
commit 59bfac50ba
4 changed files with 66 additions and 0 deletions

View file

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

View file

@ -1306,6 +1306,7 @@ void TestWaylandSeat::testSelection()
QVERIFY(surface->isValid());
QVERIFY(surfaceCreatedSpy.wait());
auto serverSurface = surfaceCreatedSpy.first().first().value<SurfaceInterface*>();
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<DataSource> 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<DataOffer*>();
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()

View file

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

View file

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