[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