diff options
Diffstat (limited to 'src/client')
-rw-r--r-- | src/client/qwaylandclipboard.cpp | 20 | ||||
-rw-r--r-- | src/client/qwaylanddatadevice.cpp | 7 | ||||
-rw-r--r-- | src/client/qwaylandprimaryselectionv1.cpp | 9 | ||||
-rw-r--r-- | src/client/qwaylandprimaryselectionv1_p.h | 2 | ||||
-rw-r--r-- | src/client/qwaylandwindow.cpp | 46 | ||||
-rw-r--r-- | src/client/qwaylandwindow_p.h | 1 | ||||
-rw-r--r-- | src/client/qwaylandwindowmanagerintegration.cpp | 10 |
7 files changed, 47 insertions, 48 deletions
diff --git a/src/client/qwaylandclipboard.cpp b/src/client/qwaylandclipboard.cpp index 369c6ec07..81f48e05e 100644 --- a/src/client/qwaylandclipboard.cpp +++ b/src/client/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"); @@ -135,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/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp index fc3c7077a..f7d135e49 100644 --- a/src/client/qwaylanddatadevice.cpp +++ b/src/client/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 diff --git a/src/client/qwaylandprimaryselectionv1.cpp b/src/client/qwaylandprimaryselectionv1.cpp index 3ddf6dac3..832f96780 100644 --- a/src/client/qwaylandprimaryselectionv1.cpp +++ b/src/client/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/client/qwaylandprimaryselectionv1_p.h b/src/client/qwaylandprimaryselectionv1_p.h index b165c51b8..3f0a42a67 100644 --- a/src/client/qwaylandprimaryselectionv1_p.h +++ b/src/client/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/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index 2704705e7..bffb57015 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -1081,25 +1081,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"; @@ -1111,6 +1092,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 @@ -1118,20 +1100,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); } @@ -1141,6 +1120,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 (!mSurface) @@ -1151,15 +1131,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 = mSurface->frame(); wl_callback_add_listener(mFrameCallback, &QWaylandWindow::callbackListener, this); mWaitingForFrameCallback = true; @@ -1179,6 +1150,7 @@ void QWaylandWindow::handleUpdate() void QWaylandWindow::deliverUpdateRequest() { + qCDebug(lcWaylandBackingstore) << "deliverUpdateRequest"; mWaitingForUpdate = true; QPlatformWindow::deliverUpdateRequest(); } diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h index 8d582eb7e..c488c2e3f 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -230,7 +230,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; diff --git a/src/client/qwaylandwindowmanagerintegration.cpp b/src/client/qwaylandwindowmanagerintegration.cpp index 17ae8a5ae..dd1acaf72 100644 --- a/src/client/qwaylandwindowmanagerintegration.cpp +++ b/src/client/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); } } |