[neon/qt/qtwayland/Neon/unstable] debian: Add patches from KDE’s Qt 5 Patch Collection up to 2022-12-04.

Dmitry Shachnev null at kde.org
Mon Apr 29 17:44:39 BST 2024


Git commit d2d1eed80f4aa8cd22817e7674487a79609cc441 by Dmitry Shachnev.
Committed on 04/12/2022 at 15:42.
Pushed by jriddell into branch 'Neon/unstable'.

Add patches from KDE’s Qt 5 Patch Collection up to 2022-12-04.

M  +1    -0    debian/changelog
A  +35   -0    debian/patches/0049-Use-CRLF-line-delimiter-for-text-uri-list-data.patch
A  +57   -0    debian/patches/0050-Fix-missing-update-when-toggling-client-side-decorat.patch
A  +38   -0    debian/patches/0051-Avoid-calling-requestUpdate-from-wrong-thread.patch
A  +37   -0    debian/patches/0052-Client-support-high-dpi-mode-for-window-icon.patch
A  +33   -0    debian/patches/0053-Call-finishDrag-in-QWaylandDataDevice-dragSourceCanc.patch
A  +78   -0    debian/patches/0054-Hold-surface-read-lock-throughout-QWaylandEglWindow-.patch
A  +100  -0    debian/patches/0055-Client-Ensure-that-wl_surface-lives-as-long-as-qtqui.patch
A  +80   -0    debian/patches/0056-Keep-toplevel-windows-in-the-top-left-corner-of-the-.patch
A  +94   -0    debian/patches/0057-Revert-Client-Ensure-that-wl_surface-lives-as-long-a.patch
A  +48   -0    debian/patches/0058-Client-Add-F_SEAL_SHRINK-seal-to-shm-backing-file.patch
A  +26   -0    debian/patches/0059-Client-Call-wl_output_release-upon-QWaylandScreen-de.patch
A  +25   -0    debian/patches/0060-Client-Bump-wl_output-version.patch
A  +158  -0    debian/patches/0061-Fix-frame-sync-related-to-unprotected-multithread-ac.patch
M  +13   -0    debian/patches/series

https://invent.kde.org/neon/qt/qtwayland/-/commit/d2d1eed80f4aa8cd22817e7674487a79609cc441

diff --git a/debian/changelog b/debian/changelog
index 115ca38..750d82e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -6,6 +6,7 @@ qtwayland-opensource-src (5.15.7-1) UNRELEASED; urgency=medium
   * Bump ABI version to 5-15-7.
   * Drop 0012-Wayland-client-Fix-crash-when-windows-are-shown-hidd.patch,
     included in the new release.
+  * Add patches from KDE’s Qt 5 Patch Collection up to 2022-12-04.
 
  -- Debian Qt/KDE Maintainers <debian-qt-kde at lists.debian.org>  Sun, 04 Dec 2022 17:49:34 +0300
 
diff --git a/debian/patches/0049-Use-CRLF-line-delimiter-for-text-uri-list-data.patch b/debian/patches/0049-Use-CRLF-line-delimiter-for-text-uri-list-data.patch
new file mode 100644
index 0000000..3cf8362
--- /dev/null
+++ b/debian/patches/0049-Use-CRLF-line-delimiter-for-text-uri-list-data.patch
@@ -0,0 +1,35 @@
+From c80442ead26f4532d139c750206e0bed04621b88 Mon Sep 17 00:00:00 2001
+From: Alexandros Frantzis <alexandros.frantzis at collabora.com>
+Date: Wed, 11 May 2022 17:12:52 +0300
+Subject: [PATCH] Use CRLF line delimiter for text/uri-list data
+
+According to RFC 2483, which describes text/uri-list, the line delimiter
+must be CRLF (instead of the currently used LF). Some applications
+strictly expect the CRLF delimiter and fail to properly parse the
+uri-list otherwise (e.g., WineX11/XWayland).
+
+https://datatracker.ietf.org/doc/html/rfc2483
+
+5. The text/uri-list Internet Media Type
+The format of text/uri-list resources is:
+3) As for all text/* formats, lines are terminated with a CRLF pair.
+
+Pick-to: 6.4 6.3 6.2 5.15
+Change-Id: I7c062224a9060028ab6293fdf172692ade28cca5
+Reviewed-by: David Edmundson <davidedmundson at kde.org>
+(cherry picked from commit bd5b0a804b91b9fbd0ce44d5d6765e07d0a50b4f)
+---
+ src/shared/qwaylandmimehelper.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/src/shared/qwaylandmimehelper.cpp
++++ b/src/shared/qwaylandmimehelper.cpp
+@@ -74,7 +74,7 @@ QByteArray QWaylandMimeHelper::getByteArray(QMimeData *mimeData, const QString &
+         QList<QUrl> urls = mimeData->urls();
+         for (int i = 0; i < urls.count(); ++i) {
+             content.append(urls.at(i).toEncoded());
+-            content.append('\n');
++            content.append("\r\n");
+         }
+     } else {
+         content = mimeData->data(mimeType);
diff --git a/debian/patches/0050-Fix-missing-update-when-toggling-client-side-decorat.patch b/debian/patches/0050-Fix-missing-update-when-toggling-client-side-decorat.patch
new file mode 100644
index 0000000..1821b38
--- /dev/null
+++ b/debian/patches/0050-Fix-missing-update-when-toggling-client-side-decorat.patch
@@ -0,0 +1,57 @@
+From 60c7d26098ec6b0da695e97e6f7cc5cd23fa2c56 Mon Sep 17 00:00:00 2001
+From: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt at qt.io>
+Date: Tue, 9 Nov 2021 13:23:41 +0100
+Subject: [PATCH] Fix missing update when toggling client-side decorations
+
+When CSD is toggled while a window is showing, it would change the
+size and recreate the buffers, but since the widget area remained
+the same size, we would not trigger a redraw. The result was that
+when you got any update to the window, it would redraw the widgets
+that had changed, and the rest would be transparent.
+
+Since this is a fairly specialized case, we fix it the simple way,
+by just issuing an extra update when it happens.
+
+This also required an update to the surface test, since there is
+an additional buffer commit in the beginning of the sequence now.
+
+Pick-to: 5.15 6.2 6.3
+Fixes: QTBUG-95032
+Change-Id: Ic4bdb9c66a2ea76546926dd622f2d2dac5dce10c
+Reviewed-by: Qt CI Bot <qt_ci_bot at qt-project.org>
+Reviewed-by: Liang Qi <liang.qi at qt.io>
+(cherry picked from commit af7b60ade5c4be81cbc58eb18307c017d5594071)
+---
+ src/client/qwaylandwindow.cpp             | 7 +++++++
+ tests/auto/client/surface/tst_surface.cpp | 4 ++++
+ 2 files changed, 11 insertions(+)
+
+--- a/src/client/qwaylandwindow.cpp
++++ b/src/client/qwaylandwindow.cpp
+@@ -867,6 +867,13 @@ bool QWaylandWindow::createDecoration()
+             subsurf->set_position(pos.x() + m.left(), pos.y() + m.top());
+         }
+         sendExposeEvent(QRect(QPoint(), geometry().size()));
++
++        // This is a special case where the buffer is recreated, but since
++        // the content rect remains the same, the widgets remain the same
++        // size and are not redrawn, leaving the new buffer empty. As a simple
++        // work-around, we trigger a full extra update whenever the client-side
++        // window decorations are toggled while the window is showing.
++        window()->requestUpdate();
+     }
+ 
+     return mWindowDecoration;
+--- a/tests/auto/client/surface/tst_surface.cpp
++++ b/tests/auto/client/surface/tst_surface.cpp
+@@ -129,6 +129,10 @@ void tst_surface::waitForFrameCallbackGl()
+     // Make sure we follow frame callbacks for some frames
+     for (int i = 0; i < 5; ++i) {
+         xdgPingAndWaitForPong(); // Make sure things have happened on the client
++        if (!qEnvironmentVariableIntValue("QT_WAYLAND_DISABLE_WINDOWDECORATION") && i == 0) {
++            QCOMPARE(bufferSpy.count(), 1);
++            bufferSpy.removeFirst();
++        }
+         exec([&] {
+             QVERIFY(bufferSpy.empty()); // Make sure no extra buffers have arrived
+             QVERIFY(!xdgToplevel()->surface()->m_waitingFrameCallbacks.empty());
diff --git a/debian/patches/0051-Avoid-calling-requestUpdate-from-wrong-thread.patch b/debian/patches/0051-Avoid-calling-requestUpdate-from-wrong-thread.patch
new file mode 100644
index 0000000..669f57c
--- /dev/null
+++ b/debian/patches/0051-Avoid-calling-requestUpdate-from-wrong-thread.patch
@@ -0,0 +1,38 @@
+From e0e030d90e0c1df94ddd9bee3e366c320d323ba1 Mon Sep 17 00:00:00 2001
+From: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt at qt.io>
+Date: Mon, 8 Aug 2022 12:14:01 +0200
+Subject: [PATCH] Avoid calling requestUpdate from wrong thread
+
+In certain circumstances, we can get to createDecoration()
+from the render thread (from QWaylandGLContext::makeCurrent)
+
+Calling requestUpdate() from this secondary thread would
+cause an assert, so we queue the call on the appropriate
+thread instead.
+
+This amends af7b60ade5c4be81cbc58eb18307c017d5594071.
+
+Pick-to: 5.15 6.2 6.3 6.3.2 6.4
+Fixes: QTBUG-105308
+Change-Id: I4805265f39e24eb1464897532be2025bc3c27728
+Reviewed-by: Inho Lee <inho.lee at qt.io>
+(cherry picked from commit a0c0b5b42335808c2222cbf72c1758e955731ed9)
+---
+ src/client/qwaylandwindow.cpp | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/src/client/qwaylandwindow.cpp
++++ b/src/client/qwaylandwindow.cpp
+@@ -873,7 +873,11 @@ bool QWaylandWindow::createDecoration()
+         // size and are not redrawn, leaving the new buffer empty. As a simple
+         // work-around, we trigger a full extra update whenever the client-side
+         // window decorations are toggled while the window is showing.
+-        window()->requestUpdate();
++        // Note: createDecoration() is sometimes called from the render thread
++        // of Qt Quick. This is essentially wrong and could potentially cause problems,
++        // but until the underlying issue has been fixed, we have to use invokeMethod()
++        // here to avoid asserts.
++        QMetaObject::invokeMethod(window(), &QWindow::requestUpdate);
+     }
+ 
+     return mWindowDecoration;
diff --git a/debian/patches/0052-Client-support-high-dpi-mode-for-window-icon.patch b/debian/patches/0052-Client-support-high-dpi-mode-for-window-icon.patch
new file mode 100644
index 0000000..4d8dc93
--- /dev/null
+++ b/debian/patches/0052-Client-support-high-dpi-mode-for-window-icon.patch
@@ -0,0 +1,37 @@
+From 78ccf62673b20111da0579e2a8e0631894099348 Mon Sep 17 00:00:00 2001
+From: Liang Qi <liang.qi at qt.io>
+Date: Mon, 13 Dec 2021 13:01:59 +0100
+Subject: [PATCH] Client: support high-dpi mode for window icon
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Fixes: QTBUG-90530
+Pick-to: 6.3 6.2 5.15
+Change-Id: Ib1f36e1cb89352dfac8a385a7b097cfc0226e813
+Reviewed-by: David Edmundson <davidedmundson at kde.org>
+Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo at qt.io>
+(cherry picked from commit fc91cd6b1306c6d452cbddab3c2289ccb92218d6)
+---
+ src/plugins/decorations/bradient/main.cpp | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+--- a/src/plugins/decorations/bradient/main.cpp
++++ b/src/plugins/decorations/bradient/main.cpp
+@@ -164,13 +164,10 @@ void QWaylandBradientDecoration::paint(QPaintDevice *device)
+     // Window icon
+     QIcon icon = waylandWindow()->windowIcon();
+     if (!icon.isNull()) {
+-        QPixmap pixmap = icon.pixmap(QSize(128, 128));
+-        QPixmap scaled = pixmap.scaled(22, 22, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+-
+         QRectF iconRect(0, 0, 22, 22);
+-        p.drawPixmap(iconRect.adjusted(margins().left() + BUTTON_SPACING, 4,
+-                                       margins().left() + BUTTON_SPACING, 4),
+-                     scaled, iconRect);
++        iconRect.adjust(margins().left() + BUTTON_SPACING, 4,
++                        margins().left() + BUTTON_SPACING, 4),
++        icon.paint(&p, iconRect.toRect());
+     }
+ 
+     // Window title
diff --git a/debian/patches/0053-Call-finishDrag-in-QWaylandDataDevice-dragSourceCanc.patch b/debian/patches/0053-Call-finishDrag-in-QWaylandDataDevice-dragSourceCanc.patch
new file mode 100644
index 0000000..b505266
--- /dev/null
+++ b/debian/patches/0053-Call-finishDrag-in-QWaylandDataDevice-dragSourceCanc.patch
@@ -0,0 +1,33 @@
+From 06222ef959875308e44fa01d89698bb2f3912056 Mon Sep 17 00:00:00 2001
+From: Fushan Wen <qydwhotmail at gmail.com>
+Date: Sun, 18 Sep 2022 18:17:18 +0800
+Subject: [PATCH] Call `finishDrag()` in
+ `QWaylandDataDevice::dragSourceCancelled()`
+
+Drags can either get finished or cancelled. If a drag is finished
+successfully we call finish on the QBasicDrag instance, which quits
+the nested event loop. This patch adds the connection for cancelled
+drags.
+
+See also: https://bugs.kde.org/show_bug.cgi?id=446111
+
+Pick-to: 6.4 6.2 5.15
+Change-Id: Ib93040648da88a433d647c87adcb7a7fabcaef6c
+Reviewed-by: Liang Qi <liang.qi at qt.io>
+(cherry picked from commit c92282b865efcf8c571bb52b5f96d8ad260a1cda)
+
+BUG: 446111
+---
+ src/client/qwaylanddatadevice.cpp | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/src/client/qwaylanddatadevice.cpp
++++ b/src/client/qwaylanddatadevice.cpp
+@@ -296,6 +296,7 @@ void QWaylandDataDevice::selectionSourceCancelled()
+ #if QT_CONFIG(draganddrop)
+ void QWaylandDataDevice::dragSourceCancelled()
+ {
++    static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->finishDrag();
+     m_dragSource.reset();
+ }
+ 
diff --git a/debian/patches/0054-Hold-surface-read-lock-throughout-QWaylandEglWindow-.patch b/debian/patches/0054-Hold-surface-read-lock-throughout-QWaylandEglWindow-.patch
new file mode 100644
index 0000000..6baf729
--- /dev/null
+++ b/debian/patches/0054-Hold-surface-read-lock-throughout-QWaylandEglWindow-.patch
@@ -0,0 +1,78 @@
+From 9c607c771acdb3d820be7f112db99213a6c6d7eb Mon Sep 17 00:00:00 2001
+From: David Edmundson <davidedmundson at kde.org>
+Date: Mon, 12 Sep 2022 13:28:08 +0100
+Subject: [PATCH] Hold surface read lock throughout
+ QWaylandEglWindow::updateSurface
+
+QWaylandEGLWindow::updateSurface is called from both the main and render
+threads. It is called on the render thread when making the surface
+current, which could be after the window is hidden if there are cleanup
+jobs to be done.
+
+Whilst the getter wlSurface() holds a read lock, it's not enough as we
+need the instance alive between the two calls and throughout the mesa
+code.
+
+This potentially fixes a crash seen in mesa where we crash creating a
+surface for an invalid wl_surface object.
+
+Change-Id: I497356e752ffaf3549d174f10c4c268234b02cbd
+Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt at qt.io>
+(cherry picked from commit 50f1ccc66c68f9f4c0b08400747942109c16b2be)
+---
+ src/client/qwaylandwindow_p.h                               | 6 ++++--
+ .../client/wayland-egl/qwaylandeglwindow.cpp                | 6 ++++--
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+--- a/src/client/qwaylandwindow_p.h
++++ b/src/client/qwaylandwindow_p.h
+@@ -220,7 +220,11 @@ signals:
+ 
+ protected:
+     QWaylandDisplay *mDisplay = nullptr;
++
++    // mSurface can be written by the main thread. Other threads should claim a read lock for access
++    mutable QReadWriteLock mSurfaceLock;
+     QScopedPointer<QWaylandSurface> mSurface;
++
+     QWaylandShellSurface *mShellSurface = nullptr;
+     QWaylandSubSurface *mSubSurfaceWindow = nullptr;
+     QVector<QWaylandSubSurface *> mChildren;
+@@ -294,8 +298,6 @@ private:
+ 
+     static QWaylandWindow *mMouseGrab;
+ 
+-    mutable QReadWriteLock mSurfaceLock;
+-
+     friend class QWaylandSubSurface;
+ };
+ 
+--- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
++++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
+@@ -40,6 +40,7 @@
+ #include "qwaylandeglwindow.h"
+ 
+ #include <QtWaylandClient/private/qwaylandscreen_p.h>
++#include <QtWaylandClient/private/qwaylandsurface_p.h>
+ #include "qwaylandglcontext.h"
+ 
+ #include <QtEglSupport/private/qeglconvenience_p.h>
+@@ -124,6 +125,7 @@ void QWaylandEglWindow::updateSurface(bool create)
+         }
+         mOffset = QPoint();
+     } else {
++        QReadLocker locker(&mSurfaceLock);
+         if (m_waylandEglWindow) {
+             int current_width, current_height;
+             static bool disableResizeCheck = qgetenv("QT_WAYLAND_DISABLE_RESIZECHECK").toInt();
+@@ -138,8 +140,8 @@ void QWaylandEglWindow::updateSurface(bool create)
+ 
+                 m_resize = true;
+             }
+-        } else if (create && wlSurface()) {
+-            m_waylandEglWindow = wl_egl_window_create(wlSurface(), sizeWithMargins.width(), sizeWithMargins.height());
++        } else if (create && mSurface) {
++            m_waylandEglWindow = wl_egl_window_create(mSurface->object(), sizeWithMargins.width(), sizeWithMargins.height());
+             m_requestedSize = sizeWithMargins;
+         }
+ 
diff --git a/debian/patches/0055-Client-Ensure-that-wl_surface-lives-as-long-as-qtqui.patch b/debian/patches/0055-Client-Ensure-that-wl_surface-lives-as-long-as-qtqui.patch
new file mode 100644
index 0000000..e4d9cc6
--- /dev/null
+++ b/debian/patches/0055-Client-Ensure-that-wl_surface-lives-as-long-as-qtqui.patch
@@ -0,0 +1,100 @@
+From 81a7702a87f386a60a0ac8c902e203daae044d81 Mon Sep 17 00:00:00 2001
+From: Vlad Zahorodnii <vlad.zahorodnii at kde.org>
+Date: Tue, 8 Nov 2022 16:10:18 +0200
+Subject: [PATCH] Client: Ensure that wl_surface lives as long as qtquick
+ render thread needs it
+
+wl_surface can be destroyed while qtquick render thread still uses it.
+That can end up in eglSwapBuffers() using defunct wl_surface, which will
+eventually lead to a crash due to the compositor posting an error.
+
+This is partially cherry-pick of dff579147b07cd15888a47c303e36684e9930f9f
+
+Change-Id: I044f40dd64e6672027a833379b57ccd9973d8305
+---
+ src/client/qwaylandwindow.cpp                       | 13 ++++++++++++-
+ src/client/qwaylandwindow_p.h                       |  3 +++
+ .../client/wayland-egl/qwaylandglcontext.cpp        |  6 +++++-
+ 3 files changed, 20 insertions(+), 2 deletions(-)
+
+--- a/src/client/qwaylandwindow.cpp
++++ b/src/client/qwaylandwindow.cpp
+@@ -76,6 +76,7 @@ QWaylandWindow *QWaylandWindow::mMouseGrab = nullptr;
+ QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display)
+     : QPlatformWindow(window)
+     , mDisplay(display)
++    , mSurfaceLock(QReadWriteLock::Recursive)
+     , mResizeAfterSwap(qEnvironmentVariableIsSet("QT_WAYLAND_RESIZE_AFTER_SWAP"))
+ {
+     {
+@@ -237,6 +238,16 @@ bool QWaylandWindow::shouldCreateSubSurface() const
+     return QPlatformWindow::parent() != nullptr;
+ }
+ 
++void QWaylandWindow::beginFrame()
++{
++    mSurfaceLock.lockForRead();
++}
++
++void QWaylandWindow::endFrame()
++{
++    mSurfaceLock.unlock();
++}
++
+ void QWaylandWindow::reset()
+ {
+     closeChildPopups();
+@@ -245,10 +256,10 @@ void QWaylandWindow::reset()
+     delete mSubSurfaceWindow;
+     mSubSurfaceWindow = nullptr;
+ 
+-    invalidateSurface();
+     if (mSurface) {
+         emit wlSurfaceDestroyed();
+         QWriteLocker lock(&mSurfaceLock);
++        invalidateSurface();
+         mSurface.reset();
+     }
+ 
+--- a/src/client/qwaylandwindow_p.h
++++ b/src/client/qwaylandwindow_p.h
+@@ -207,6 +207,9 @@ public:
+     void handleUpdate();
+     void deliverUpdateRequest() override;
+ 
++    void beginFrame();
++    void endFrame();
++
+     void addChildPopup(QWaylandWindow* child);
+     void removeChildPopup(QWaylandWindow* child);
+     void closeChildPopups();
+--- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
++++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
+@@ -432,8 +432,10 @@ bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface)
+         return true;
+     }
+ 
+-    if (window->isExposed())
++    if (window->isExposed()) {
++        window->beginFrame();
+         window->setCanResize(false);
++    }
+     if (m_decorationsContext != EGL_NO_CONTEXT && !window->decoration())
+         window->createDecoration();
+ 
+@@ -449,6 +451,7 @@ bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface)
+     if (!eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_context)) {
+         qWarning("QWaylandGLContext::makeCurrent: eglError: %x, this: %p \n", eglGetError(), this);
+         window->setCanResize(true);
++        window->endFrame();
+         return false;
+     }
+ 
+@@ -502,6 +505,7 @@ void QWaylandGLContext::swapBuffers(QPlatformSurface *surface)
+     eglSwapBuffers(m_eglDisplay, eglSurface);
+ 
+     window->setCanResize(true);
++    window->endFrame();
+ }
+ 
+ GLuint QWaylandGLContext::defaultFramebufferObject(QPlatformSurface *surface) const
diff --git a/debian/patches/0056-Keep-toplevel-windows-in-the-top-left-corner-of-the-.patch b/debian/patches/0056-Keep-toplevel-windows-in-the-top-left-corner-of-the-.patch
new file mode 100644
index 0000000..b62b006
--- /dev/null
+++ b/debian/patches/0056-Keep-toplevel-windows-in-the-top-left-corner-of-the-.patch
@@ -0,0 +1,80 @@
+From aed15df34710dd5f95f7993e1a1892ee41b5661b Mon Sep 17 00:00:00 2001
+From: David Redondo <qt at david-redondo.de>
+Date: Wed, 8 Jun 2022 11:25:59 +0200
+Subject: [PATCH] Keep toplevel windows in the top left corner of the screen
+
+We can't know the actual position of a window on the screen. This causes
+an issue when Widgets try to position a popup/menu absolutely and keep
+it on the screen when the screen geometry doesn't include (0,0).
+Instead report their positions always as the top left corner of
+the screen that they are on.
+This new behavior can be disabled for qt-shell or via an environment
+variable by users that rely on the old behavior.
+
+Fixes: QTBUG-85297
+Change-Id: Iacb91cb03a0df87af950115760d2f41124ac06a3
+Reviewed-by: Qt CI Bot <qt_ci_bot at qt-project.org>
+Reviewed-by: David Edmundson <davidedmundson at kde.org>
+Reviewed-by: Aleix Pol Gonzalez <aleixpol at kde.org>
+(cherry picked from commit a46795a22e05722917c6ebc60ed01bebf49898ae)
+---
+ src/client/qwaylandintegration.cpp |  3 +++
+ src/client/qwaylandwindow.cpp      | 14 +++++++++++++-
+ src/client/qwaylandwindow_p.h      |  3 +++
+ 3 files changed, 19 insertions(+), 1 deletion(-)
+
+--- a/src/client/qwaylandintegration.cpp
++++ b/src/client/qwaylandintegration.cpp
+@@ -125,6 +125,9 @@ QWaylandIntegration::QWaylandIntegration()
+ #endif
+ 
+     reconfigureInputContext();
++
++    QWaylandWindow::fixedToplevelPositions =
++            !qEnvironmentVariableIsSet("QT_WAYLAND_DISABLE_FIXED_POSITIONS");
+ }
+ 
+ QWaylandIntegration::~QWaylandIntegration()
+--- a/src/client/qwaylandwindow.cpp
++++ b/src/client/qwaylandwindow.cpp
+@@ -361,8 +361,13 @@ void QWaylandWindow::setGeometry_helper(const QRect &rect)
+     }
+ }
+ 
+-void QWaylandWindow::setGeometry(const QRect &rect)
++void QWaylandWindow::setGeometry(const QRect &r)
+ {
++    auto rect = r;
++    if (fixedToplevelPositions && !QPlatformWindow::parent() && window()->type() != Qt::Popup
++        && window()->type() != Qt::ToolTip) {
++        rect.moveTo(screen()->geometry().topLeft());
++    }
+     setGeometry_helper(rect);
+ 
+     if (window()->isVisible() && rect.isValid()) {
+@@ -1044,6 +1049,13 @@ void QWaylandWindow::handleScreensChanged()
+ 
+     QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen());
+     mLastReportedScreen = newScreen;
++    if (fixedToplevelPositions && !QPlatformWindow::parent() && window()->type() != Qt::Popup
++        && window()->type() != Qt::ToolTip
++        && geometry().topLeft() != newScreen->geometry().topLeft()) {
++        auto geometry = this->geometry();
++        geometry.moveTo(newScreen->geometry().topLeft());
++        setGeometry(geometry);
++    }
+ 
+     int scale = newScreen->isPlaceholder() ? 1 : static_cast<QWaylandScreen *>(newScreen)->scale();
+     if (scale != mScale) {
+--- a/src/client/qwaylandwindow_p.h
++++ b/src/client/qwaylandwindow_p.h
+@@ -98,6 +98,9 @@ public:
+     QWaylandWindow(QWindow *window, QWaylandDisplay *display);
+     ~QWaylandWindow() override;
+ 
++    // Keep Toplevels position on the top left corner of their screen
++    static inline bool fixedToplevelPositions = true;
++
+     virtual WindowType windowType() const = 0;
+     virtual void ensureSize();
+     WId winId() const override;
diff --git a/debian/patches/0057-Revert-Client-Ensure-that-wl_surface-lives-as-long-a.patch b/debian/patches/0057-Revert-Client-Ensure-that-wl_surface-lives-as-long-a.patch
new file mode 100644
index 0000000..c14f786
--- /dev/null
+++ b/debian/patches/0057-Revert-Client-Ensure-that-wl_surface-lives-as-long-a.patch
@@ -0,0 +1,94 @@
+From 4b43f2dc58e71732ebdbe1eaf4392272bc692e6d Mon Sep 17 00:00:00 2001
+From: David Edmundson <kde at davidedmundson.co.uk>
+Date: Mon, 14 Nov 2022 10:43:25 +0000
+Subject: [PATCH] Revert "Client: Ensure that wl_surface lives as long as
+ qtquick render thread needs it"
+
+This reverts commit 81a7702a87f386a60a0ac8c902e203daae044d81
+---
+ src/client/qwaylandwindow.cpp                       | 13 +------------
+ src/client/qwaylandwindow_p.h                       |  3 ---
+ .../client/wayland-egl/qwaylandglcontext.cpp        |  6 +-----
+ 3 files changed, 2 insertions(+), 20 deletions(-)
+
+--- a/src/client/qwaylandwindow.cpp
++++ b/src/client/qwaylandwindow.cpp
+@@ -76,7 +76,6 @@ QWaylandWindow *QWaylandWindow::mMouseGrab = nullptr;
+ QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display)
+     : QPlatformWindow(window)
+     , mDisplay(display)
+-    , mSurfaceLock(QReadWriteLock::Recursive)
+     , mResizeAfterSwap(qEnvironmentVariableIsSet("QT_WAYLAND_RESIZE_AFTER_SWAP"))
+ {
+     {
+@@ -238,16 +237,6 @@ bool QWaylandWindow::shouldCreateSubSurface() const
+     return QPlatformWindow::parent() != nullptr;
+ }
+ 
+-void QWaylandWindow::beginFrame()
+-{
+-    mSurfaceLock.lockForRead();
+-}
+-
+-void QWaylandWindow::endFrame()
+-{
+-    mSurfaceLock.unlock();
+-}
+-
+ void QWaylandWindow::reset()
+ {
+     closeChildPopups();
+@@ -256,10 +245,10 @@ void QWaylandWindow::reset()
+     delete mSubSurfaceWindow;
+     mSubSurfaceWindow = nullptr;
+ 
++    invalidateSurface();
+     if (mSurface) {
+         emit wlSurfaceDestroyed();
+         QWriteLocker lock(&mSurfaceLock);
+-        invalidateSurface();
+         mSurface.reset();
+     }
+ 
+--- a/src/client/qwaylandwindow_p.h
++++ b/src/client/qwaylandwindow_p.h
+@@ -210,9 +210,6 @@ public:
+     void handleUpdate();
+     void deliverUpdateRequest() override;
+ 
+-    void beginFrame();
+-    void endFrame();
+-
+     void addChildPopup(QWaylandWindow* child);
+     void removeChildPopup(QWaylandWindow* child);
+     void closeChildPopups();
+--- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
++++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
+@@ -432,10 +432,8 @@ bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface)
+         return true;
+     }
+ 
+-    if (window->isExposed()) {
+-        window->beginFrame();
++    if (window->isExposed())
+         window->setCanResize(false);
+-    }
+     if (m_decorationsContext != EGL_NO_CONTEXT && !window->decoration())
+         window->createDecoration();
+ 
+@@ -451,7 +449,6 @@ bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface)
+     if (!eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_context)) {
+         qWarning("QWaylandGLContext::makeCurrent: eglError: %x, this: %p \n", eglGetError(), this);
+         window->setCanResize(true);
+-        window->endFrame();
+         return false;
+     }
+ 
+@@ -505,7 +502,6 @@ void QWaylandGLContext::swapBuffers(QPlatformSurface *surface)
+     eglSwapBuffers(m_eglDisplay, eglSurface);
+ 
+     window->setCanResize(true);
+-    window->endFrame();
+ }
+ 
+ GLuint QWaylandGLContext::defaultFramebufferObject(QPlatformSurface *surface) const
diff --git a/debian/patches/0058-Client-Add-F_SEAL_SHRINK-seal-to-shm-backing-file.patch b/debian/patches/0058-Client-Add-F_SEAL_SHRINK-seal-to-shm-backing-file.patch
new file mode 100644
index 0000000..1b5ee75
--- /dev/null
+++ b/debian/patches/0058-Client-Add-F_SEAL_SHRINK-seal-to-shm-backing-file.patch
@@ -0,0 +1,48 @@
+From 5ac65f91431c0f711ffc9b49b92a019e979d02dc Mon Sep 17 00:00:00 2001
+From: Vlad Zahorodnii <vlad.zahorodnii at kde.org>
+Date: Thu, 17 Nov 2022 15:25:37 +0200
+Subject: [PATCH] Client: Add F_SEAL_SHRINK seal to shm backing file
+
+This lets libwayland-server avoid installing a SIGBUS handler when it
+wants to mmap() the backing file and access the contents of shared
+memory client buffers.
+
+Change-Id: Id0b17f729799535d73e8700c5a99c32fd88a068a
+Reviewed-by: Qt CI Bot <qt_ci_bot at qt-project.org>
+Reviewed-by: David Edmundson <davidedmundson at kde.org>
+(cherry picked from commit 0c1cbb376e0cf878e3a91ab4917fe784a3b4c547)
+---
+ src/client/qwaylandshmbackingstore.cpp | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/src/client/qwaylandshmbackingstore.cpp
++++ b/src/client/qwaylandshmbackingstore.cpp
+@@ -52,6 +52,7 @@
+ 
+ #include <QtWaylandClient/private/wayland-wayland-client-protocol.h>
+ 
++#include <fcntl.h>
+ #include <unistd.h>
+ #include <sys/mman.h>
+ 
+@@ -61,6 +62,9 @@
+ #  ifndef MFD_CLOEXEC
+ #    define MFD_CLOEXEC     0x0001U
+ #  endif
++#  ifndef MFD_ALLOW_SEALING
++#    define MFD_ALLOW_SEALING 0x0002U
++#  endif
+ #endif
+ 
+ QT_BEGIN_NAMESPACE
+@@ -75,7 +79,9 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display,
+     int fd = -1;
+ 
+ #ifdef SYS_memfd_create
+-    fd = syscall(SYS_memfd_create, "wayland-shm", MFD_CLOEXEC);
++    fd = syscall(SYS_memfd_create, "wayland-shm", MFD_CLOEXEC | MFD_ALLOW_SEALING);
++    if (fd >= 0)
++        fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_SEAL);
+ #endif
+ 
+     QScopedPointer<QFile> filePointer;
diff --git a/debian/patches/0059-Client-Call-wl_output_release-upon-QWaylandScreen-de.patch b/debian/patches/0059-Client-Call-wl_output_release-upon-QWaylandScreen-de.patch
new file mode 100644
index 0000000..a583b72
--- /dev/null
+++ b/debian/patches/0059-Client-Call-wl_output_release-upon-QWaylandScreen-de.patch
@@ -0,0 +1,26 @@
+From a2c4483f7205dd96f1f84c3e94ce4e85583a22e7 Mon Sep 17 00:00:00 2001
+From: Vlad Zahorodnii <vlad.zahorodnii at kde.org>
+Date: Mon, 21 Nov 2022 18:39:40 +0200
+Subject: [PATCH] Client: Call wl_output_release() upon QWaylandScreen
+ destruction
+
+It ensures that the proxy gets destroyed.
+
+Change-Id: I915cc8814e33dd3b0405b2bf82bd12ce6b5f785b
+Reviewed-by: David Edmundson <davidedmundson at kde.org>
+(cherry picked from commit 054e54759dbd6c3e76b55d5c4a9a54f62967ad1a)
+---
+ src/client/qwaylandscreen.cpp | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/src/client/qwaylandscreen.cpp
++++ b/src/client/qwaylandscreen.cpp
+@@ -81,6 +81,8 @@ QWaylandScreen::~QWaylandScreen()
+ {
+     if (zxdg_output_v1::isInitialized())
+         zxdg_output_v1::destroy();
++    if (wl_output::isInitialized() && wl_output_get_version(wl_output::object()) >= WL_OUTPUT_RELEASE_SINCE_VERSION)
++        wl_output::release();
+ }
+ 
+ uint QWaylandScreen::requiredEvents() const
diff --git a/debian/patches/0060-Client-Bump-wl_output-version.patch b/debian/patches/0060-Client-Bump-wl_output-version.patch
new file mode 100644
index 0000000..d992273
--- /dev/null
+++ b/debian/patches/0060-Client-Bump-wl_output-version.patch
@@ -0,0 +1,25 @@
+From 206ee84d640b4160c25c95aeb26197743d533397 Mon Sep 17 00:00:00 2001
+From: Vlad Zahorodnii <vlad.zahorodnii at kde.org>
+Date: Tue, 22 Nov 2022 12:33:41 +0200
+Subject: [PATCH] Client: Bump wl_output version
+
+wl_output_release is available starting with wl_output v3.
+
+Change-Id: I21822b26728ffb9318f1f8b4bd82ef7329682838
+Reviewed-by: David Edmundson <davidedmundson at kde.org>
+(cherry picked from commit c14916f5fd84f6b5483024b3df77592661a0f04e)
+---
+ src/client/qwaylandscreen.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/src/client/qwaylandscreen.cpp
++++ b/src/client/qwaylandscreen.cpp
+@@ -60,7 +60,7 @@ QWaylandXdgOutputManagerV1::QWaylandXdgOutputManagerV1(QWaylandDisplay* display,
+ }
+ 
+ QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, int version, uint32_t id)
+-    : QtWayland::wl_output(waylandDisplay->wl_registry(), id, qMin(version, 2))
++    : QtWayland::wl_output(waylandDisplay->wl_registry(), id, qMin(version, 3))
+     , m_outputId(id)
+     , mWaylandDisplay(waylandDisplay)
+     , mOutputName(QStringLiteral("Screen%1").arg(id))
diff --git a/debian/patches/0061-Fix-frame-sync-related-to-unprotected-multithread-ac.patch b/debian/patches/0061-Fix-frame-sync-related-to-unprotected-multithread-ac.patch
new file mode 100644
index 0000000..185e937
--- /dev/null
+++ b/debian/patches/0061-Fix-frame-sync-related-to-unprotected-multithread-ac.patch
@@ -0,0 +1,158 @@
+From 241486c4a90b222b9127c316c821090131057933 Mon Sep 17 00:00:00 2001
+From: Weng Xuetian <wengxt at gmail.com>
+Date: Sun, 27 Nov 2022 12:44:40 -0800
+Subject: [PATCH] Fix frame sync related to unprotected multithread access
+
+There is a few crashes happens in real life that frame callback is
+double-free'd and hit an assertion in wayland-client. e.g.
+https://bugs.kde.org/show_bug.cgi?id=450003
+
+This is due to the WaylandEventThread and calls to QWaylandWindow::reset
+may free and unset the mFrameCallback at the same time. mFrameSyncMutex
+should be used to protect such access.
+
+Pick-to: 6.4
+Change-Id: Ie01d08d07a2f10f70606ed1935caac09cb4f0382
+(cherry picked from commit b6cbb5e323822d6e3ef5ed4dd5a4c4cc1ea85038)
+---
+ src/client/qwaylandwindow.cpp | 64 ++++++++++++++++++++---------------
+ src/client/qwaylandwindow_p.h | 11 +++---
+ 2 files changed, 43 insertions(+), 32 deletions(-)
+
+--- a/src/client/qwaylandwindow.cpp
++++ b/src/client/qwaylandwindow.cpp
+@@ -252,13 +252,16 @@ void QWaylandWindow::reset()
+         mSurface.reset();
+     }
+ 
+-    if (mFrameCallback) {
+-        wl_callback_destroy(mFrameCallback);
+-        mFrameCallback = nullptr;
+-    }
++    {
++        QMutexLocker lock(&mFrameSyncMutex);
++        if (mFrameCallback) {
++            wl_callback_destroy(mFrameCallback);
++            mFrameCallback = nullptr;
++        }
+ 
+-    mFrameCallbackElapsedTimer.invalidate();
+-    mWaitingForFrameCallback = false;
++        mFrameCallbackElapsedTimer.invalidate();
++        mWaitingForFrameCallback = false;
++    }
+     mFrameCallbackTimedOut = false;
+ 
+     mMask = QRegion();
+@@ -633,18 +636,21 @@ const wl_callback_listener QWaylandWindow::callbackListener = {
+     [](void *data, wl_callback *callback, uint32_t time) {
+         Q_UNUSED(time);
+         auto *window = static_cast<QWaylandWindow*>(data);
+-
+-        Q_ASSERT(callback == window->mFrameCallback);
+-        wl_callback_destroy(callback);
+-        window->mFrameCallback = nullptr;
+-
+-        window->handleFrameCallback();
++        window->handleFrameCallback(callback);
+     }
+ };
+ 
+-void QWaylandWindow::handleFrameCallback()
++void QWaylandWindow::handleFrameCallback(wl_callback* callback)
+ {
+     QMutexLocker locker(&mFrameSyncMutex);
++    if (!mFrameCallback) {
++        // This means the callback is already unset by QWaylandWindow::reset.
++        // The wl_callback object will be destroyed there too.
++        return;
++    }
++    Q_ASSERT(callback == mFrameCallback);
++    wl_callback_destroy(callback);
++    mFrameCallback = nullptr;
+ 
+     mWaitingForFrameCallback = false;
+     mFrameCallbackElapsedTimer.invalidate();
+@@ -1169,19 +1175,24 @@ void QWaylandWindow::timerEvent(QTimerEvent *event)
+     if (event->timerId() != mFrameCallbackCheckIntervalTimerId)
+         return;
+ 
+-    bool callbackTimerExpired = mFrameCallbackElapsedTimer.hasExpired(mFrameCallbackTimeout);
+-    if (!mFrameCallbackElapsedTimer.isValid() || callbackTimerExpired ) {
+-        killTimer(mFrameCallbackCheckIntervalTimerId);
+-        mFrameCallbackCheckIntervalTimerId = -1;
+-    }
+-    if (mFrameCallbackElapsedTimer.isValid() && callbackTimerExpired) {
+-        mFrameCallbackElapsedTimer.invalidate();
++    {
++        QMutexLocker lock(&mFrameSyncMutex);
+ 
+-        qCDebug(lcWaylandBackingstore) << "Didn't receive frame callback in time, window should now be inexposed";
+-        mFrameCallbackTimedOut = true;
+-        mWaitingForUpdate = false;
+-        sendExposeEvent(QRect());
++        bool callbackTimerExpired = mFrameCallbackElapsedTimer.hasExpired(mFrameCallbackTimeout);
++        if (!mFrameCallbackElapsedTimer.isValid() || callbackTimerExpired ) {
++            killTimer(mFrameCallbackCheckIntervalTimerId);
++            mFrameCallbackCheckIntervalTimerId = -1;
++        }
++        if (!mFrameCallbackElapsedTimer.isValid() || !callbackTimerExpired) {
++            return;
++        }
++        mFrameCallbackElapsedTimer.invalidate();
+     }
++
++    qCDebug(lcWaylandBackingstore) << "Didn't receive frame callback in time, window should now be inexposed";
++    mFrameCallbackTimedOut = true;
++    mWaitingForUpdate = false;
++    sendExposeEvent(QRect());
+ }
+ 
+ void QWaylandWindow::requestUpdate()
+@@ -1224,15 +1235,14 @@ void QWaylandWindow::handleUpdate()
+ {
+     qCDebug(lcWaylandBackingstore) << "handleUpdate" << QThread::currentThread();
+ 
+-    if (mWaitingForFrameCallback)
+-        return;
+-
+     // TODO: Should sync subsurfaces avoid requesting frame callbacks?
+     QReadLocker lock(&mSurfaceLock);
+     if (!mSurface)
+         return;
+ 
+     QMutexLocker locker(&mFrameSyncMutex);
++    if (mWaitingForFrameCallback)
++        return;
+ 
+     struct ::wl_surface *wrappedSurface = reinterpret_cast<struct ::wl_surface *>(wl_proxy_create_wrapper(mSurface->object()));
+     wl_proxy_set_queue(reinterpret_cast<wl_proxy *>(wrappedSurface), mDisplay->frameEventQueue());
+--- a/src/client/qwaylandwindow_p.h
++++ b/src/client/qwaylandwindow_p.h
+@@ -237,12 +237,13 @@ protected:
+     Qt::MouseButtons mMousePressedInContentArea = Qt::NoButton;
+ 
+     WId mWindowId;
+-    bool mWaitingForFrameCallback = false;
+     bool mFrameCallbackTimedOut = false; // Whether the frame callback has timed out
+-    QAtomicInt mWaitingForUpdateDelivery = false;
+     int mFrameCallbackCheckIntervalTimerId = -1;
+-    QElapsedTimer mFrameCallbackElapsedTimer;
+-    struct ::wl_callback *mFrameCallback = nullptr;
++    QAtomicInt mWaitingForUpdateDelivery = false;
++
++    bool mWaitingForFrameCallback = false; // Protected by mFrameSyncMutex
++    QElapsedTimer mFrameCallbackElapsedTimer; // Protected by mFrameSyncMutex
++    struct ::wl_callback *mFrameCallback = nullptr; // Protected by mFrameSyncMutex
+     QMutex mFrameSyncMutex;
+     QWaitCondition mFrameSyncWait;
+ 
+@@ -297,7 +298,7 @@ private:
+     QRect mLastExposeGeometry;
+ 
+     static const wl_callback_listener callbackListener;
+-    void handleFrameCallback();
++    void handleFrameCallback(struct ::wl_callback* callback);
+ 
+     static QWaylandWindow *mMouseGrab;
+ 
diff --git a/debian/patches/series b/debian/patches/series
index e96df0a..109232e 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -41,4 +41,17 @@
 0046-Guard-mResizeDirty-by-the-correctMutex.patch
 0047-client-Synthesize-enter-leave-event-for-popup-in-xdg.patch
 0048-Fix-compile-tests.patch
+0049-Use-CRLF-line-delimiter-for-text-uri-list-data.patch
+0050-Fix-missing-update-when-toggling-client-side-decorat.patch
+0051-Avoid-calling-requestUpdate-from-wrong-thread.patch
+0052-Client-support-high-dpi-mode-for-window-icon.patch
+0053-Call-finishDrag-in-QWaylandDataDevice-dragSourceCanc.patch
+0054-Hold-surface-read-lock-throughout-QWaylandEglWindow-.patch
+0055-Client-Ensure-that-wl_surface-lives-as-long-as-qtqui.patch
+0056-Keep-toplevel-windows-in-the-top-left-corner-of-the-.patch
+0057-Revert-Client-Ensure-that-wl_surface-lives-as-long-a.patch
+0058-Client-Add-F_SEAL_SHRINK-seal-to-shm-backing-file.patch
+0059-Client-Call-wl_output_release-upon-QWaylandScreen-de.patch
+0060-Client-Bump-wl_output-version.patch
+0061-Fix-frame-sync-related-to-unprotected-multithread-ac.patch
 skip_animated_cursor_test.diff



More information about the Neon-commits mailing list