From de789045bc5c1f23b1c6134bcc5f65a075dd393b Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Wed, 3 Apr 2024 13:07:55 +0300 Subject: [PATCH] Guard against calling set_size while applying a configure event more explicitly Depending on code path taken, geometry.size() == m_pendingSize can produce incorrect results. If a configure event is applied, it's fine. If the window is resized by user, m_pendingSize will have outdated value, and setWindowGeometry() can ignore future size updates that are valid. In hindsight, we need special hooks in the QWaylandWindow to request and apply new geometry. Rather than have one function that deals with all cases. --- src/qwaylandlayersurface.cpp | 39 ++++-------------------------------- src/qwaylandlayersurface_p.h | 6 ++---- 2 files changed, 6 insertions(+), 39 deletions(-) diff --git a/src/qwaylandlayersurface.cpp b/src/qwaylandlayersurface.cpp index d186df8..e43b938 100644 --- a/src/qwaylandlayersurface.cpp +++ b/src/qwaylandlayersurface.cpp @@ -79,9 +79,6 @@ QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShellIntegration *shell, QWaylandLayerSurface::~QWaylandLayerSurface() { - if (m_waitForSyncCallback) { - wl_callback_destroy(m_waitForSyncCallback); - } destroy(); } @@ -99,7 +96,7 @@ void QWaylandLayerSurface::zwlr_layer_surface_v1_configure(uint32_t serial, uint if (!m_configured) { m_configured = true; - window()->resizeFromApplyConfigure(m_pendingSize); + applyConfigure(); sendExpose(); } else { // Later configures are resizes, so we have to queue them up for a time when we @@ -121,7 +118,9 @@ void QWaylandLayerSurface::attachPopup(QtWaylandClient::QWaylandShellSurface *po void QWaylandLayerSurface::applyConfigure() { + m_configuring = true; window()->resizeFromApplyConfigure(m_pendingSize); + m_configuring = false; } void QWaylandLayerSurface::setAnchor(uint anchor) @@ -160,8 +159,7 @@ void QWaylandLayerSurface::setLayer(uint32_t layer) void QWaylandLayerSurface::setWindowGeometry(const QRect &geometry) { - // if we are setting it to the last size we were configured at, we don't need to do anything - if (geometry.size() == m_pendingSize && !m_waitForSyncCallback) { + if (m_configuring) { return; } @@ -176,7 +174,6 @@ void QWaylandLayerSurface::setWindowGeometry(const QRect &geometry) size.setHeight(0); } set_size(size.width(), size.height()); - requestWaylandSync(); } bool QWaylandLayerSurface::requestActivate() @@ -227,34 +224,6 @@ void QWaylandLayerSurface::requestXdgActivationToken(quint32 serial) connect(tokenProvider, &QWaylandXdgActivationTokenV1::done, tokenProvider, &QObject::deleteLater); } -const wl_callback_listener QWaylandLayerSurface::syncCallbackListener = { - .done = [](void *data, struct wl_callback *callback, uint32_t time){ - Q_UNUSED(time); - wl_callback_destroy(callback); - QWaylandLayerSurface *layerSurface = static_cast(data); - layerSurface->m_waitForSyncCallback = nullptr; - layerSurface->sendExpose(); - } -}; - -void QWaylandLayerSurface::requestWaylandSync() -{ - if (m_waitForSyncCallback) { - return; - } - - m_waitForSyncCallback = wl_display_sync(m_window->display()->wl_display()); - wl_callback_add_listener(m_waitForSyncCallback, &syncCallbackListener, this); -} - -void QWaylandLayerSurface::handleWaylandSyncDone() -{ - if (!window()->isExposed()) { - return; - } - sendExpose(); -} - void QWaylandLayerSurface::sendExpose() { #if QT_VERSION < QT_VERSION_CHECK(6, 7, 0) diff --git a/src/qwaylandlayersurface_p.h b/src/qwaylandlayersurface_p.h index c4f7e12..12c2644 100644 --- a/src/qwaylandlayersurface_p.h +++ b/src/qwaylandlayersurface_p.h @@ -30,7 +30,7 @@ public: bool isExposed() const override { - return m_configured && !m_waitForSyncCallback; + return m_configured; } void attachPopup(QtWaylandClient::QWaylandShellSurface *popup) override; @@ -62,9 +62,7 @@ private: QString m_activationToken; bool m_configured = false; - - static const wl_callback_listener syncCallbackListener; - struct wl_callback *m_waitForSyncCallback = nullptr; + bool m_configuring = false; }; }