Commit 9f3d6c8f authored by Martin Flöser's avatar Martin Flöser
Browse files

[server] Cancel previous selection from SeatInterface::setSelection

Summary:
When changing the selection the previous selection needs to be
cancelled. This is already done in the "normal" updating of the
selection. If the previous selection doesn't get cancelled QtWayland is
not able to accept anything new from the clipboard. The setSelection
didn't cancel it yet, due to that copy from Xwayland to QtWayland
windows doesn't work in KWin as KWin uses the setSelection call for the
Xwayland clipboard.

With this change the cancelling of previous selection is moved into a
dedicated method and called from the normal way and the setSelection
way.

Reviewers: #plasma_on_wayland, bshah

Subscribers: plasma-devel

Tags: #plasma_on_wayland

Differential Revision: https://phabricator.kde.org/D2997
parent 25dbc84d
......@@ -1487,6 +1487,19 @@ void TestWaylandSeat::testSelection()
m_seatInterface->setSelection(nullptr);
QVERIFY(selectionClearedSpy.wait());
QCOMPARE(selectionSpy.count(), 2);
// create a second ddi and a data source
QScopedPointer<DataDevice> dd2(ddm->getDataDevice(m_seat));
QVERIFY(dd2->isValid());
QScopedPointer<DataSource> ds2(ddm->createDataSource());
QVERIFY(ds2->isValid());
ds2->offer(QStringLiteral("text/plain"));
dd2->setSelection(0, ds2.data());
QVERIFY(selectionSpy.wait());
QSignalSpy cancelledSpy(ds2.data(), &DataSource::cancelled);
QVERIFY(cancelledSpy.isValid());
m_seatInterface->setSelection(ddi);
QVERIFY(cancelledSpy.wait());
}
void TestWaylandSeat::testTouch()
......
......@@ -339,19 +339,25 @@ void SeatInterface::Private::endDrag(quint32 serial)
emit q->dragEnded();
}
void SeatInterface::Private::cancelPreviousSelection(DataDeviceInterface *dataDevice)
{
if (!currentSelection) {
return;
}
if (auto s = currentSelection->selection()) {
if (currentSelection != dataDevice) {
// only if current selection is not on the same device
// that would cancel the newly set source
s->cancel();
}
}
}
void SeatInterface::Private::updateSelection(DataDeviceInterface *dataDevice, bool set)
{
if (keys.focus.surface && (keys.focus.surface->client() == dataDevice->client())) {
if (currentSelection) {
// cancel the previous selection
if (auto s = currentSelection->selection()) {
if (currentSelection != dataDevice) {
// only if current selection is not on the same device
// that would cancel the newly set source
s->cancel();
}
}
}
// cancel the previous selection
cancelPreviousSelection(dataDevice);
// new selection on a data device belonging to current keyboard focus
currentSelection = dataDevice;
}
......@@ -1303,6 +1309,8 @@ void SeatInterface::setSelection(DataDeviceInterface *dataDevice)
if (d->currentSelection == dataDevice) {
return;
}
// cancel the previous selection
d->cancelPreviousSelection(dataDevice);
d->currentSelection = dataDevice;
if (d->keys.focus.selection) {
if (dataDevice) {
......
......@@ -51,6 +51,7 @@ public:
void registerDataDevice(DataDeviceInterface *dataDevice);
void registerTextInput(TextInputInterface *textInput);
void endDrag(quint32 serial);
void cancelPreviousSelection(DataDeviceInterface *newlySelectedDataDevice);
QString name;
bool pointer = false;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment