From 918cc075b9c4ebdf40c985dd17a087e151d88dba Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Mon, 14 Oct 2019 11:10:42 +0200 Subject: [PATCH 01/10] Fix build: Use temporary directories for tests' XDG_RUNTIME_DIR Using XDG_RUNTIME_DIR="." does not work after qtbase 5542785, and it was a rather brittle solution anyway. Fixes: QTBUG-79185 Change-Id: Iaf9ced66709cc6cbac8a2d54efc64e1a8c528561 Reviewed-by: Paul Olav Tvete --- tests/auto/wayland/client/tst_client.cpp | 3 ++- tests/auto/wayland/inputcontext/tst_inputcontext.cpp | 3 ++- tests/auto/wayland/shared/mockcompositor.h | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/auto/wayland/client/tst_client.cpp b/tests/auto/wayland/client/tst_client.cpp index 83b9e6ce0b3..e7729ce8b20 100644 --- a/tests/auto/wayland/client/tst_client.cpp +++ b/tests/auto/wayland/client/tst_client.cpp @@ -507,7 +507,8 @@ void tst_WaylandClient::longWindowTitleWithUtf16Characters() int main(int argc, char **argv) { - setenv("XDG_RUNTIME_DIR", ".", 1); + QTemporaryDir tmpRuntimeDir; + setenv("XDG_RUNTIME_DIR", tmpRuntimeDir.path().toLocal8Bit(), 1); setenv("QT_QPA_PLATFORM", "wayland", 1); // force QGuiApplication to use wayland plugin MockCompositor compositor; diff --git a/tests/auto/wayland/inputcontext/tst_inputcontext.cpp b/tests/auto/wayland/inputcontext/tst_inputcontext.cpp index b1a5a7f17f8..3e6de4a0800 100644 --- a/tests/auto/wayland/inputcontext/tst_inputcontext.cpp +++ b/tests/auto/wayland/inputcontext/tst_inputcontext.cpp @@ -173,7 +173,8 @@ void tst_inputcontext::inputContextReconfigurationWhenTogglingTextInputExtension int main(int argc, char *argv[]) { - qputenv("XDG_RUNTIME_DIR", "."); + QTemporaryDir tmpRuntimeDir; + qputenv("XDG_RUNTIME_DIR", tmpRuntimeDir.path().toLocal8Bit()); qputenv("QT_QPA_PLATFORM", "wayland"); tst_inputcontext tc; diff --git a/tests/auto/wayland/shared/mockcompositor.h b/tests/auto/wayland/shared/mockcompositor.h index 05bf32c8d50..f5264ccf611 100644 --- a/tests/auto/wayland/shared/mockcompositor.h +++ b/tests/auto/wayland/shared/mockcompositor.h @@ -77,7 +77,8 @@ public: #define QCOMPOSITOR_TEST_MAIN(test) \ int main(int argc, char **argv) \ { \ - setenv("XDG_RUNTIME_DIR", ".", 1); \ + QTemporaryDir tmpRuntimeDir; \ + setenv("XDG_RUNTIME_DIR", tmpRuntimeDir.path().toLocal8Bit(), 1); \ setenv("XDG_CURRENT_DESKTOP", "qtwaylandtests", 1); \ setenv("QT_QPA_PLATFORM", "wayland", 1); \ test tc; \ From da9d36b394dc27914fdf1145894efd5ef466c4c5 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Tue, 15 Oct 2019 09:51:43 +0200 Subject: [PATCH 02/10] Client: Fix 100ms freeze when applications do not swap after deliverUpdateRequest [ChangeLog][QPA plugin] Fixed a 100 ms freeze that would occur if applications did not draw after receiving a deliverUpdateRequest(). QtQuick does this at the start of animations. This should get rid of those backingstore warnings (and also remove a 100ms freeze before animations start in those instances). Fixes: QTBUG-76813 Change-Id: Id366bf4a14f402fa44530ae46e7b66d9988c14f6 Reviewed-by: Paul Olav Tvete Reviewed-by: John Brooks --- .../platforms/wayland/qwaylandwindow.cpp | 46 ++++--------------- .../platforms/wayland/qwaylandwindow_p.h | 1 - 2 files changed, 9 insertions(+), 38 deletions(-) diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index ae26ba04946..8d34afd1f11 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -1105,25 +1105,6 @@ QVariant QWaylandWindow::property(const QString &name, const QVariant &defaultVa void QWaylandWindow::timerEvent(QTimerEvent *event) { - if (event->timerId() == mFallbackUpdateTimerId) { - killTimer(mFallbackUpdateTimerId); - mFallbackUpdateTimerId = -1; - qCDebug(lcWaylandBackingstore) << "mFallbackUpdateTimer timed out"; - - if (!isExposed()) { - qCDebug(lcWaylandBackingstore) << "Fallback update timer: Window not exposed," - << "not delivering update request."; - return; - } - - if (mWaitingForUpdate && hasPendingUpdateRequest() && !mWaitingForFrameCallback) { - qCWarning(lcWaylandBackingstore) << "Delivering update request through fallback timer," - << "may not be in sync with display"; - deliverUpdateRequest(); - } - } - - if (mFrameCallbackTimerId.testAndSetOrdered(event->timerId(), -1)) { killTimer(event->timerId()); qCDebug(lcWaylandBackingstore) << "Didn't receive frame callback in time, window should now be inexposed"; @@ -1135,6 +1116,7 @@ void QWaylandWindow::timerEvent(QTimerEvent *event) void QWaylandWindow::requestUpdate() { + qCDebug(lcWaylandBackingstore) << "requestUpdate"; Q_ASSERT(hasPendingUpdateRequest()); // should be set by QPA // If we have a frame callback all is good and will be taken care of there @@ -1142,20 +1124,17 @@ void QWaylandWindow::requestUpdate() return; // If we've already called deliverUpdateRequest(), but haven't seen any attach+commit/swap yet - if (mWaitingForUpdate) { - // Ideally, we should just have returned here, but we're not guaranteed that the client - // will actually update, so start this timer to deliver another request update after a while - // *IF* the client doesn't update. - int fallbackTimeout = 100; - mFallbackUpdateTimerId = startTimer(fallbackTimeout); - return; - } + // This is a somewhat redundant behavior and might indicate a bug in the calling code, so log + // here so we can get this information when debugging update/frame callback issues. + // Continue as nothing happened, though. + if (mWaitingForUpdate) + qCDebug(lcWaylandBackingstore) << "requestUpdate called twice without committing anything"; // Some applications (such as Qt Quick) depend on updates being delivered asynchronously, // so use invokeMethod to delay the delivery a bit. QMetaObject::invokeMethod(this, [this] { // Things might have changed in the meantime - if (hasPendingUpdateRequest() && !mWaitingForUpdate && !mWaitingForFrameCallback) + if (hasPendingUpdateRequest() && !mWaitingForFrameCallback) deliverUpdateRequest(); }, Qt::QueuedConnection); } @@ -1165,6 +1144,7 @@ void QWaylandWindow::requestUpdate() // Can be called from the render thread (without locking anything) so make sure to not make races in this method. void QWaylandWindow::handleUpdate() { + qCDebug(lcWaylandBackingstore) << "handleUpdate" << QThread::currentThread(); // TODO: Should sync subsurfaces avoid requesting frame callbacks? QReadLocker lock(&mSurfaceLock); if (!isInitialized()) @@ -1175,15 +1155,6 @@ void QWaylandWindow::handleUpdate() mFrameCallback = nullptr; } - if (mFallbackUpdateTimerId != -1) { - // Ideally, we would stop the fallback timer here, but since we're on another thread, - // it's not allowed. Instead we set mFallbackUpdateTimer to -1 here, so we'll just - // ignore it if it times out before it's cleaned up by the invokeMethod call. - int id = mFallbackUpdateTimerId; - mFallbackUpdateTimerId = -1; - QMetaObject::invokeMethod(this, [this, id] { killTimer(id); }, Qt::QueuedConnection); - } - mFrameCallback = frame(); wl_callback_add_listener(mFrameCallback, &QWaylandWindow::callbackListener, this); mWaitingForFrameCallback = true; @@ -1203,6 +1174,7 @@ void QWaylandWindow::handleUpdate() void QWaylandWindow::deliverUpdateRequest() { + qCDebug(lcWaylandBackingstore) << "deliverUpdateRequest"; mWaitingForUpdate = true; QPlatformWindow::deliverUpdateRequest(); } diff --git a/src/plugins/platforms/wayland/qwaylandwindow_p.h b/src/plugins/platforms/wayland/qwaylandwindow_p.h index b03d92e5633..e4a1124e7d6 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow_p.h +++ b/src/plugins/platforms/wayland/qwaylandwindow_p.h @@ -232,7 +232,6 @@ protected: // True when we have called deliverRequestUpdate, but the client has not yet attached a new buffer bool mWaitingForUpdate = false; - int mFallbackUpdateTimerId = -1; // Started when waiting for app to commit QMutex mResizeLock; bool mWaitingToApplyConfigure = false; From e38ac423a00e0b2c69ac7534bbb9c41b35fe9512 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Fri, 18 Oct 2019 14:22:28 +0200 Subject: [PATCH 03/10] Client: Print a warning when trying to set clipboard without a seat This warning can save some time when trying to understand why some qtbase auto tests are failing on headless Weston (which doesn't have seats at the moment). Change-Id: I361546611d12bff8a465af5bb103f61e80d73a15 Reviewed-by: Pier Luigi Fiorini --- src/plugins/platforms/wayland/qwaylandclipboard.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/wayland/qwaylandclipboard.cpp b/src/plugins/platforms/wayland/qwaylandclipboard.cpp index 369c6ec07db..c3a526ddc01 100644 --- a/src/plugins/platforms/wayland/qwaylandclipboard.cpp +++ b/src/plugins/platforms/wayland/qwaylandclipboard.cpp @@ -93,8 +93,10 @@ QMimeData *QWaylandClipboard::mimeData(QClipboard::Mode mode) void QWaylandClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode) { auto *seat = mDisplay->currentInputDevice(); - if (!seat) + if (!seat) { + qCWarning(lcQpaWayland) << "Can't set clipboard contents with no wl_seats available"; return; + } static const QString plain = QStringLiteral("text/plain"); static const QString utf8 = QStringLiteral("text/plain;charset=utf-8"); From eda76963a83f881d12f0d9c1ab68ef70372643cd Mon Sep 17 00:00:00 2001 From: Pekka Vuorela Date: Mon, 14 Oct 2019 17:20:59 +0300 Subject: [PATCH 04/10] Fix url getting broken on openUrl UTF-8 byte array cannot be split in random position and assume getting valid content on resulting parts. Switched chunk size to be based on characters, encoded size will vary but don't think that should matter. Change-Id: Ic41ea16d2111b1620993b60fdbc6e739929f25d7 Reviewed-by: Paul Olav Tvete --- .../wayland/qwaylandwindowmanagerintegration.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/wayland/qwaylandwindowmanagerintegration.cpp b/src/plugins/platforms/wayland/qwaylandwindowmanagerintegration.cpp index 17ae8a5ae85..dd1acaf7215 100644 --- a/src/plugins/platforms/wayland/qwaylandwindowmanagerintegration.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindowmanagerintegration.cpp @@ -110,13 +110,17 @@ void QWaylandWindowManagerIntegration::windowmanager_quit() void QWaylandWindowManagerIntegration::openUrl_helper(const QUrl &url) { Q_ASSERT(isInitialized()); - QByteArray data = url.toString().toUtf8(); + QString data = url.toString(); static const int chunkSize = 128; while (!data.isEmpty()) { - QByteArray chunk = data.left(chunkSize); + QString chunk = data.left(chunkSize); data = data.mid(chunkSize); - open_url(!data.isEmpty(), QString::fromUtf8(chunk)); + if (chunk.at(chunk.size() - 1).isHighSurrogate() && !data.isEmpty()) { + chunk.append(data.at(0)); + data = data.mid(1); + } + open_url(!data.isEmpty(), chunk); } } From 7cc704a3a7f58b055ca9113cbdfd1e6bb4eeb6d7 Mon Sep 17 00:00:00 2001 From: Pekka Vuorela Date: Thu, 17 Oct 2019 12:18:16 +0300 Subject: [PATCH 05/10] Signal clipboard change when focus lost clears the selection offer Change-Id: I311a5d422f31347029795dbd2479a771ae93c01f Reviewed-by: Johan Helsing --- src/plugins/platforms/wayland/qwaylanddatadevice.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/plugins/platforms/wayland/qwaylanddatadevice.cpp b/src/plugins/platforms/wayland/qwaylanddatadevice.cpp index fc3c7077a84..f7d135e49f3 100644 --- a/src/plugins/platforms/wayland/qwaylanddatadevice.cpp +++ b/src/plugins/platforms/wayland/qwaylanddatadevice.cpp @@ -81,7 +81,14 @@ QWaylandDataOffer *QWaylandDataDevice::selectionOffer() const void QWaylandDataDevice::invalidateSelectionOffer() { + if (m_selectionOffer.isNull()) + return; + m_selectionOffer.reset(); + +#if QT_CONFIG(clipboard) + QGuiApplicationPrivate::platformIntegration()->clipboard()->emitChanged(QClipboard::Clipboard); +#endif } QWaylandDataSource *QWaylandDataDevice::selectionSource() const From 37e0cd278a35ac8d34f998ca77ce1bd02af712bb Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Tue, 22 Oct 2019 12:30:09 +0200 Subject: [PATCH 06/10] Add client test for clipboard when losing keyboard focus Also, verifies that we fixed a recent bug about QClipboard::dataChanged not being emitted when the clipboard is invalidated due to losing focus. Change-Id: Ie92b618a4f673c21d6582979249700aef8785536 Reviewed-by: Pekka Vuorela --- .../wayland/datadevicev1/tst_datadevicev1.cpp | 30 +++++++++++++++++++ tests/auto/wayland/shared/datadevice.h | 1 - 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/tests/auto/wayland/datadevicev1/tst_datadevicev1.cpp b/tests/auto/wayland/datadevicev1/tst_datadevicev1.cpp index e3babceb53e..1568b3b9680 100644 --- a/tests/auto/wayland/datadevicev1/tst_datadevicev1.cpp +++ b/tests/auto/wayland/datadevicev1/tst_datadevicev1.cpp @@ -59,6 +59,7 @@ private slots: void pasteUtf8(); void destroysPreviousSelection(); void destroysSelectionWithSurface(); + void destroysSelectionOnLeave(); void dragWithoutFocus(); }; @@ -215,6 +216,35 @@ void tst_datadevicev1::destroysSelectionWithSurface() QCOMPOSITOR_TRY_COMPARE(dataDevice()->m_sentSelectionOffers.size(), 0); } +void tst_datadevicev1::destroysSelectionOnLeave() +{ + QRasterWindow window; + window.resize(64, 64); + window.show(); + QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial); + + exec([&] { + auto *offer = dataDevice()->sendDataOffer(client(), {"text/plain"}); + dataDevice()->sendSelection(offer); + + auto *surface = xdgSurface()->m_surface; + keyboard()->sendEnter(surface); // Need to set keyboard focus according to protocol + }); + + QTRY_VERIFY(QGuiApplication::clipboard()->mimeData(QClipboard::Clipboard)); + QTRY_VERIFY(QGuiApplication::clipboard()->mimeData(QClipboard::Clipboard)->hasText()); + + QSignalSpy dataChangedSpy(QGuiApplication::clipboard(), &QClipboard::dataChanged); + + exec([&] { + auto *surface = xdgSurface()->m_surface; + keyboard()->sendLeave(surface); + }); + + QTRY_COMPARE(dataChangedSpy.count(), 1); + QVERIFY(!QGuiApplication::clipboard()->mimeData(QClipboard::Clipboard)->hasText()); +} + // The application should not crash if it attempts to start a drag operation // when it doesn't have input focus (QTBUG-76368) void tst_datadevicev1::dragWithoutFocus() diff --git a/tests/auto/wayland/shared/datadevice.h b/tests/auto/wayland/shared/datadevice.h index a96da86f081..98e780b2283 100644 --- a/tests/auto/wayland/shared/datadevice.h +++ b/tests/auto/wayland/shared/datadevice.h @@ -65,7 +65,6 @@ public: ~DataDevice() override; void send_data_offer(::wl_resource *resource) = delete; DataOffer *sendDataOffer(::wl_client *client, const QStringList &mimeTypes = {}); - DataOffer *sendDataOffer(const QStringList &mimeTypes = {}); void send_selection(::wl_resource *resource) = delete; void sendSelection(DataOffer *offer); From 87b4273398c2e1768820146fc136c99a15e14cc9 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Mon, 14 Oct 2019 12:21:41 +0200 Subject: [PATCH 07/10] Client tests: Set WAYLAND_DISPLAY The tests would previously fail if WAYLAND_DISPLAY was set to something other than empty or wayland-0. For instance when running multiple compositors and trying to run the tests, they would fail because they create a compositor on wayland-0 (using wl_display_add_socket_auto()), but would try to connect to wayland-1 due to the env var. Change-Id: I7771d41737410d5c32f5a6db3de4987096cb4d22 Reviewed-by: Paul Olav Tvete --- tests/auto/wayland/shared/corecompositor.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/wayland/shared/corecompositor.cpp b/tests/auto/wayland/shared/corecompositor.cpp index 7edb1c2d434..5c6c83baa88 100644 --- a/tests/auto/wayland/shared/corecompositor.cpp +++ b/tests/auto/wayland/shared/corecompositor.cpp @@ -43,6 +43,7 @@ CoreCompositor::CoreCompositor() } }) { + qputenv("WAYLAND_DISPLAY", m_socketName); m_timer.start(); Q_ASSERT(isClean()); } From 94ea0eaf839fe9893e2881b4e52a486ac8c5acd8 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Tue, 22 Oct 2019 10:17:56 +0200 Subject: [PATCH 08/10] Fix missing emission of QClipboard::selectionChanged And add a test to verify we've fixed it. Change-Id: Ic6d5e64b3000444465935f7caf7e32ec9c4f1012 Reviewed-by: Paul Olav Tvete --- .../wayland/qwaylandprimaryselectionv1.cpp | 9 ++++++ .../wayland/qwaylandprimaryselectionv1_p.h | 2 +- .../tst_primaryselectionv1.cpp | 30 +++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/wayland/qwaylandprimaryselectionv1.cpp b/src/plugins/platforms/wayland/qwaylandprimaryselectionv1.cpp index 3ddf6dac376..832f967804a 100644 --- a/src/plugins/platforms/wayland/qwaylandprimaryselectionv1.cpp +++ b/src/plugins/platforms/wayland/qwaylandprimaryselectionv1.cpp @@ -96,6 +96,15 @@ QWaylandPrimarySelectionDeviceV1::~QWaylandPrimarySelectionDeviceV1() destroy(); } +void QWaylandPrimarySelectionDeviceV1::invalidateSelectionOffer() +{ + if (!m_selectionOffer) + return; + + m_selectionOffer.reset(); + QGuiApplicationPrivate::platformIntegration()->clipboard()->emitChanged(QClipboard::Selection); +} + void QWaylandPrimarySelectionDeviceV1::setSelectionSource(QWaylandPrimarySelectionSourceV1 *source) { if (source) { diff --git a/src/plugins/platforms/wayland/qwaylandprimaryselectionv1_p.h b/src/plugins/platforms/wayland/qwaylandprimaryselectionv1_p.h index b165c51b8c6..3f0a42a6702 100644 --- a/src/plugins/platforms/wayland/qwaylandprimaryselectionv1_p.h +++ b/src/plugins/platforms/wayland/qwaylandprimaryselectionv1_p.h @@ -125,7 +125,7 @@ class QWaylandPrimarySelectionDeviceV1 : public QObject, public QtWayland::zwp_p public: ~QWaylandPrimarySelectionDeviceV1() override; QWaylandPrimarySelectionOfferV1 *selectionOffer() const { return m_selectionOffer.data(); } - void invalidateSelectionOffer() { m_selectionOffer.reset(); } + void invalidateSelectionOffer(); QWaylandPrimarySelectionSourceV1 *selectionSource() const { return m_selectionSource.data(); } void setSelectionSource(QWaylandPrimarySelectionSourceV1 *source); diff --git a/tests/auto/wayland/primaryselectionv1/tst_primaryselectionv1.cpp b/tests/auto/wayland/primaryselectionv1/tst_primaryselectionv1.cpp index 216db85cd6b..b3fa2b13c60 100644 --- a/tests/auto/wayland/primaryselectionv1/tst_primaryselectionv1.cpp +++ b/tests/auto/wayland/primaryselectionv1/tst_primaryselectionv1.cpp @@ -261,6 +261,7 @@ private slots: void pasteAscii(); void pasteUtf8(); void destroysPreviousSelection(); + void destroysSelectionOnLeave(); void copy(); }; @@ -411,6 +412,35 @@ void tst_primaryselectionv1::destroysPreviousSelection() QCOMPOSITOR_TRY_COMPARE(primarySelectionDevice()->m_sentSelectionOffers.size(), 1); } +void tst_primaryselectionv1::destroysSelectionOnLeave() +{ + QRasterWindow window; + window.resize(64, 64); + window.show(); + QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial); + + exec([&] { + auto *surface = xdgSurface()->m_surface; + keyboard()->sendEnter(surface); // Need to set keyboard focus according to protocol + + auto *offer = primarySelectionDevice()->sendDataOffer({"text/plain"}); + primarySelectionDevice()->sendSelection(offer); + }); + + QTRY_VERIFY(QGuiApplication::clipboard()->mimeData(QClipboard::Selection)); + QTRY_VERIFY(QGuiApplication::clipboard()->mimeData(QClipboard::Selection)->hasText()); + + QSignalSpy selectionChangedSpy(QGuiApplication::clipboard(), &QClipboard::selectionChanged); + + exec([&] { + auto *surface = xdgSurface()->m_surface; + keyboard()->sendLeave(surface); + }); + + QTRY_COMPARE(selectionChangedSpy.count(), 1); + QVERIFY(!QGuiApplication::clipboard()->mimeData(QClipboard::Selection)->hasText()); +} + void tst_primaryselectionv1::copy() { class Window : public QRasterWindow { From f8651a551dca9d5062aa3f077bc3e48fd4f96784 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Tue, 22 Oct 2019 12:02:23 +0200 Subject: [PATCH 09/10] Fix QClipboard::ownSelection always returning false It would return false regardless of whether we owned the selection. Change-Id: I6df394d8dbceeccb6eb6d0670b4351af1a158491 Reviewed-by: Paul Olav Tvete --- .../platforms/wayland/qwaylandclipboard.cpp | 16 +++++++++++----- .../tst_primaryselectionv1.cpp | 1 + 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/wayland/qwaylandclipboard.cpp b/src/plugins/platforms/wayland/qwaylandclipboard.cpp index c3a526ddc01..81f48e05ee3 100644 --- a/src/plugins/platforms/wayland/qwaylandclipboard.cpp +++ b/src/plugins/platforms/wayland/qwaylandclipboard.cpp @@ -137,14 +137,20 @@ bool QWaylandClipboard::supportsMode(QClipboard::Mode mode) const bool QWaylandClipboard::ownsMode(QClipboard::Mode mode) const { - if (mode != QClipboard::Clipboard) + QWaylandInputDevice *seat = mDisplay->currentInputDevice(); + if (!seat) return false; - QWaylandInputDevice *inputDevice = mDisplay->currentInputDevice(); - if (!inputDevice || !inputDevice->dataDevice()) + switch (mode) { + case QClipboard::Clipboard: + return seat->dataDevice() && seat->dataDevice()->selectionSource() != nullptr; +#if QT_CONFIG(wayland_client_primary_selection) + case QClipboard::Selection: + return seat->primarySelectionDevice() && seat->primarySelectionDevice()->selectionSource() != nullptr; +#endif + default: return false; - - return inputDevice->dataDevice()->selectionSource() != nullptr; + } } } diff --git a/tests/auto/wayland/primaryselectionv1/tst_primaryselectionv1.cpp b/tests/auto/wayland/primaryselectionv1/tst_primaryselectionv1.cpp index b3fa2b13c60..ee9fa110e4b 100644 --- a/tests/auto/wayland/primaryselectionv1/tst_primaryselectionv1.cpp +++ b/tests/auto/wayland/primaryselectionv1/tst_primaryselectionv1.cpp @@ -472,6 +472,7 @@ void tst_primaryselectionv1::copy() }); QCOMPOSITOR_TRY_VERIFY(primarySelectionDevice()->m_selectionSource); QCOMPOSITOR_TRY_VERIFY(mouseSerials.contains(primarySelectionDevice()->m_serial)); + QVERIFY(QGuiApplication::clipboard()->ownsSelection()); QByteArray pastedBuf; exec([&](){ auto *source = primarySelectionDevice()->m_selectionSource; From 68e70fd9507319af4a2971b797077d1994ff9a9f Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Thu, 31 Oct 2019 10:02:09 +0100 Subject: [PATCH 10/10] Set temporary XDG_RUNTIME_DIR for more tests Some tests were left out when we switched to using a temporary XDG_RUNTIME_DIR. Fixes: QTBUG-79652 Change-Id: I8208d63f3f6a937406d25b1a8cf3f5b0be04bc73 Reviewed-by: Paul Olav Tvete Reviewed-by: Pier Luigi Fiorini --- tests/auto/wayland/fullscreenshellv1/tst_fullscreenshellv1.cpp | 3 ++- tests/auto/wayland/xdgshellv6/tst_xdgshellv6.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/auto/wayland/fullscreenshellv1/tst_fullscreenshellv1.cpp b/tests/auto/wayland/fullscreenshellv1/tst_fullscreenshellv1.cpp index f93d9fbc5d2..55158474c3e 100644 --- a/tests/auto/wayland/fullscreenshellv1/tst_fullscreenshellv1.cpp +++ b/tests/auto/wayland/fullscreenshellv1/tst_fullscreenshellv1.cpp @@ -93,7 +93,8 @@ void tst_WaylandClientFullScreenShellV1::createDestroyWindow() int main(int argc, char **argv) { - setenv("XDG_RUNTIME_DIR", ".", 1); + QTemporaryDir tmpRuntimeDir; + setenv("XDG_RUNTIME_DIR", tmpRuntimeDir.path().toLocal8Bit(), 1); setenv("QT_QPA_PLATFORM", "wayland", 1); // force QGuiApplication to use wayland plugin setenv("QT_WAYLAND_SHELL_INTEGRATION", "fullscreen-shell-v1", 1); setenv("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1", 1); // window decorations don't make much sense here diff --git a/tests/auto/wayland/xdgshellv6/tst_xdgshellv6.cpp b/tests/auto/wayland/xdgshellv6/tst_xdgshellv6.cpp index a397f60eb4e..9885ee2bc68 100644 --- a/tests/auto/wayland/xdgshellv6/tst_xdgshellv6.cpp +++ b/tests/auto/wayland/xdgshellv6/tst_xdgshellv6.cpp @@ -422,7 +422,8 @@ void tst_WaylandClientXdgShellV6::dontSpamExposeEvents() int main(int argc, char **argv) { - setenv("XDG_RUNTIME_DIR", ".", 1); + QTemporaryDir tmpRuntimeDir; + setenv("XDG_RUNTIME_DIR", tmpRuntimeDir.path().toLocal8Bit(), 1); setenv("QT_QPA_PLATFORM", "wayland", 1); // force QGuiApplication to use wayland plugin setenv("QT_WAYLAND_SHELL_INTEGRATION", "xdg-shell-v6", 1);