diff options
Diffstat (limited to 'user/qt5-qtwayland/kde-lts.patch')
-rw-r--r-- | user/qt5-qtwayland/kde-lts.patch | 3373 |
1 files changed, 2576 insertions, 797 deletions
diff --git a/user/qt5-qtwayland/kde-lts.patch b/user/qt5-qtwayland/kde-lts.patch index 4a884c995..87ddb050f 100644 --- a/user/qt5-qtwayland/kde-lts.patch +++ b/user/qt5-qtwayland/kde-lts.patch @@ -1,7 +1,7 @@ -From eca0516905c3f88aba876d18742c9102da2319db Mon Sep 17 00:00:00 2001 +From 71f68537466cf6f42981a1eb4929ac56c9ef12fe Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii <vlad.zahorodnii@kde.org> Date: Wed, 5 May 2021 20:49:26 +0300 -Subject: [PATCH 01/38] Client: Announce an output after receiving more +Subject: [PATCH 01/57] Client: Announce an output after receiving more complete state Output initialization is not atomic, meaning that the compositor may @@ -142,12 +142,12 @@ index df1c94f2..050cfdc0 100644 #if QT_CONFIG(cursor) -- -2.36.0 +2.49.0 -From 95a139413337bb92a9dbbbd95f61e52cc1f43649 Mon Sep 17 00:00:00 2001 +From 32bacc3b758a25a856e26f01f5d054d6ef2c0652 Mon Sep 17 00:00:00 2001 From: Jaeyoon Jung <jaeyoon.jung@lge.com> Date: Mon, 15 Feb 2021 08:31:06 +0900 -Subject: [PATCH 02/38] Fix issue with repeated window size changes +Subject: [PATCH 02/57] Fix issue with repeated window size changes Check if the new window size is different from the size requested previously before calling wl_egl_window_resize. It addresses the issue @@ -166,10 +166,10 @@ Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp -index 7889f575..201b583b 100644 +index e00c28c3..64f7caeb 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp +++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp -@@ -131,14 +131,16 @@ void QWaylandEglWindow::updateSurface(bool create) +@@ -122,14 +122,16 @@ void QWaylandEglWindow::updateSurface(bool create) if (!disableResizeCheck) { wl_egl_window_get_attached_size(m_waylandEglWindow, ¤t_width, ¤t_height); } @@ -188,10 +188,10 @@ index 7889f575..201b583b 100644 if (!m_eglSurface && m_waylandEglWindow && create) { diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h -index 5b1f4d56..0079dfef 100644 +index 2fccbcea..ad1e5ee9 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h +++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h -@@ -88,6 +88,7 @@ private: +@@ -85,6 +85,7 @@ private: mutable QOpenGLFramebufferObject *m_contentFBO = nullptr; QSurfaceFormat m_format; @@ -200,43 +200,12 @@ index 5b1f4d56..0079dfef 100644 } -- -2.36.0 +2.49.0 -From 4f5bef9e6e0d16bb859e7a99ef5ebfca2ac93f45 Mon Sep 17 00:00:00 2001 -From: Albert Astals Cid <albert.astals.cid@kdab.com> -Date: Mon, 10 May 2021 14:38:49 +0200 -Subject: [PATCH 03/38] Include locale.h for setlocale/LC_CTYPE - -Pick-to: 5.15 -Change-Id: Iced32a31a63cec71008549c1e0961d59ffc45a37 -Reviewed-by: Aleix Pol Gonzalez <aleixpol@kde.org> -(cherry picked from commit e9522eda46028f351d87311d898ab985856970b0) ---- - src/client/qwaylandinputcontext.cpp | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/client/qwaylandinputcontext.cpp b/src/client/qwaylandinputcontext.cpp -index ef5aa375..503fd735 100644 ---- a/src/client/qwaylandinputcontext.cpp -+++ b/src/client/qwaylandinputcontext.cpp -@@ -51,6 +51,10 @@ - #include "qwaylandinputmethodeventbuilder_p.h" - #include "qwaylandwindow_p.h" - -+#if QT_CONFIG(xkbcommon) -+#include <locale.h> -+#endif -+ - QT_BEGIN_NAMESPACE - - Q_LOGGING_CATEGORY(qLcQpaInputMethods, "qt.qpa.input.methods") --- -2.36.0 - -From 58f7e6cfb61e4f170ab7ced2e01b6222036f934d Mon Sep 17 00:00:00 2001 +From 98df701a25a9493c454699398482a4873f6e2cb9 Mon Sep 17 00:00:00 2001 From: David Edmundson <davidedmundson@kde.org> Date: Tue, 9 Feb 2021 16:09:21 +0000 -Subject: [PATCH 04/38] Client: Connect drags being accepted to updating the +Subject: [PATCH 03/57] Client: Connect drags being accepted to updating the source drag icon Currently in a multi-process drag and drop when the other client accepts @@ -258,10 +227,10 @@ Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> 1 file changed, 1 insertion(+) diff --git a/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp -index 19944a34..54a69c3c 100644 +index 4d2459d1..375f13fb 100644 --- a/src/client/qwaylanddatadevice.cpp +++ b/src/client/qwaylanddatadevice.cpp -@@ -124,6 +124,7 @@ bool QWaylandDataDevice::startDrag(QMimeData *mimeData, QWaylandWindow *icon) +@@ -130,6 +130,7 @@ bool QWaylandDataDevice::startDrag(QMimeData *mimeData, QWaylandWindow *icon) m_dragSource.reset(new QWaylandDataSource(m_display->dndSelectionHandler(), mimeData)); connect(m_dragSource.data(), &QWaylandDataSource::cancelled, this, &QWaylandDataDevice::dragSourceCancelled); @@ -270,12 +239,12 @@ index 19944a34..54a69c3c 100644 start_drag(m_dragSource->object(), origin->wlSurface(), icon->wlSurface(), m_display->currentInputDevice()->serial()); return true; -- -2.36.0 +2.49.0 -From 0b8b965626c7d02ce885187fa46fe6c69af3ede3 Mon Sep 17 00:00:00 2001 +From bd2d78e034ffab276333d954eb391cd2d06438c8 Mon Sep 17 00:00:00 2001 From: David Edmundson <davidedmundson@kde.org> Date: Fri, 14 May 2021 13:23:24 +0100 -Subject: [PATCH 05/38] Client: Disconnect registry listener on destruction +Subject: [PATCH 04/57] Client: Disconnect registry listener on destruction If a display outlives a QWaylandClientExtension and a new global is announced we end up delivering an event to a now deleted extension which @@ -289,7 +258,7 @@ Change-Id: Idc0de40be61a2f7627ab4963e1fe29b22fbf3f04 2 files changed, 8 insertions(+) diff --git a/src/client/global/qwaylandclientextension.cpp b/src/client/global/qwaylandclientextension.cpp -index 125b1e19..797b06fe 100644 +index 966096a8..2dc61b77 100644 --- a/src/client/global/qwaylandclientextension.cpp +++ b/src/client/global/qwaylandclientextension.cpp @@ -88,6 +88,13 @@ QWaylandClientExtension::QWaylandClientExtension(const int ver) @@ -319,12 +288,12 @@ index 98272e57..5bd28398 100644 QtWaylandClient::QWaylandIntegration *integration() const; int version() const; -- -2.36.0 +2.49.0 -From 71de867aab030a9f48bd73e4090d301da75e4102 Mon Sep 17 00:00:00 2001 +From 8329054a32746bc3b7d47d17cb75164aa4833f1a Mon Sep 17 00:00:00 2001 From: David Edmundson <davidedmundson@kde.org> Date: Mon, 3 May 2021 23:01:53 +0100 -Subject: [PATCH 06/38] Client: Set XdgShell size hints before the first commit +Subject: [PATCH 05/57] Client: Set XdgShell size hints before the first commit propagateSizeHints is only called in QWindow we have platform window and minimumSizeHint is then sent. We also need to send existing hints when @@ -343,10 +312,10 @@ Reviewed-by: Aleix Pol Gonzalez <aleixpol@kde.org> 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp -index 3a1569f7..7d33dabd 100644 +index 77ae62d6..45519ae5 100644 --- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp +++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp -@@ -105,8 +105,6 @@ void QWaylandXdgSurface::Toplevel::applyConfigure() +@@ -106,8 +106,6 @@ void QWaylandXdgSurface::Toplevel::applyConfigure() m_xdgSurface->m_window->resizeFromApplyConfigure(m_pending.size); } @@ -355,7 +324,7 @@ index 3a1569f7..7d33dabd 100644 m_applied = m_pending; qCDebug(lcQpaWayland) << "Applied pending xdg_toplevel configure event:" << m_applied.size << m_applied.states; } -@@ -257,6 +255,7 @@ QWaylandXdgSurface::QWaylandXdgSurface(QWaylandXdgShell *shell, ::xdg_surface *s +@@ -270,6 +268,7 @@ QWaylandXdgSurface::QWaylandXdgSurface(QWaylandXdgShell *shell, ::xdg_surface *s m_toplevel->set_parent(parentXdgSurface->m_toplevel->object()); } } @@ -364,7 +333,7 @@ index 3a1569f7..7d33dabd 100644 QWaylandXdgSurface::~QWaylandXdgSurface() diff --git a/tests/auto/client/xdgshell/tst_xdgshell.cpp b/tests/auto/client/xdgshell/tst_xdgshell.cpp -index 2277bbb8..2fdd0a7c 100644 +index 1c23728b..1423d647 100644 --- a/tests/auto/client/xdgshell/tst_xdgshell.cpp +++ b/tests/auto/client/xdgshell/tst_xdgshell.cpp @@ -505,7 +505,7 @@ void tst_xdgshell::minMaxSize() @@ -377,12 +346,12 @@ index 2277bbb8..2fdd0a7c 100644 QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_committed.minSize, QSize(100, 100)); QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_committed.maxSize, QSize(1000, 1000)); -- -2.36.0 +2.49.0 -From 342e5b7d0b45db4ed6679af4b40b05b4bd96de09 Mon Sep 17 00:00:00 2001 +From 7a34952c2e7a32d0b6f5ec43468226296213e666 Mon Sep 17 00:00:00 2001 From: David Edmundson <davidedmundson@kde.org> Date: Mon, 14 Jun 2021 12:45:37 +0100 -Subject: [PATCH 07/38] Fix build +Subject: [PATCH 06/57] Fix build 1b5e43a593e917610e6245f7a272ac081c508ba4 relied on a patch that we can't backport. @@ -395,7 +364,7 @@ d6ac8cf6. 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/client/global/qwaylandclientextension.cpp b/src/client/global/qwaylandclientextension.cpp -index 797b06fe..edccfe63 100644 +index 2dc61b77..36609c08 100644 --- a/src/client/global/qwaylandclientextension.cpp +++ b/src/client/global/qwaylandclientextension.cpp @@ -74,7 +74,10 @@ void QWaylandClientExtensionPrivate::handleRegistryGlobal(void *data, ::wl_regis @@ -423,12 +392,12 @@ index 69cc46a0..9091efbe 100644 class Q_WAYLAND_CLIENT_EXPORT QWaylandClientExtensionTemplatePrivate : public QWaylandClientExtensionPrivate -- -2.36.0 +2.49.0 -From 7d6a8aa51603e39a5da5b87af2acd0433a265987 Mon Sep 17 00:00:00 2001 +From 7a6744480cb1ff20d1bd7e08985f257f256fea6c Mon Sep 17 00:00:00 2001 From: Zhang Liang <zhanglianga@uniontech.com> Date: Mon, 1 Feb 2021 19:29:43 +0800 -Subject: [PATCH 08/38] Fix: remove listener +Subject: [PATCH 07/57] Fix: remove listener Add the operation for removing the listener form listener list @@ -440,10 +409,10 @@ Reviewed-by: David Edmundson <davidedmundson@kde.org> 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp -index f10c1f79..e0dfe8b2 100644 +index 8a6d5db1..16f8ca1a 100644 --- a/src/client/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp -@@ -452,9 +452,10 @@ void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data) +@@ -456,9 +456,10 @@ void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data) void QWaylandDisplay::removeListener(RegistryListener listener, void *data) { @@ -456,12 +425,12 @@ index f10c1f79..e0dfe8b2 100644 uint32_t QWaylandDisplay::currentTimeMillisec() -- -2.36.0 +2.49.0 -From bea49655add94c2ab77ec39dfe33bf6c7f5ce927 Mon Sep 17 00:00:00 2001 +From c056a86ae6b48a23f1a677bdb298b3e0e00b2e58 Mon Sep 17 00:00:00 2001 From: David Redondo <qt@david-redondo.de> Date: Wed, 26 May 2021 14:49:40 +0200 -Subject: [PATCH 09/38] Hook up queryKeyboardModifers +Subject: [PATCH 08/57] Hook up queryKeyboardModifers Can be useful when upon enter a modifiers event is received but no key event so no QKeyEvent is generated. @@ -479,7 +448,7 @@ Reviewed-by: David Edmundson <davidedmundson@kde.org> 2 files changed, 10 insertions(+) diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp -index c53ccb78..e5e7dd42 100644 +index d257e2e3..cd8569b1 100644 --- a/src/client/qwaylandintegration.cpp +++ b/src/client/qwaylandintegration.cpp @@ -262,6 +262,14 @@ QWaylandDisplay *QWaylandIntegration::display() const @@ -511,56 +480,12 @@ index ff70ae25..73b80658 100644 QStringList themeNames() const override; -- -2.36.0 - -From c7022c1c0107781993b1d13e7aa11dd3f7486249 Mon Sep 17 00:00:00 2001 -From: Aleix Pol <aleixpol@kde.org> -Date: Tue, 13 Jul 2021 13:32:15 +0200 -Subject: [PATCH 10/38] Do not update the mask if we do not have a surface - -mMask serves as a cache to remember what we've sent, the source of truth -for the value is window()->mask(). -No need to store values that we are going to discard, because it will -confuse the state of newly created windows. - -Change-Id: I6aa3da82c7f09c7ef90d0f7060f292fb042730f0 -Pick-to: 5.15 6.2 -Reviewed-by: David Edmundson <davidedmundson@kde.org> -(cherry picked from commit 962f87190c682562b369c5ebd93dc9ce0915ed7a) ---- - src/client/qwaylandwindow.cpp | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp -index e96d8fe9..bd70f4af 100644 ---- a/src/client/qwaylandwindow.cpp -+++ b/src/client/qwaylandwindow.cpp -@@ -464,14 +464,15 @@ void QWaylandWindow::lower() - - void QWaylandWindow::setMask(const QRegion &mask) - { -+ QReadLocker locker(&mSurfaceLock); -+ if (!mSurface) -+ return; -+ - if (mMask == mask) - return; - - mMask = mask; - -- if (!mSurface) -- return; -- - if (mMask.isEmpty()) { - mSurface->set_input_region(nullptr); - --- -2.36.0 +2.49.0 -From 83a5e079e4bdf567010abc0b7d67eff052b76249 Mon Sep 17 00:00:00 2001 +From 73636c9dd2af7410e988fb63649262b669036f8b Mon Sep 17 00:00:00 2001 From: Jan Blackquill <uhhadd@gmail.com> Date: Tue, 24 Aug 2021 14:36:34 -0400 -Subject: [PATCH 11/38] Correctly detect if image format is supported by +Subject: [PATCH 09/57] Correctly detect if image format is supported by QImageWriter The code queries potential image formats by stripping a mimetype of its @@ -610,7 +535,7 @@ Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/qwaylandmimehelper.cpp b/src/shared/qwaylandmimehelper.cpp -index a5fdd34d..051a91dc 100644 +index c5266ab3..e2fe1928 100644 --- a/src/shared/qwaylandmimehelper.cpp +++ b/src/shared/qwaylandmimehelper.cpp @@ -60,7 +60,7 @@ QByteArray QWaylandMimeHelper::getByteArray(QMimeData *mimeData, const QString & @@ -623,43 +548,12 @@ index a5fdd34d..051a91dc 100644 fmt = imgFmt; } -- -2.36.0 - -From 19d0878e56094b5cced1154ce07f566f2b147e2a Mon Sep 17 00:00:00 2001 -From: Paul Olav Tvete <paul.tvete@qt.io> -Date: Tue, 14 Sep 2021 11:56:23 +0200 -Subject: [PATCH 12/38] Wayland client: Fix crash when windows are shown/hidden - during drag - -Fixes: QTBUG-87624 -Pick-to: 6.2 5.15 -Change-Id: I1b9443df091878abcd4fbe9c55927cb819aebd59 -Reviewed-by: David Edmundson <davidedmundson@kde.org> -(cherry picked from commit c64c5d3849b40617e1de0295f8690f354cab2b3a) ---- - src/client/qwaylanddatadevice.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) +2.49.0 -diff --git a/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp -index 54a69c3c..bbd2d568 100644 ---- a/src/client/qwaylanddatadevice.cpp -+++ b/src/client/qwaylanddatadevice.cpp -@@ -169,7 +169,7 @@ void QWaylandDataDevice::data_device_drop() - - void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface, wl_fixed_t x, wl_fixed_t y, wl_data_offer *id) - { -- auto *dragWaylandWindow = QWaylandWindow::fromWlSurface(surface); -+ auto *dragWaylandWindow = surface ? QWaylandWindow::fromWlSurface(surface) : nullptr; - if (!dragWaylandWindow) - return; // Ignore foreign surfaces - --- -2.36.0 - -From abaa0b1765551533112944e624ac5989df7d7b6c Mon Sep 17 00:00:00 2001 +From 0e054eab8f64ea3ad58225967b3374df380bcf8f Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto <gbsneto@gnome.org> Date: Thu, 27 May 2021 19:55:04 -0300 -Subject: [PATCH 13/38] Client: Don't always recreate frame callbacks +Subject: [PATCH 10/57] Client: Don't always recreate frame callbacks The main QWaylandWindow method that is executed when handling updates is QWaylandWindow::handleUpdate(). This method always, unconditionally queues @@ -696,10 +590,10 @@ Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> 2 files changed, 6 insertions(+) diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp -index bd70f4af..85307875 100644 +index d57094a7..9de284de 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp -@@ -1170,6 +1170,10 @@ void QWaylandWindow::requestUpdate() +@@ -1199,6 +1199,10 @@ void QWaylandWindow::requestUpdate() void QWaylandWindow::handleUpdate() { qCDebug(lcWaylandBackingstore) << "handleUpdate" << QThread::currentThread(); @@ -711,7 +605,7 @@ index bd70f4af..85307875 100644 QReadLocker lock(&mSurfaceLock); if (!mSurface) diff --git a/tests/auto/client/xdgshell/tst_xdgshell.cpp b/tests/auto/client/xdgshell/tst_xdgshell.cpp -index 2fdd0a7c..e2593314 100644 +index 1423d647..46f07c0a 100644 --- a/tests/auto/client/xdgshell/tst_xdgshell.cpp +++ b/tests/auto/client/xdgshell/tst_xdgshell.cpp @@ -138,6 +138,7 @@ void tst_xdgshell::configureSize() @@ -731,12 +625,12 @@ index 2fdd0a7c..e2593314 100644 void tst_xdgshell::popup() -- -2.36.0 +2.49.0 -From 1428e39b6e686faf4d25ab4f8506662bcc23e6f9 Mon Sep 17 00:00:00 2001 +From f0753e3fa7a2a531ca03a51a9ad35a3df4ecba0c Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto <gbsneto@gnome.org> Date: Thu, 27 May 2021 20:02:53 -0300 -Subject: [PATCH 14/38] Client: Always destroy frame callback in the actual +Subject: [PATCH 11/57] Client: Always destroy frame callback in the actual callback It's good hygiene to destroy all frame callbacks. Destroy the @@ -758,10 +652,10 @@ Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp -index 85307875..c020a58f 100644 +index 9de284de..e0093013 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp -@@ -622,9 +622,13 @@ void QWaylandWindow::commit() +@@ -635,9 +635,13 @@ void QWaylandWindow::commit() const wl_callback_listener QWaylandWindow::callbackListener = { [](void *data, wl_callback *callback, uint32_t time) { @@ -776,7 +670,7 @@ index 85307875..c020a58f 100644 window->handleFrameCallback(); } }; -@@ -1179,11 +1183,6 @@ void QWaylandWindow::handleUpdate() +@@ -1208,11 +1212,6 @@ void QWaylandWindow::handleUpdate() if (!mSurface) return; @@ -789,52 +683,12 @@ index 85307875..c020a58f 100644 struct ::wl_surface *wrappedSurface = reinterpret_cast<struct ::wl_surface *>(wl_proxy_create_wrapper(mSurface->object())); wl_proxy_set_queue(reinterpret_cast<wl_proxy *>(wrappedSurface), mFrameQueue.queue); -- -2.36.0 - -From 132be08e4d81c1e05b93f31a6e2b6a6bd65d5726 Mon Sep 17 00:00:00 2001 -From: Rodney Dawes <dobey.pwns@gmail.com> -Date: Fri, 15 Oct 2021 12:55:33 -0400 -Subject: [PATCH 15/38] Fix the logic for decoding modifiers map in Wayland - text input protocol - -Correctly check for the flags in the modifiers map when we get it from -the compositor, instead of modifying the map in the for loop conditional. +2.49.0 -[ChangeLog][QWaylandInputContext] Fix modifiers map decoding -logic when receiving the map from the compositor. - -Fixes: QTBUG-97094 -Pick-to: 6.2 5.15 5.12 -Change-Id: Idad19f7b1f4560d40abbb5b31032360cfe915261 -Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io> ---- - src/client/qwaylandinputcontext.cpp | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/src/client/qwaylandinputcontext.cpp b/src/client/qwaylandinputcontext.cpp -index 503fd735..e290baa2 100644 ---- a/src/client/qwaylandinputcontext.cpp -+++ b/src/client/qwaylandinputcontext.cpp -@@ -387,8 +387,10 @@ void QWaylandTextInput::zwp_text_input_v2_input_method_changed(uint32_t serial, - Qt::KeyboardModifiers QWaylandTextInput::modifiersToQtModifiers(uint32_t modifiers) - { - Qt::KeyboardModifiers ret = Qt::NoModifier; -- for (int i = 0; modifiers >>= 1; ++i) { -- ret |= m_modifiersMap[i]; -+ for (int i = 0; i < m_modifiersMap.size(); ++i) { -+ if (modifiers & (1 << i)) { -+ ret |= m_modifiersMap[i]; -+ } - } - return ret; - } --- -2.36.0 - -From f73a3ec466eb30e554f918d6d2da2c5d1b0e23bd Mon Sep 17 00:00:00 2001 +From 8c2c86baa59e7e867ab62263df75749fe8b1401d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9ven=20Car?= <meven.car@enioka.com> Date: Wed, 18 Aug 2021 18:28:20 +0200 -Subject: [PATCH 16/38] Wayland client: use wl_keyboard to determine active +Subject: [PATCH 12/57] Wayland client: use wl_keyboard to determine active state Commit f497a5bb87270174b8e0106b7eca1992d44ff15d made QWaylandDisplay @@ -879,10 +733,10 @@ Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> 13 files changed, 39 insertions(+), 66 deletions(-) diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp -index e0dfe8b2..27303110 100644 +index 16f8ca1a..d1ca0274 100644 --- a/src/client/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp -@@ -575,14 +575,10 @@ void QWaylandDisplay::handleKeyboardFocusChanged(QWaylandInputDevice *inputDevic +@@ -579,14 +579,10 @@ void QWaylandDisplay::handleKeyboardFocusChanged(QWaylandInputDevice *inputDevic if (mLastKeyboardFocus == keyboardFocus) return; @@ -901,7 +755,7 @@ index e0dfe8b2..27303110 100644 mLastKeyboardFocus = keyboardFocus; } -@@ -627,6 +623,13 @@ QWaylandInputDevice *QWaylandDisplay::defaultInputDevice() const +@@ -631,6 +627,13 @@ QWaylandInputDevice *QWaylandDisplay::defaultInputDevice() const return mInputDevices.isEmpty() ? 0 : mInputDevices.first(); } @@ -916,10 +770,10 @@ index e0dfe8b2..27303110 100644 QWaylandCursor *QWaylandDisplay::waylandCursor() diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h -index 3b092bc8..09a1736a 100644 +index 1bad8b67..15104d65 100644 --- a/src/client/qwaylanddisplay_p.h +++ b/src/client/qwaylanddisplay_p.h -@@ -215,6 +215,7 @@ public: +@@ -219,6 +219,7 @@ public: void destroyFrameQueue(const FrameQueue &q); void dispatchQueueWhile(wl_event_queue *queue, std::function<bool()> condition, int timeout = -1); @@ -928,7 +782,7 @@ index 3b092bc8..09a1736a 100644 void blockingReadEvents(); void flushRequests(); diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp -index c020a58f..ba881cb3 100644 +index e0093013..bba43a54 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -96,7 +96,6 @@ QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display) @@ -948,7 +802,7 @@ index c020a58f..ba881cb3 100644 } QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface) -@@ -1083,10 +1084,18 @@ bool QWaylandWindow::setMouseGrabEnabled(bool grab) +@@ -1112,10 +1113,18 @@ bool QWaylandWindow::setMouseGrabEnabled(bool grab) return true; } @@ -969,7 +823,7 @@ index c020a58f..ba881cb3 100644 } diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h -index 6cc1664b..e0687962 100644 +index 01337cff..fb3ed606 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -148,6 +148,7 @@ public: @@ -1067,10 +921,10 @@ index 261f8cbb..c1bcd5c6 100644 private: QScopedPointer<QWaylandXdgShellV6> m_xdgShell; diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp -index 7d33dabd..d7d0ddf7 100644 +index 45519ae5..e7bd5117 100644 --- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp +++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp -@@ -67,11 +67,6 @@ QWaylandXdgSurface::Toplevel::Toplevel(QWaylandXdgSurface *xdgSurface) +@@ -68,11 +68,6 @@ QWaylandXdgSurface::Toplevel::Toplevel(QWaylandXdgSurface *xdgSurface) QWaylandXdgSurface::Toplevel::~Toplevel() { @@ -1082,7 +936,7 @@ index 7d33dabd..d7d0ddf7 100644 // The protocol spec requires that the decoration object is deleted before xdg_toplevel. delete m_decoration; m_decoration = nullptr; -@@ -85,16 +80,15 @@ void QWaylandXdgSurface::Toplevel::applyConfigure() +@@ -86,16 +81,15 @@ void QWaylandXdgSurface::Toplevel::applyConfigure() if (!(m_applied.states & (Qt::WindowMaximized|Qt::WindowFullScreen))) m_normalSize = m_xdgSurface->m_window->windowFrameGeometry().size(); @@ -1142,7 +996,7 @@ index b6caa6c9..2f929f98 100644 private: QScopedPointer<QWaylandXdgShell> m_xdgShell; diff --git a/tests/auto/client/xdgshell/tst_xdgshell.cpp b/tests/auto/client/xdgshell/tst_xdgshell.cpp -index e2593314..73d1eb9c 100644 +index 46f07c0a..1da70ff2 100644 --- a/tests/auto/client/xdgshell/tst_xdgshell.cpp +++ b/tests/auto/client/xdgshell/tst_xdgshell.cpp @@ -31,6 +31,7 @@ @@ -1168,14 +1022,14 @@ index e2593314..73d1eb9c 100644 + Qt::WindowActive)); // Just make sure it eventually get's set correctly const QSize screenSize(640, 480); - const uint maximizedSerial = exec([=] { + const uint maximizedSerial = exec([&] { -- -2.36.0 +2.49.0 -From 83440ae9e002f0c7bdec6b54db6b382d2e28bf7d Mon Sep 17 00:00:00 2001 +From b69868cb4d7d7717d08a8294896acd4043292546 Mon Sep 17 00:00:00 2001 From: Jan Grulich <jgrulich@redhat.com> Date: Fri, 16 Jul 2021 13:00:03 +0200 -Subject: [PATCH 17/38] Client: do not empty clipboard when a new popup/window +Subject: [PATCH 13/57] Client: do not empty clipboard when a new popup/window is opened If we open a new popup or a window within the same app we have to avoid @@ -1195,10 +1049,10 @@ Cherry-pick: 1e57ebd501cfc2255300392cd4565cd034efeed8 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp -index 27303110..9f595af3 100644 +index d1ca0274..7560bf41 100644 --- a/src/client/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp -@@ -597,6 +597,19 @@ void QWaylandDisplay::handleWaylandSync() +@@ -601,6 +601,19 @@ void QWaylandDisplay::handleWaylandSync() QWindow *activeWindow = mActiveWindows.empty() ? nullptr : mActiveWindows.last()->window(); if (activeWindow != QGuiApplication::focusWindow()) QWindowSystemInterface::handleWindowActivated(activeWindow); @@ -1219,10 +1073,10 @@ index 27303110..9f595af3 100644 const wl_callback_listener QWaylandDisplay::syncCallbackListener = { diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp -index 613fe862..aaec7eb8 100644 +index 5994774f..5ec64faf 100644 --- a/src/client/qwaylandinputdevice.cpp +++ b/src/client/qwaylandinputdevice.cpp -@@ -1300,14 +1300,6 @@ void QWaylandInputDevice::Keyboard::handleFocusDestroyed() +@@ -1303,14 +1303,6 @@ void QWaylandInputDevice::Keyboard::handleFocusDestroyed() void QWaylandInputDevice::Keyboard::handleFocusLost() { mFocus = nullptr; @@ -1238,41 +1092,12 @@ index 613fe862..aaec7eb8 100644 mRepeatTimer.stop(); } -- -2.36.0 +2.49.0 -From 1a476429c2d9034322d5b3366ce53375e484353a Mon Sep 17 00:00:00 2001 -From: Weng Xuetian <wengxt@gmail.com> -Date: Sat, 18 Dec 2021 23:42:49 -0800 -Subject: [PATCH 18/38] Set preedit cursor when cursor equals to 0 - -Pick-to: 6.3 6.2 5.15 -Change-Id: I832fbb22d973b36ac4ab51570fc53bc2e4c3ed58 -Reviewed-by: Liang Qi <liang.qi@qt.io> -(cherry picked from commit 719a55be13bdadfa659a732755f280e276a894bd) ---- - src/shared/qwaylandinputmethodeventbuilder.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/shared/qwaylandinputmethodeventbuilder.cpp b/src/shared/qwaylandinputmethodeventbuilder.cpp -index 526d0ef4..25be2509 100644 ---- a/src/shared/qwaylandinputmethodeventbuilder.cpp -+++ b/src/shared/qwaylandinputmethodeventbuilder.cpp -@@ -151,7 +151,7 @@ QInputMethodEvent QWaylandInputMethodEventBuilder::buildPreedit(const QString &t - { - QList<QInputMethodEvent::Attribute> attributes; - -- if (m_preeditCursor < 0) { -+ if (m_preeditCursor <= 0) { - attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 0, QVariant())); - } else if (m_preeditCursor > 0) { - attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, indexFromWayland(text, m_preeditCursor), 1, QVariant())); --- -2.36.0 - -From 8afae71a44d0d5a0be477863da791dd2dfe2027d Mon Sep 17 00:00:00 2001 +From 77d8a85bedfd1f91970c8cf39709853776f80933 Mon Sep 17 00:00:00 2001 From: David Edmundson <davidedmundson@kde.org> Date: Tue, 16 Feb 2021 09:51:47 +0000 -Subject: [PATCH 19/38] Client: Implement DataDeviceV3 +Subject: [PATCH 14/57] Client: Implement DataDeviceV3 DataDeviceV2 fixes a leak of DataDevice resources. @@ -1307,7 +1132,7 @@ Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> 12 files changed, 153 insertions(+), 46 deletions(-) diff --git a/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp -index bbd2d568..fbb5aa91 100644 +index 375f13fb..89e4e372 100644 --- a/src/client/qwaylanddatadevice.cpp +++ b/src/client/qwaylanddatadevice.cpp @@ -72,6 +72,8 @@ QWaylandDataDevice::QWaylandDataDevice(QWaylandDataDeviceManager *manager, QWayl @@ -1328,8 +1153,8 @@ index bbd2d568..fbb5aa91 100644 { auto *seat = m_display->currentInputDevice(); auto *origin = seat->pointerFocus(); -@@ -123,8 +125,28 @@ bool QWaylandDataDevice::startDrag(QMimeData *mimeData, QWaylandWindow *icon) - } +@@ -129,8 +131,28 @@ bool QWaylandDataDevice::startDrag(QMimeData *mimeData, QWaylandWindow *icon) + mimeData->setData("application/x-qt-avoid-empty-placeholder", QByteArray("1")); m_dragSource.reset(new QWaylandDataSource(m_display->dndSelectionHandler(), mimeData)); + @@ -1358,7 +1183,7 @@ index bbd2d568..fbb5aa91 100644 start_drag(m_dragSource->object(), origin->wlSurface(), icon->wlSurface(), m_display->currentInputDevice()->serial()); return true; -@@ -153,7 +175,7 @@ void QWaylandDataDevice::data_device_drop() +@@ -159,7 +181,7 @@ void QWaylandDataDevice::data_device_drop() supportedActions = drag->supportedActions(); } else if (m_dragOffer) { dragData = m_dragOffer->mimeData(); @@ -1367,7 +1192,7 @@ index bbd2d568..fbb5aa91 100644 } else { return; } -@@ -163,7 +185,11 @@ void QWaylandDataDevice::data_device_drop() +@@ -169,7 +191,11 @@ void QWaylandDataDevice::data_device_drop() QGuiApplication::keyboardModifiers()); if (drag) { @@ -1380,7 +1205,7 @@ index bbd2d568..fbb5aa91 100644 } } -@@ -187,7 +213,7 @@ void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface, +@@ -193,7 +219,7 @@ void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface, supportedActions = drag->supportedActions(); } else if (m_dragOffer) { dragData = m_dragOffer->mimeData(); @@ -1389,7 +1214,7 @@ index bbd2d568..fbb5aa91 100644 } const QPlatformDragQtResponse &response = QWindowSystemInterface::handleDrag(m_dragWindow, dragData, m_dragPoint, supportedActions, -@@ -198,11 +224,7 @@ void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface, +@@ -204,11 +230,7 @@ void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface, static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->setResponse(response); } @@ -1402,7 +1227,7 @@ index bbd2d568..fbb5aa91 100644 } void QWaylandDataDevice::data_device_leave() -@@ -236,10 +258,10 @@ void QWaylandDataDevice::data_device_motion(uint32_t time, wl_fixed_t x, wl_fixe +@@ -242,10 +264,10 @@ void QWaylandDataDevice::data_device_motion(uint32_t time, wl_fixed_t x, wl_fixe supportedActions = drag->supportedActions(); } else { dragData = m_dragOffer->mimeData(); @@ -1415,7 +1240,7 @@ index bbd2d568..fbb5aa91 100644 QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers()); -@@ -247,11 +269,7 @@ void QWaylandDataDevice::data_device_motion(uint32_t time, wl_fixed_t x, wl_fixe +@@ -253,11 +275,7 @@ void QWaylandDataDevice::data_device_motion(uint32_t time, wl_fixed_t x, wl_fixe static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->setResponse(response); } @@ -1428,7 +1253,7 @@ index bbd2d568..fbb5aa91 100644 } #endif // QT_CONFIG(draganddrop) -@@ -281,11 +299,6 @@ void QWaylandDataDevice::dragSourceCancelled() +@@ -287,11 +305,6 @@ void QWaylandDataDevice::dragSourceCancelled() m_dragSource.reset(); } @@ -1440,7 +1265,7 @@ index bbd2d568..fbb5aa91 100644 QPoint QWaylandDataDevice::calculateDragPosition(int x, int y, QWindow *wnd) const { QPoint pnt(wl_fixed_to_int(x), wl_fixed_to_int(y)); -@@ -298,6 +311,33 @@ QPoint QWaylandDataDevice::calculateDragPosition(int x, int y, QWindow *wnd) con +@@ -304,6 +317,33 @@ QPoint QWaylandDataDevice::calculateDragPosition(int x, int y, QWindow *wnd) con } return pnt; } @@ -1542,10 +1367,10 @@ index bd05c0fb..510d9be4 100644 QWaylandDataDevice *getDataDevice(QWaylandInputDevice *inputDevice); diff --git a/src/client/qwaylanddataoffer.cpp b/src/client/qwaylanddataoffer.cpp -index 2297e8a1..c9e158cc 100644 +index 6046a9b5..09e29973 100644 --- a/src/client/qwaylanddataoffer.cpp +++ b/src/client/qwaylanddataoffer.cpp -@@ -82,6 +82,15 @@ QMimeData *QWaylandDataOffer::mimeData() +@@ -87,6 +87,15 @@ QMimeData *QWaylandDataOffer::mimeData() return m_mimeData.data(); } @@ -1561,7 +1386,7 @@ index 2297e8a1..c9e158cc 100644 void QWaylandDataOffer::startReceiving(const QString &mimeType, int fd) { receive(mimeType, fd); -@@ -93,6 +102,22 @@ void QWaylandDataOffer::data_offer_offer(const QString &mime_type) +@@ -98,6 +107,22 @@ void QWaylandDataOffer::data_offer_offer(const QString &mime_type) m_mimeData->appendFormat(mime_type); } @@ -1611,10 +1436,10 @@ index 9cf1483c..6f667398 100644 diff --git a/src/client/qwaylanddatasource.cpp b/src/client/qwaylanddatasource.cpp -index f45122fb..5599cbd4 100644 +index c86c1416..321170a6 100644 --- a/src/client/qwaylanddatasource.cpp +++ b/src/client/qwaylanddatasource.cpp -@@ -101,7 +101,32 @@ void QWaylandDataSource::data_source_send(const QString &mime_type, int32_t fd) +@@ -105,7 +105,32 @@ void QWaylandDataSource::data_source_send(const QString &mime_type, int32_t fd) void QWaylandDataSource::data_source_target(const QString &mime_type) { @@ -1649,11 +1474,11 @@ index f45122fb..5599cbd4 100644 } diff --git a/src/client/qwaylanddatasource_p.h b/src/client/qwaylanddatasource_p.h -index 25afff79..96f07bc3 100644 +index 520b3165..089c5485 100644 --- a/src/client/qwaylanddatasource_p.h +++ b/src/client/qwaylanddatasource_p.h -@@ -77,17 +77,25 @@ public: - QMimeData *mimeData() const; +@@ -75,16 +75,24 @@ public: + ~QWaylandDataSource() override; Q_SIGNALS: - void targetChanged(const QString &mime_type); @@ -1672,7 +1497,6 @@ index 25afff79..96f07bc3 100644 + void data_source_action(uint32_t action) override; private: - QWaylandDisplay *m_display = nullptr; QMimeData *m_mime_data = nullptr; + bool m_accepted = false; + Qt::DropAction m_dropAction = Qt::IgnoreAction; @@ -1680,10 +1504,10 @@ index 25afff79..96f07bc3 100644 } diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp -index 9f595af3..ea344c61 100644 +index 7560bf41..7f28d01c 100644 --- a/src/client/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp -@@ -354,7 +354,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin +@@ -356,7 +356,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin mInputDevices.append(inputDevice); #if QT_CONFIG(wayland_datadevice) } else if (interface == QStringLiteral("wl_data_device_manager")) { @@ -1780,12 +1604,12 @@ index 1568b3b9..067410d0 100644 class DataDeviceCompositor : public DefaultCompositor { public: -- -2.36.0 +2.49.0 -From e92aff243eca4c1e30c093692dce6f7c91d7a19c Mon Sep 17 00:00:00 2001 +From fd53a9ccbb0c5e3b8dc5b436c34958761cb4c5a4 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra <ahiemstra@heimr.nl> Date: Thu, 18 Nov 2021 13:05:30 +0100 -Subject: [PATCH 20/38] Client: Delay deletion of QDrag object until after +Subject: [PATCH 15/57] Client: Delay deletion of QDrag object until after we're done with it In certain cases, most notably when performing drag and drop operations @@ -1847,12 +1671,12 @@ index 747f0190..46f629ac 100644 private: QWaylandDisplay *m_display = nullptr; -- -2.36.0 +2.49.0 -From 340e89575c93435abab78ac73603b405f1f05ceb Mon Sep 17 00:00:00 2001 +From 757c941881e535178bf92ffc5c40f8ac7485b975 Mon Sep 17 00:00:00 2001 From: David Edmundson <davidedmundson@kde.org> Date: Sun, 14 Nov 2021 13:54:19 +0000 -Subject: [PATCH 21/38] Client: Avoid processing of events when showing windows +Subject: [PATCH 16/57] Client: Avoid processing of events when showing windows The only time we want to dispatch events from the wayland socket is when the application is waiting for external events. Doing so at any other @@ -1873,10 +1697,10 @@ Reviewed-by: Aleix Pol Gonzalez <aleixpol@kde.org> 1 file changed, 1 deletion(-) diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp -index ba881cb3..1597f67e 100644 +index bba43a54..41e56d24 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp -@@ -436,7 +436,6 @@ void QWaylandWindow::setVisible(bool visible) +@@ -437,7 +437,6 @@ void QWaylandWindow::setVisible(bool visible) if (window()->type() == Qt::Popup || window()->type() == Qt::ToolTip) activePopups << this; initWindow(); @@ -1885,12 +1709,12 @@ index ba881cb3..1597f67e 100644 setGeometry(windowGeometry()); // Don't flush the events here, or else the newly visible window may start drawing, but since -- -2.36.0 +2.49.0 -From de7afd339100cac1470f875eafc22d3ee87870bd Mon Sep 17 00:00:00 2001 +From 980225f489e7ec09068c5ea2a51c14692a986c67 Mon Sep 17 00:00:00 2001 From: Elvis Lee <kwangwoong.lee@lge.com> Date: Thu, 18 Feb 2021 15:45:49 +0900 -Subject: [PATCH 22/38] Handle registry_global out of constructor +Subject: [PATCH 17/57] Handle registry_global out of constructor Factory functions in QWaylandDisplay::registry_global() can be overridden. Later, other classes instantiated in the registry_global can support @@ -1906,10 +1730,10 @@ Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp -index ea344c61..0f75cb7e 100644 +index 7f28d01c..c2482030 100644 --- a/src/client/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp -@@ -158,13 +158,6 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration) +@@ -160,13 +160,6 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration) if (!mXkbContext) qCWarning(lcQpaWayland, "failed to create xkb context"); #endif @@ -1923,7 +1747,7 @@ index ea344c61..0f75cb7e 100644 } QWaylandDisplay::~QWaylandDisplay(void) -@@ -189,6 +182,18 @@ QWaylandDisplay::~QWaylandDisplay(void) +@@ -191,6 +184,18 @@ QWaylandDisplay::~QWaylandDisplay(void) wl_display_disconnect(mDisplay); } @@ -1943,10 +1767,10 @@ index ea344c61..0f75cb7e 100644 { if (!mScreens.empty() || mPlaceholderScreen) diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h -index 09a1736a..d9c8849f 100644 +index 15104d65..49820255 100644 --- a/src/client/qwaylanddisplay_p.h +++ b/src/client/qwaylanddisplay_p.h -@@ -129,6 +129,8 @@ public: +@@ -131,6 +131,8 @@ public: QWaylandDisplay(QWaylandIntegration *waylandIntegration); ~QWaylandDisplay(void) override; @@ -1956,7 +1780,7 @@ index 09a1736a..d9c8849f 100644 struct xkb_context *xkbContext() const { return mXkbContext.get(); } #endif diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp -index e5e7dd42..f5632982 100644 +index cd8569b1..8afecb31 100644 --- a/src/client/qwaylandintegration.cpp +++ b/src/client/qwaylandintegration.cpp @@ -200,6 +200,9 @@ void QWaylandIntegration::initialize() @@ -1970,12 +1794,12 @@ index e5e7dd42..f5632982 100644 mDisplay->ensureScreen(); } -- -2.36.0 +2.49.0 -From a5df6f67f446ed091c688336510b5da2970a0d84 Mon Sep 17 00:00:00 2001 +From 21ddde34937f948deeb0e1e69068e291d1ec6556 Mon Sep 17 00:00:00 2001 From: Elvis Lee <kwangwoong.lee@lge.com> Date: Wed, 17 Mar 2021 16:31:10 +0900 -Subject: [PATCH 23/38] Connect flushRequest after forceRoundTrip +Subject: [PATCH 18/57] Connect flushRequest after forceRoundTrip If flushRequest is connected with aboutToBlock, the flushRequest may consumes all events so that processEvents might be blocked in forceRoundTrip. @@ -1988,7 +1812,7 @@ Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp -index f5632982..3a6fa651 100644 +index 8afecb31..661cea53 100644 --- a/src/client/qwaylandintegration.cpp +++ b/src/client/qwaylandintegration.cpp @@ -192,10 +192,6 @@ QAbstractEventDispatcher *QWaylandIntegration::createEventDispatcher() const @@ -2017,12 +1841,12 @@ index f5632982..3a6fa651 100644 mDisplay->ensureScreen(); } -- -2.36.0 +2.49.0 -From 967883d20e94183bd9cf6648297b9d76ba0e167e Mon Sep 17 00:00:00 2001 +From 52a15fa6e08b056dcff74afc677d895251b97148 Mon Sep 17 00:00:00 2001 From: Adrien Faveraux <af@brain-networks.fr> Date: Fri, 26 Nov 2021 09:18:58 +0100 -Subject: [PATCH 24/38] Move the wayland socket polling to a separate event +Subject: [PATCH 19/57] Move the wayland socket polling to a separate event thread New event threads is introduced which calls poll() on the wayland fd, @@ -2053,10 +1877,10 @@ Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> 5 files changed, 255 insertions(+), 108 deletions(-) diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp -index 0f75cb7e..a7ce280a 100644 +index c2482030..c38f6f82 100644 --- a/src/client/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp -@@ -85,10 +85,203 @@ +@@ -87,10 +87,203 @@ #include <errno.h> @@ -2260,7 +2084,7 @@ index 0f75cb7e..a7ce280a 100644 Q_LOGGING_CATEGORY(lcQpaWayland, "qt.qpa.wayland"); // for general (uncategorized) Wayland platform logging struct wl_surface *QWaylandDisplay::createSurface(void *handle) -@@ -162,6 +355,12 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration) +@@ -164,6 +357,12 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration) QWaylandDisplay::~QWaylandDisplay(void) { @@ -2273,7 +2097,7 @@ index 0f75cb7e..a7ce280a 100644 if (mSyncCallback) wl_callback_destroy(mSyncCallback); -@@ -208,98 +407,37 @@ void QWaylandDisplay::ensureScreen() +@@ -210,98 +409,37 @@ void QWaylandDisplay::ensureScreen() void QWaylandDisplay::checkError() const { @@ -2392,18 +2216,20 @@ index 0f75cb7e..a7ce280a 100644 } QWaylandScreen *QWaylandDisplay::screenForOutput(struct wl_output *output) const -@@ -674,4 +812,6 @@ QWaylandCursorTheme *QWaylandDisplay::loadCursorTheme(const QString &name, int p +@@ -678,6 +816,8 @@ QWaylandCursorTheme *QWaylandDisplay::loadCursorTheme(const QString &name, int p } // namespace QtWaylandClient +#include "qwaylanddisplay.moc" + QT_END_NAMESPACE + + #include "moc_qwaylanddisplay_p.cpp" diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h -index d9c8849f..42bc661d 100644 +index 49820255..cf91b924 100644 --- a/src/client/qwaylanddisplay_p.h +++ b/src/client/qwaylanddisplay_p.h -@@ -109,6 +109,7 @@ class QWaylandSurface; +@@ -111,6 +111,7 @@ class QWaylandSurface; class QWaylandShellIntegration; class QWaylandCursor; class QWaylandCursorTheme; @@ -2411,7 +2237,7 @@ index d9c8849f..42bc661d 100644 typedef void (*RegistryListener)(void *data, struct wl_registry *registry, -@@ -120,12 +121,6 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandDisplay : public QObject, public QtWayland +@@ -122,12 +123,6 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandDisplay : public QObject, public QtWayland Q_OBJECT public: @@ -2424,7 +2250,7 @@ index d9c8849f..42bc661d 100644 QWaylandDisplay(QWaylandIntegration *waylandIntegration); ~QWaylandDisplay(void) override; -@@ -212,12 +207,11 @@ public: +@@ -216,12 +211,11 @@ public: void handleKeyboardFocusChanged(QWaylandInputDevice *inputDevice); void handleWindowDestroyed(QWaylandWindow *window); @@ -2440,7 +2266,7 @@ index d9c8849f..42bc661d 100644 public slots: void blockingReadEvents(); void flushRequests(); -@@ -240,6 +234,9 @@ private: +@@ -244,6 +238,9 @@ private: }; struct wl_display *mDisplay = nullptr; @@ -2450,7 +2276,7 @@ index d9c8849f..42bc661d 100644 QtWayland::wl_compositor mCompositor; QScopedPointer<QWaylandShm> mShm; QList<QWaylandScreen *> mWaitingScreens; -@@ -276,11 +273,9 @@ private: +@@ -282,11 +279,9 @@ private: QWaylandInputDevice *mLastInputDevice = nullptr; QPointer<QWaylandWindow> mLastInputWindow; QPointer<QWaylandWindow> mLastKeyboardFocus; @@ -2464,7 +2290,7 @@ index d9c8849f..42bc661d 100644 bool mClientSideInputContextRequested = !QPlatformInputContextFactory::requested().isNull(); diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp -index 3a6fa651..3b876047 100644 +index 661cea53..fbf00c6b 100644 --- a/src/client/qwaylandintegration.cpp +++ b/src/client/qwaylandintegration.cpp @@ -192,9 +192,7 @@ QAbstractEventDispatcher *QWaylandIntegration::createEventDispatcher() const @@ -2479,7 +2305,7 @@ index 3a6fa651..3b876047 100644 // Call after eventDispatcher is fully connected, for QWaylandDisplay::forceRoundTrip() mDisplay->initialize(); diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp -index 1597f67e..7de19a74 100644 +index 41e56d24..a38f7d55 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -76,7 +76,6 @@ QWaylandWindow *QWaylandWindow::mMouseGrab = nullptr; @@ -2499,7 +2325,7 @@ index 1597f67e..7de19a74 100644 delete mWindowDecoration; if (mSurface) -@@ -635,6 +632,8 @@ const wl_callback_listener QWaylandWindow::callbackListener = { +@@ -648,6 +645,8 @@ const wl_callback_listener QWaylandWindow::callbackListener = { void QWaylandWindow::handleFrameCallback() { @@ -2508,7 +2334,7 @@ index 1597f67e..7de19a74 100644 mWaitingForFrameCallback = false; mFrameCallbackElapsedTimer.invalidate(); -@@ -656,12 +655,16 @@ void QWaylandWindow::handleFrameCallback() +@@ -669,12 +668,16 @@ void QWaylandWindow::handleFrameCallback() mWaitingForUpdateDelivery = true; QMetaObject::invokeMethod(this, doHandleExpose, Qt::QueuedConnection); } @@ -2527,7 +2353,7 @@ index 1597f67e..7de19a74 100644 if (mWaitingForFrameCallback) { qCDebug(lcWaylandBackingstore) << "Didn't receive frame callback in time, window should now be inexposed"; -@@ -1157,8 +1160,11 @@ void QWaylandWindow::requestUpdate() +@@ -1186,8 +1189,11 @@ void QWaylandWindow::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 @@ -2541,7 +2367,7 @@ index 1597f67e..7de19a74 100644 // If we've already called deliverUpdateRequest(), but haven't seen any attach+commit/swap yet // This is a somewhat redundant behavior and might indicate a bug in the calling code, so log -@@ -1171,7 +1177,12 @@ void QWaylandWindow::requestUpdate() +@@ -1200,7 +1206,12 @@ void QWaylandWindow::requestUpdate() // so use invokeMethod to delay the delivery a bit. QMetaObject::invokeMethod(this, [this] { // Things might have changed in the meantime @@ -2555,7 +2381,7 @@ index 1597f67e..7de19a74 100644 deliverUpdateRequest(); }, Qt::QueuedConnection); } -@@ -1191,9 +1202,10 @@ void QWaylandWindow::handleUpdate() +@@ -1220,9 +1231,10 @@ void QWaylandWindow::handleUpdate() if (!mSurface) return; @@ -2568,7 +2394,7 @@ index 1597f67e..7de19a74 100644 mFrameCallback = wl_surface_frame(wrappedSurface); wl_proxy_wrapper_destroy(wrappedSurface); wl_callback_add_listener(mFrameCallback, &QWaylandWindow::callbackListener, this); -@@ -1203,6 +1215,8 @@ void QWaylandWindow::handleUpdate() +@@ -1232,6 +1244,8 @@ void QWaylandWindow::handleUpdate() // Start a timer for handling the case when the compositor stops sending frame callbacks. if (mFrameCallbackTimeout > 0) { QMetaObject::invokeMethod(this, [this] { @@ -2578,7 +2404,7 @@ index 1597f67e..7de19a74 100644 if (mFrameCallbackCheckIntervalTimerId < 0) mFrameCallbackCheckIntervalTimerId = startTimer(mFrameCallbackTimeout); diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h -index e0687962..d45980a8 100644 +index fb3ed606..54ac67a9 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -232,7 +232,7 @@ protected: @@ -2591,241 +2417,12 @@ index e0687962..d45980a8 100644 // True when we have called deliverRequestUpdate, but the client has not yet attached a new buffer -- -2.36.0 - -From 520f58c24e0fbb33f84f329fc9879b72710c77ae Mon Sep 17 00:00:00 2001 -From: Roman Genkhel <roman.genhel@lge.com> -Date: Thu, 12 Nov 2020 12:21:51 +0300 -Subject: [PATCH 25/38] Check pointer for null before use in ASSERT - -Task-number: QTBUG-85195 -Change-Id: I331e54f6e58aa9d536351a55223610c60b3cb414 -Reviewed-by: David Edmundson <davidedmundson@kde.org> -(cherry picked from commit e235e8ddb1fc3cc5ab3b70b1fb285770b2c8c9ca) ---- - src/client/qwaylandwindow.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp -index 7de19a74..ac01dc05 100644 ---- a/src/client/qwaylandwindow.cpp -+++ b/src/client/qwaylandwindow.cpp -@@ -552,8 +552,8 @@ void QWaylandWindow::sendRecursiveExposeEvent() - - void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y) - { -- Q_ASSERT(!buffer->committed()); - if (buffer) { -+ Q_ASSERT(!buffer->committed()); - handleUpdate(); - buffer->setBusy(); - --- -2.36.0 - -From 72f64f397c72afb22df1825382e17a310517add1 Mon Sep 17 00:00:00 2001 -From: Inho Lee <inho.lee@qt.io> -Date: Mon, 1 Nov 2021 14:23:58 +0100 -Subject: [PATCH 26/38] Do not create decorations when the shellSurface is not - ready - -A cases reported that client windows try to make decorations -when their shell surfaces are null. -Since the surfaces' requests for decorations should be applied, -those case will be failed to create decorations. - -This patch was modified by Paul Tvete's advice. -(paul.tvete@qt.io) - -Pick-to: 6.2 5.15 -Task-number: QTBUG-97608 -Change-Id: I2563dbd73b730f81cc411857af07da99ceb2d063 -Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io> -(cherry picked from commit 246f0c0bc01dd059bf8165e81f7b49efa36e4d95) ---- - src/client/qwaylandwindow.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp -index ac01dc05..acfe390e 100644 ---- a/src/client/qwaylandwindow.cpp -+++ b/src/client/qwaylandwindow.cpp -@@ -813,7 +813,7 @@ bool QWaylandWindow::createDecoration() - decoration = false; - if (mSubSurfaceWindow) - decoration = false; -- if (mShellSurface && !mShellSurface->wantsDecorations()) -+ if (!mShellSurface || !mShellSurface->wantsDecorations()) - decoration = false; - - bool hadDecoration = mWindowDecoration; --- -2.36.0 - -From 6935647966b456e760745a6b2a13a04ba6543803 Mon Sep 17 00:00:00 2001 -From: Paul Olav Tvete <paul.tvete@qt.io> -Date: Mon, 6 Jul 2020 14:37:35 +0200 -Subject: [PATCH 27/38] Use wl_surface.damage_buffer on the client side - -Prefer the newer, recommended damage_buffer when the compositor -supports it. - -Fixes: QTBUG-74929 -Change-Id: I9107966910b616a666931404a7b41bfac14c22c0 -Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> -(cherry picked from commit 314fd6db51277224cdc799b039ef79db1101f5cd) ---- - src/client/qwaylanddisplay.cpp | 2 +- - src/client/qwaylandwindow.cpp | 16 +++++++++++++--- - tests/auto/client/shared/coreprotocol.h | 2 +- - tests/auto/client/shared_old/mockcompositor.cpp | 2 +- - tests/auto/client/shared_old/mocksurface.cpp | 10 ++++++++++ - tests/auto/client/shared_old/mocksurface.h | 2 ++ - 6 files changed, 28 insertions(+), 6 deletions(-) - -diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp -index a7ce280a..6f1bada5 100644 ---- a/src/client/qwaylanddisplay.cpp -+++ b/src/client/qwaylanddisplay.cpp -@@ -488,7 +488,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin - if (interface == QStringLiteral("wl_output")) { - mWaitingScreens << new QWaylandScreen(this, version, id); - } else if (interface == QStringLiteral("wl_compositor")) { -- mCompositorVersion = qMin((int)version, 3); -+ mCompositorVersion = qMin((int)version, 4); - mCompositor.init(registry, id, mCompositorVersion); - } else if (interface == QStringLiteral("wl_shm")) { - mShm.reset(new QWaylandShm(this, version, id)); -diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp -index acfe390e..4c5711a0 100644 ---- a/src/client/qwaylandwindow.cpp -+++ b/src/client/qwaylandwindow.cpp -@@ -571,7 +571,11 @@ void QWaylandWindow::attachOffset(QWaylandBuffer *buffer) - - void QWaylandWindow::damage(const QRect &rect) - { -- mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height()); -+ const int s = scale(); -+ if (mDisplay->compositorVersion() >= 4) -+ mSurface->damage_buffer(s * rect.x(), s * rect.y(), s * rect.width(), s * rect.height()); -+ else -+ mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height()); - } - - void QWaylandWindow::safeCommit(QWaylandBuffer *buffer, const QRegion &damage) -@@ -605,8 +609,14 @@ void QWaylandWindow::commit(QWaylandBuffer *buffer, const QRegion &damage) - return; - - attachOffset(buffer); -- for (const QRect &rect: damage) -- mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height()); -+ if (mDisplay->compositorVersion() >= 4) { -+ const int s = scale(); -+ for (const QRect &rect: damage) -+ mSurface->damage_buffer(s * rect.x(), s * rect.y(), s * rect.width(), s * rect.height()); -+ } else { -+ for (const QRect &rect: damage) -+ mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height()); -+ } - Q_ASSERT(!buffer->committed()); - buffer->setCommitted(); - mSurface->commit(); -diff --git a/tests/auto/client/shared/coreprotocol.h b/tests/auto/client/shared/coreprotocol.h -index a1af137a..296dbf47 100644 ---- a/tests/auto/client/shared/coreprotocol.h -+++ b/tests/auto/client/shared/coreprotocol.h -@@ -158,7 +158,7 @@ class WlCompositor : public Global, public QtWaylandServer::wl_compositor - { - Q_OBJECT - public: -- explicit WlCompositor(CoreCompositor *compositor, int version = 3) -+ explicit WlCompositor(CoreCompositor *compositor, int version = 4) - : QtWaylandServer::wl_compositor(compositor->m_display, version) - , m_compositor(compositor) - {} -diff --git a/tests/auto/client/shared_old/mockcompositor.cpp b/tests/auto/client/shared_old/mockcompositor.cpp -index a415cbf5..b1d3d07d 100644 ---- a/tests/auto/client/shared_old/mockcompositor.cpp -+++ b/tests/auto/client/shared_old/mockcompositor.cpp -@@ -342,7 +342,7 @@ Compositor::Compositor(MockCompositor *mockCompositor) - exit(EXIT_FAILURE); - } - -- wl_global_create(m_display, &wl_compositor_interface, 1, this, bindCompositor); -+ wl_global_create(m_display, &wl_compositor_interface, 4, this, bindCompositor); - - m_data_device_manager.reset(new DataDeviceManager(this, m_display)); - -diff --git a/tests/auto/client/shared_old/mocksurface.cpp b/tests/auto/client/shared_old/mocksurface.cpp -index e9df5f90..c3246e4a 100644 ---- a/tests/auto/client/shared_old/mocksurface.cpp -+++ b/tests/auto/client/shared_old/mocksurface.cpp -@@ -125,6 +125,16 @@ void Surface::surface_damage(Resource *resource, - Q_UNUSED(height); - } - -+void Surface::surface_damage_buffer(Resource *resource, -+ int32_t x, int32_t y, int32_t width, int32_t height) -+{ -+ Q_UNUSED(resource); -+ Q_UNUSED(x); -+ Q_UNUSED(y); -+ Q_UNUSED(width); -+ Q_UNUSED(height); -+} -+ - void Surface::surface_frame(Resource *resource, - uint32_t callback) - { -diff --git a/tests/auto/client/shared_old/mocksurface.h b/tests/auto/client/shared_old/mocksurface.h -index 949dc23d..d176837e 100644 ---- a/tests/auto/client/shared_old/mocksurface.h -+++ b/tests/auto/client/shared_old/mocksurface.h -@@ -65,6 +65,8 @@ protected: - struct wl_resource *buffer, int x, int y) override; - void surface_damage(Resource *resource, - int32_t x, int32_t y, int32_t width, int32_t height) override; -+ void surface_damage_buffer(Resource *resource, -+ int32_t x, int32_t y, int32_t width, int32_t height) override; - void surface_frame(Resource *resource, - uint32_t callback) override; - void surface_commit(Resource *resource) override; --- -2.36.0 - -From 506d0372178134f208fd08b3f6b9499fc0e14a5e Mon Sep 17 00:00:00 2001 -From: Joni Poikelin <joni.poikelin@qt.io> -Date: Thu, 3 Feb 2022 14:01:50 +0200 -Subject: [PATCH 28/38] Fix crash if no input method module could be loaded - -Pick-to: 6.2 6.3 5.15 -Change-Id: I8f346def616606a6c5540856bd08a84ee7ed5ca2 -Reviewed-by: David Edmundson <davidedmundson@kde.org> -(cherry picked from commit 49fb7248f6ab7de046e2179c7861951ea1169e9b) ---- - src/client/qwaylandintegration.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) +2.49.0 -diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp -index 3b876047..fbf00c6b 100644 ---- a/src/client/qwaylandintegration.cpp -+++ b/src/client/qwaylandintegration.cpp -@@ -491,7 +491,7 @@ void QWaylandIntegration::reconfigureInputContext() - } - #endif - -- qCDebug(lcQpaWayland) << "using input method:" << inputContext()->metaObject()->className(); -+ qCDebug(lcQpaWayland) << "using input method:" << (inputContext() ? inputContext()->metaObject()->className() : "<none>"); - } - - QWaylandShellIntegration *QWaylandIntegration::createShellIntegration(const QString &integrationName) --- -2.36.0 - -From c2e56e076f0ded39b1ab34ebf07afad2f344f53f Mon Sep 17 00:00:00 2001 +From 0068c01fc78ef3f4a2e75adf21028a44c239bff7 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii <vlad.zahorodnii@kde.org> Date: Tue, 1 Feb 2022 13:05:36 +0200 -Subject: [PATCH 29/38] Client: Remove mWaitingForUpdateDelivery +Subject: [PATCH 20/57] Client: Remove mWaitingForUpdateDelivery Currently, mWaitingForUpdateDelivery is shared between the main thread (doHandleFrameCallback()) and the frame callback event thread @@ -2847,10 +2444,10 @@ Reviewed-by: David Edmundson <davidedmundson@kde.org> 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp -index 4c5711a0..949374b1 100644 +index a38f7d55..6bf0fc4b 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp -@@ -648,23 +648,18 @@ void QWaylandWindow::handleFrameCallback() +@@ -651,23 +651,18 @@ void QWaylandWindow::handleFrameCallback() mFrameCallbackElapsedTimer.invalidate(); // The rest can wait until we can run it on the correct thread @@ -2887,7 +2484,7 @@ index 4c5711a0..949374b1 100644 mFrameSyncWait.notify_all(); } diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h -index d45980a8..3ff68ccb 100644 +index 54ac67a9..cf7ce879 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -228,7 +228,6 @@ protected: @@ -2899,135 +2496,12 @@ index d45980a8..3ff68ccb 100644 QElapsedTimer mFrameCallbackElapsedTimer; struct ::wl_callback *mFrameCallback = nullptr; -- -2.36.0 - -From 2d0bd70b55ebde2e22d0b95e8122235f90c8f9f1 Mon Sep 17 00:00:00 2001 -From: Weng Xuetian <wengxt@gmail.com> -Date: Tue, 8 Feb 2022 07:11:25 -0800 -Subject: [PATCH 30/38] Cursor position == 0 should still show the cursor - -Otherwise the cursor would be hidden even if preedit is empty. -Amends 719a55be13bdadfa659a732755f280e276a894bd - -Pick-to: 5.15 6.2 6.3 -Change-Id: I320733b917779b7b51aa4a28eaea411fdb10a318 -Reviewed-by: Liang Qi <liang.qi@qt.io> -(cherry picked from commit 31ae194e295651d9ece03408630d2358acd4f7b4) ---- - src/shared/qwaylandinputmethodeventbuilder.cpp | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/shared/qwaylandinputmethodeventbuilder.cpp b/src/shared/qwaylandinputmethodeventbuilder.cpp -index 25be2509..458d818e 100644 ---- a/src/shared/qwaylandinputmethodeventbuilder.cpp -+++ b/src/shared/qwaylandinputmethodeventbuilder.cpp -@@ -151,9 +151,9 @@ QInputMethodEvent QWaylandInputMethodEventBuilder::buildPreedit(const QString &t - { - QList<QInputMethodEvent::Attribute> attributes; - -- if (m_preeditCursor <= 0) { -+ if (m_preeditCursor < 0) { - attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 0, QVariant())); -- } else if (m_preeditCursor > 0) { -+ } else { - attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, indexFromWayland(text, m_preeditCursor), 1, QVariant())); - } - --- -2.36.0 - -From f0f7b2bea822f73ae00fcfd4ee1679596d550a20 Mon Sep 17 00:00:00 2001 -From: Weng Xuetian <wengxt@gmail.com> -Date: Wed, 22 Dec 2021 10:42:38 -0800 -Subject: [PATCH 31/38] Update the preedit styling mapping - -- None mapping to no style. -- Default/Underline mapping to underline. -- Highlight/Selection mapping to background color/text color with highlight/highlight -text with underline. -- Active/Inactive mapping to bold text with underline. -- Incorrect mapping to red wave underline. - -Pick-to: 5.15 6.2 6.3 -Change-Id: Iab51d671b8f83aece8596f7f7610de19343fcceb -Reviewed-by: Aleix Pol Gonzalez <aleixpol@kde.org> -(cherry picked from commit f1fb5d9e568a24e213ee41e82a1142cef56f1098) ---- - .../qwaylandinputmethodeventbuilder.cpp | 31 ++++++++++++------- - 1 file changed, 20 insertions(+), 11 deletions(-) - -diff --git a/src/shared/qwaylandinputmethodeventbuilder.cpp b/src/shared/qwaylandinputmethodeventbuilder.cpp -index 458d818e..f50ccf30 100644 ---- a/src/shared/qwaylandinputmethodeventbuilder.cpp -+++ b/src/shared/qwaylandinputmethodeventbuilder.cpp -@@ -39,7 +39,10 @@ - - #include "qwaylandinputmethodeventbuilder_p.h" - -+#include <QBrush> -+#include <QGuiApplication> - #include <QInputMethod> -+#include <QPalette> - #include <QTextCharFormat> - - #ifdef QT_BUILD_WAYLANDCOMPOSITOR_LIB -@@ -81,32 +84,38 @@ void QWaylandInputMethodEventBuilder::addPreeditStyling(uint32_t index, uint32_t - QTextCharFormat format; - - switch (style) { -- case 0: -- case 1: -+ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_NONE: -+ break; -+ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_DEFAULT: -+ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_UNDERLINE: - format.setFontUnderline(true); - format.setUnderlineStyle(QTextCharFormat::SingleUnderline); - m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format)); - break; -- case 2: -- case 3: -+ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_ACTIVE: -+ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_INACTIVE: - format.setFontWeight(QFont::Bold); - format.setFontUnderline(true); - format.setUnderlineStyle(QTextCharFormat::SingleUnderline); - m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format)); - break; -- case 4: -- format.setFontUnderline(true); -- format.setUnderlineStyle(QTextCharFormat::SingleUnderline); -- m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format)); -+ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_HIGHLIGHT: -+ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_SELECTION: -+ { -+ format.setFontUnderline(true); -+ format.setUnderlineStyle(QTextCharFormat::SingleUnderline); -+ QPalette palette = qApp->palette(); -+ format.setBackground(QBrush(palette.color(QPalette::Active, QPalette::Highlight))); -+ format.setForeground(QBrush(palette.color(QPalette::Active, QPalette::HighlightedText))); -+ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format)); -+ } - break; -- case 5: -+ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_INCORRECT: - format.setFontUnderline(true); - format.setUnderlineStyle(QTextCharFormat::WaveUnderline); - format.setUnderlineColor(QColor(Qt::red)); - m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format)); - break; --// case QtWayland::wl_text_input::preedit_style_selection: --// case QtWayland::wl_text_input::preedit_style_none: - default: - break; - } --- -2.36.0 +2.49.0 -From 596ecf46bb0c2427cda2894dd2157b3f5a2cd34f Mon Sep 17 00:00:00 2001 +From a9f4245f4d42f544414f6bde4dc132aaf3622af0 Mon Sep 17 00:00:00 2001 From: David Edmundson <davidedmundson@kde.org> Date: Wed, 9 Feb 2022 17:20:48 +0000 -Subject: [PATCH 32/38] client: Simplify round trip behavior +Subject: [PATCH 21/57] client: Simplify round trip behavior The custom event queue was removed in 302d4ffb8549214eb4028dc3e47ec4ee4e12ffbd (2015) so the comment about not @@ -3048,10 +2522,10 @@ Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> 1 file changed, 1 insertion(+), 42 deletions(-) diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp -index 6f1bada5..86045a35 100644 +index c38f6f82..b8da02b3 100644 --- a/src/client/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp -@@ -611,50 +611,9 @@ uint32_t QWaylandDisplay::currentTimeMillisec() +@@ -615,50 +615,9 @@ uint32_t QWaylandDisplay::currentTimeMillisec() return 0; } @@ -3104,12 +2578,12 @@ index 6f1bada5..86045a35 100644 bool QWaylandDisplay::supportsWindowDecoration() const -- -2.36.0 +2.49.0 -From f7b7b39d00ae31676fc678446d7090e7a9dd95b4 Mon Sep 17 00:00:00 2001 +From 089279664f3586bb77b5378575f33af208732571 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii <vlad.zahorodnii@kde.org> Date: Sat, 19 Feb 2022 17:01:04 +0200 -Subject: [PATCH 33/38] Client: Fix opaque region setter +Subject: [PATCH 22/57] Client: Fix opaque region setter The rect is in the global coordinate system, while the opaque region must be in the surface local coordinate system. @@ -3122,7 +2596,7 @@ Reviewed-by: Aleix Pol Gonzalez <aleixpol@kde.org> 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp -index 949374b1..fee2ecdd 100644 +index 6bf0fc4b..9cc8cb12 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -372,7 +372,7 @@ void QWaylandWindow::setGeometry(const QRect &rect) @@ -3135,12 +2609,12 @@ index 949374b1..fee2ecdd 100644 void QWaylandWindow::resizeFromApplyConfigure(const QSize &sizeWithMargins, const QPoint &offset) -- -2.36.0 +2.49.0 -From 6a95428357872353a20ab6dcc5f8facdb520e8dc Mon Sep 17 00:00:00 2001 +From d8b932f753536c96acf8e8fc5cf774e8acae360e Mon Sep 17 00:00:00 2001 From: Fabian Vogt <fabian@ritter-vogt.de> Date: Fri, 4 Feb 2022 11:07:36 +0100 -Subject: [PATCH 34/38] Use proper dependencies in compile tests +Subject: [PATCH 23/57] Use proper dependencies in compile tests Use the dependencies as found by the "libraries" section instead of relying on them being available in the default location (e.g. "-ldrm"). @@ -3157,25 +2631,15 @@ different patch and not a cherry-pick of 5fc2e1915c3a Fixes: QTBUG-100475 --- - src/client/configure.json | 8 ++++---- - src/compositor/configure.json | 34 +++++++++++++++++++++++++++++----- - 2 files changed, 33 insertions(+), 9 deletions(-) + src/client/configure.json | 5 +++-- + src/compositor/configure.json | 28 +++++++++++++++++++++++++++- + 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/client/configure.json b/src/client/configure.json -index 2f424580..29222357 100644 +index 73f23362..6247f85e 100644 --- a/src/client/configure.json +++ b/src/client/configure.json -@@ -149,8 +149,7 @@ - "#endif" - ] - }, -- "libs": "-ldrm", -- "use": "egl" -+ "use": "drm egl" - }, - "vulkan-server-buffer": { - "label": "Vulkan Buffer Sharing", -@@ -168,7 +167,8 @@ +@@ -167,7 +167,8 @@ "exportAllocInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;", "return 0;" ] @@ -3185,7 +2649,7 @@ index 2f424580..29222357 100644 }, "egl_1_5-wayland": { "label": "EGL 1.5 with Wayland Platform", -@@ -183,7 +183,7 @@ +@@ -182,7 +183,7 @@ "eglGetPlatformDisplay(EGL_PLATFORM_WAYLAND_EXT, (struct wl_display *)(nullptr), nullptr);" ] }, @@ -3195,7 +2659,7 @@ index 2f424580..29222357 100644 }, diff --git a/src/compositor/configure.json b/src/compositor/configure.json -index bcfd5215..da95d07b 100644 +index c5b0f03e..031e4cc3 100644 --- a/src/compositor/configure.json +++ b/src/compositor/configure.json @@ -7,6 +7,31 @@ @@ -3230,27 +2694,7 @@ index bcfd5215..da95d07b 100644 "wayland-server": { "label": "wayland-server", "headers": "wayland-version.h", -@@ -151,8 +176,7 @@ - "#endif" - ] - }, -- "libs": "-ldrm", -- "use": "egl" -+ "use": "drm egl" - }, - "dmabuf-client-buffer": { - "label": "Linux Client dma-buf Buffer Sharing", -@@ -176,8 +200,7 @@ - "return 0;" - ] - }, -- "libs": "-ldrm", -- "use": "egl" -+ "use": "drm egl" - }, - "vulkan-server-buffer": { - "label": "Vulkan Buffer Sharing", -@@ -195,7 +218,8 @@ +@@ -193,7 +218,8 @@ "exportAllocInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;", "return 0;" ] @@ -3261,62 +2705,12 @@ index bcfd5215..da95d07b 100644 }, -- -2.36.0 - -From 169052d99391eef62c181c8b5b107280688045d1 Mon Sep 17 00:00:00 2001 -From: Liang Qi <liang.qi@qt.io> -Date: Wed, 9 Mar 2022 10:47:42 +0100 -Subject: [PATCH 35/38] client: update button state and etc in pointer_leave() - -The cleanup work needs to be done even the surface is null, for -example, a window was closed in mouse press handler, then will not -get a mouse release. - -Fixes: QTBUG-100942 -Pick-to: 5.15 6.2 6.3 -Change-Id: I637a6744909ddbe62bdeba6b21494e5a6ae7fa9f -Reviewed-by: Tang Haixiang <tanghaixiang@uniontech.com> -Reviewed-by: David Edmundson <davidedmundson@kde.org> -(cherry picked from commit 409d1080f25b653b3ff3f57c9776c5c390912206) ---- - src/client/qwaylandinputdevice.cpp | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp -index aaec7eb8..c3cc4eca 100644 ---- a/src/client/qwaylandinputdevice.cpp -+++ b/src/client/qwaylandinputdevice.cpp -@@ -685,6 +685,11 @@ public: - - void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surface *surface) - { -+ invalidateFocus(); -+ mButtons = Qt::NoButton; -+ -+ mParent->mTime = time; -+ - // The event may arrive after destroying the window, indicated by - // a null surface. - if (!surface) -@@ -696,11 +701,6 @@ void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surfac - - if (!QWaylandWindow::mouseGrab()) - setFrameEvent(new LeaveEvent(window, mSurfacePos, mGlobalPos)); -- -- invalidateFocus(); -- mButtons = Qt::NoButton; -- -- mParent->mTime = time; - } - - class MotionEvent : public QWaylandPointerEvent --- -2.36.0 +2.49.0 -From 36756f5d1b8891465bddd31e990c81e149dce0f1 Mon Sep 17 00:00:00 2001 +From 8584cc9e877ecf67452c523d1c3f1691a6af1607 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete <paul.tvete@qt.io> Date: Tue, 15 Mar 2022 15:59:15 +0100 -Subject: [PATCH 36/38] Revert "Client: Remove mWaitingForUpdateDelivery" +Subject: [PATCH 24/57] Revert "Client: Remove mWaitingForUpdateDelivery" The reverted commit introduces a severe performance regression when a client window is resized while a QtQuick renderthread @@ -3333,10 +2727,10 @@ Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp -index fee2ecdd..bf41cc5b 100644 +index 9cc8cb12..3d1be31c 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp -@@ -655,11 +655,17 @@ void QWaylandWindow::handleFrameCallback() +@@ -658,11 +658,17 @@ void QWaylandWindow::handleFrameCallback() sendExposeEvent(QRect(QPoint(), geometry().size())); if (wasExposed && hasPendingUpdateRequest()) deliverUpdateRequest(); @@ -3358,7 +2752,7 @@ index fee2ecdd..bf41cc5b 100644 mFrameSyncWait.notify_all(); } diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h -index 3ff68ccb..d45980a8 100644 +index cf7ce879..54ac67a9 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -228,6 +228,7 @@ protected: @@ -3370,12 +2764,12 @@ index 3ff68ccb..d45980a8 100644 QElapsedTimer mFrameCallbackElapsedTimer; struct ::wl_callback *mFrameCallback = nullptr; -- -2.36.0 +2.49.0 -From a83e65ddc9a965b25e435d136849a50f0b99c4ae Mon Sep 17 00:00:00 2001 +From a743f6e0516b2d286fefe74b0c045509fed9626a Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete <paul.tvete@qt.io> Date: Tue, 15 Mar 2022 16:53:04 +0100 -Subject: [PATCH 37/38] Fix race condition on mWaitingForUpdateDelivery +Subject: [PATCH 25/57] Fix race condition on mWaitingForUpdateDelivery Change-Id: I0e91bda73722468b9339fc434fe04420b5e7d3da Reviewed-by: David Edmundson <davidedmundson@kde.org> @@ -3385,10 +2779,10 @@ Reviewed-by: David Edmundson <davidedmundson@kde.org> 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp -index bf41cc5b..ceaa4c73 100644 +index 3d1be31c..014e2d87 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp -@@ -649,24 +649,21 @@ void QWaylandWindow::handleFrameCallback() +@@ -652,24 +652,21 @@ void QWaylandWindow::handleFrameCallback() // The rest can wait until we can run it on the correct thread auto doHandleExpose = [this]() { @@ -3416,7 +2810,7 @@ index bf41cc5b..ceaa4c73 100644 } diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h -index d45980a8..cb9135f6 100644 +index 54ac67a9..c0a76345 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -228,7 +228,7 @@ protected: @@ -3429,12 +2823,12 @@ index d45980a8..cb9135f6 100644 QElapsedTimer mFrameCallbackElapsedTimer; struct ::wl_callback *mFrameCallback = nullptr; -- -2.36.0 +2.49.0 -From 36659e6130ed3fc2b3f0c91423408ef5ecb7b991 Mon Sep 17 00:00:00 2001 +From 5bc262cd799c8aec1a67193dfb5e2cb95962978f Mon Sep 17 00:00:00 2001 From: Kenneth Topp <ken@bllue.org> Date: Mon, 4 Apr 2022 09:36:21 -0400 -Subject: [PATCH 38/38] use poll(2) when reading from clipboard +Subject: [PATCH 26/57] use poll(2) when reading from clipboard change clipboard read away from select(2) call which can fail when an application has large number of open files @@ -3447,10 +2841,10 @@ Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/client/qwaylanddataoffer.cpp b/src/client/qwaylanddataoffer.cpp -index c9e158cc..fe0ea8c9 100644 +index 09e29973..0241a1df 100644 --- a/src/client/qwaylanddataoffer.cpp +++ b/src/client/qwaylanddataoffer.cpp -@@ -188,17 +188,18 @@ QVariant QWaylandMimeData::retrieveData_sys(const QString &mimeType, QVariant::T +@@ -195,17 +195,18 @@ QVariant QWaylandMimeData::retrieveData_sys(const QString &mimeType, QVariant::T int QWaylandMimeData::readData(int fd, QByteArray &data) const { @@ -3477,5 +2871,2390 @@ index c9e158cc..fe0ea8c9 100644 } else if (ready == 0) { qWarning("QWaylandDataOffer: timeout reading from pipe"); -- -2.36.0 +2.49.0 + +From 32b52debc17b894e02c4292ad408d4ce60ac4880 Mon Sep 17 00:00:00 2001 +From: Ulf Hermann <ulf.hermann@qt.io> +Date: Tue, 22 Feb 2022 12:31:08 +0100 +Subject: [PATCH 27/57] Reduce memory leakage + +We need to clean up the event queue when we're done. + +Change-Id: I13a9eb77e978f4eab227a3a28dab8ebc8de94405 +Reviewed-by: David Edmundson <davidedmundson@kde.org> +(cherry picked from commit 1264e5f565d8fb7ac200e4b00531ab876922458f) +--- + src/client/qwaylanddisplay.cpp | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp +index b8da02b3..4a331a4c 100644 +--- a/src/client/qwaylanddisplay.cpp ++++ b/src/client/qwaylanddisplay.cpp +@@ -381,6 +381,9 @@ QWaylandDisplay::~QWaylandDisplay(void) + #endif + if (mDisplay) + wl_display_disconnect(mDisplay); ++ ++ if (m_frameEventQueue) ++ wl_event_queue_destroy(m_frameEventQueue); + } + + // Steps which is called just after constructor. This separates registry_global() out of the constructor +-- +2.49.0 + +From cedbdae068bedfafeb43c6661a88b8ea28cce680 Mon Sep 17 00:00:00 2001 +From: Weng Xuetian <wengxt@gmail.com> +Date: Wed, 20 Jul 2022 15:57:40 -0700 +Subject: [PATCH 28/57] Only close popup in the the hierchary + +Imagine following event sequences: +1. a tooltip is shown. activePopups = {tooltip} +2. user click menu bar to show the menu, QMenu::setVisible is called. + now activePopups(tooltip, menu} +3. tooltip visibility changed to false. +4. closePopups() close both tooltip and menu. + +This is a common pattern under wayland that menu is shown as a invisible +state. This patch tries to memorize the surface hierchary used to create +the popup role. And only close those popups whose ancesotor is hidden. + +Pick-to: 6.4 +Change-Id: I78aa0b4e32a5812603e003e756d8bcd202e94af4 +Reviewed-by: David Edmundson <davidedmundson@kde.org> +(cherry picked from commit f8e3257e9b1e22d52e9c221c62b8d9b6dd1151a3) +--- + src/client/qwaylandwindow.cpp | 33 ++++--- + src/client/qwaylandwindow_p.h | 6 ++ + .../xdg-shell-v5/qwaylandxdgpopupv5.cpp | 5 +- + .../xdg-shell-v5/qwaylandxdgpopupv5_p.h | 3 +- + .../xdg-shell-v5/qwaylandxdgshellv5.cpp | 2 +- + .../xdg-shell-v6/qwaylandxdgshellv6.cpp | 3 + + .../xdg-shell/qwaylandxdgshell.cpp | 22 +++-- + .../xdg-shell/qwaylandxdgshell_p.h | 5 +- + tests/auto/client/xdgshell/tst_xdgshell.cpp | 87 +++++++++++++++++++ + 9 files changed, 136 insertions(+), 30 deletions(-) + +diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp +index 014e2d87..1e916ca1 100644 +--- a/src/client/qwaylandwindow.cpp ++++ b/src/client/qwaylandwindow.cpp +@@ -239,6 +239,7 @@ bool QWaylandWindow::shouldCreateSubSurface() const + + void QWaylandWindow::reset() + { ++ closeChildPopups(); + delete mShellSurface; + mShellSurface = nullptr; + delete mSubSurfaceWindow; +@@ -397,21 +398,6 @@ void QWaylandWindow::sendExposeEvent(const QRect &rect) + mLastExposeGeometry = rect; + } + +- +-static QVector<QPointer<QWaylandWindow>> activePopups; +- +-void QWaylandWindow::closePopups(QWaylandWindow *parent) +-{ +- while (!activePopups.isEmpty()) { +- auto popup = activePopups.takeLast(); +- if (popup.isNull()) +- continue; +- if (popup.data() == parent) +- return; +- popup->reset(); +- } +-} +- + QPlatformScreen *QWaylandWindow::calculateScreenFromSurfaceEvents() const + { + QReadLocker lock(&mSurfaceLock); +@@ -431,8 +417,6 @@ void QWaylandWindow::setVisible(bool visible) + lastVisible = visible; + + if (visible) { +- if (window()->type() == Qt::Popup || window()->type() == Qt::ToolTip) +- activePopups << this; + initWindow(); + + setGeometry(windowGeometry()); +@@ -441,7 +425,6 @@ void QWaylandWindow::setVisible(bool visible) + // QWaylandShmBackingStore::beginPaint(). + } else { + sendExposeEvent(QRect()); +- closePopups(this); + reset(); + } + } +@@ -1304,6 +1287,20 @@ void QWaylandWindow::setOpaqueArea(const QRegion &opaqueArea) + wl_region_destroy(region); + } + ++void QWaylandWindow::addChildPopup(QWaylandWindow *surface) { ++ mChildPopups.append(surface); ++} ++ ++void QWaylandWindow::removeChildPopup(QWaylandWindow *surface) { ++ mChildPopups.removeAll(surface); ++} ++ ++void QWaylandWindow::closeChildPopups() { ++ while (!mChildPopups.isEmpty()) { ++ auto popup = mChildPopups.takeLast(); ++ popup->reset(); ++ } ++} + } + + QT_END_NAMESPACE +diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h +index c0a76345..2be87bc0 100644 +--- a/src/client/qwaylandwindow_p.h ++++ b/src/client/qwaylandwindow_p.h +@@ -207,6 +207,10 @@ public: + void handleUpdate(); + void deliverUpdateRequest() override; + ++ void addChildPopup(QWaylandWindow* child); ++ void removeChildPopup(QWaylandWindow* child); ++ void closeChildPopups(); ++ + public slots: + void applyConfigure(); + +@@ -262,6 +266,8 @@ protected: + QWaylandBuffer *mQueuedBuffer = nullptr; + QRegion mQueuedBufferDamage; + ++ QList<QPointer<QWaylandWindow>> mChildPopups; ++ + private: + void setGeometry_helper(const QRect &rect); + void initWindow(); +diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp +index 85d25e3c..60bdd491 100644 +--- a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp ++++ b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp +@@ -47,18 +47,21 @@ QT_BEGIN_NAMESPACE + + namespace QtWaylandClient { + +-QWaylandXdgPopupV5::QWaylandXdgPopupV5(struct ::xdg_popup_v5 *popup, QWaylandWindow *window) ++QWaylandXdgPopupV5::QWaylandXdgPopupV5(struct ::xdg_popup_v5 *popup, QWaylandWindow* parent, QWaylandWindow *window) + : QWaylandShellSurface(window) + , QtWayland::xdg_popup_v5(popup) ++ , m_parent(parent) + , m_window(window) + { + if (window->display()->windowExtension()) + m_extendedWindow = new QWaylandExtendedSurface(window); ++ m_parent->addChildPopup(m_window); + } + + QWaylandXdgPopupV5::~QWaylandXdgPopupV5() + { + xdg_popup_destroy(object()); ++ m_parent->removeChildPopup(m_window); + delete m_extendedWindow; + } + +diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h +index 7494f6a6..d85f130b 100644 +--- a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h ++++ b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h +@@ -70,7 +70,7 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandXdgPopupV5 : public QWaylandShellSurface + { + Q_OBJECT + public: +- QWaylandXdgPopupV5(struct ::xdg_popup_v5 *popup, QWaylandWindow *window); ++ QWaylandXdgPopupV5(struct ::xdg_popup_v5 *popup, QWaylandWindow* parent, QWaylandWindow *window); + ~QWaylandXdgPopupV5() override; + + protected: +@@ -78,6 +78,7 @@ protected: + + private: + QWaylandExtendedSurface *m_extendedWindow = nullptr; ++ QWaylandWindow *m_parent = nullptr; + QWaylandWindow *m_window = nullptr; + }; + +diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp +index 7e242c4a..def8452a 100644 +--- a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp ++++ b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp +@@ -84,7 +84,7 @@ QWaylandXdgPopupV5 *QWaylandXdgShellV5::createXdgPopup(QWaylandWindow *window, Q + int x = position.x() + parentWindow->frameMargins().left(); + int y = position.y() + parentWindow->frameMargins().top(); + +- auto popup = new QWaylandXdgPopupV5(get_xdg_popup(window->wlSurface(), parentSurface, seat, m_popupSerial, x, y), window); ++ auto popup = new QWaylandXdgPopupV5(get_xdg_popup(window->wlSurface(), parentSurface, seat, m_popupSerial, x, y), parentWindow, window); + m_popups.append(window); + QObject::connect(popup, &QWaylandXdgPopupV5::destroyed, [this, window](){ + m_popups.removeOne(window); +diff --git a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp +index 8c371661..151c78e3 100644 +--- a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp ++++ b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp +@@ -174,6 +174,7 @@ QWaylandXdgSurfaceV6::Popup::Popup(QWaylandXdgSurfaceV6 *xdgSurface, QWaylandXdg + , m_xdgSurface(xdgSurface) + , m_parent(parent) + { ++ m_parent->window()->addChildPopup(m_xdgSurface->window()); + } + + QWaylandXdgSurfaceV6::Popup::~Popup() +@@ -181,6 +182,8 @@ QWaylandXdgSurfaceV6::Popup::~Popup() + if (isInitialized()) + destroy(); + ++ m_parent->window()->removeChildPopup(m_xdgSurface->window()); ++ + if (m_grabbing) { + auto *shell = m_xdgSurface->m_shell; + Q_ASSERT(shell->m_topmostGrabbingPopup == this); +diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp +index e7bd5117..c79b0e49 100644 +--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp ++++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp +@@ -196,12 +196,17 @@ QtWayland::xdg_toplevel::resize_edge QWaylandXdgSurface::Toplevel::convertToResi + | ((edges & Qt::RightEdge) ? resize_edge_right : 0)); + } + +-QWaylandXdgSurface::Popup::Popup(QWaylandXdgSurface *xdgSurface, QWaylandXdgSurface *parent, ++QWaylandXdgSurface::Popup::Popup(QWaylandXdgSurface *xdgSurface, QWaylandWindow *parent, + QtWayland::xdg_positioner *positioner) +- : xdg_popup(xdgSurface->get_popup(parent->object(), positioner->object())) +- , m_xdgSurface(xdgSurface) ++ : m_xdgSurface(xdgSurface) ++ , m_parentXdgSurface(qobject_cast<QWaylandXdgSurface *>(parent->shellSurface())) + , m_parent(parent) + { ++ ++ init(xdgSurface->get_popup(m_parentXdgSurface ? m_parentXdgSurface->object() : nullptr, positioner->object())); ++ if (m_parent) { ++ m_parent->addChildPopup(m_xdgSurface->window()); ++ } + } + + QWaylandXdgSurface::Popup::~Popup() +@@ -209,10 +214,14 @@ QWaylandXdgSurface::Popup::~Popup() + if (isInitialized()) + destroy(); + ++ if (m_parent) { ++ m_parent->removeChildPopup(m_xdgSurface->window()); ++ } ++ + if (m_grabbing) { + auto *shell = m_xdgSurface->m_shell; + Q_ASSERT(shell->m_topmostGrabbingPopup == this); +- shell->m_topmostGrabbingPopup = m_parent->m_popup; ++ shell->m_topmostGrabbingPopup = m_parentXdgSurface ? m_parentXdgSurface->m_popup : nullptr; + m_grabbing = false; + + // Synthesize Qt enter/leave events for popup +@@ -406,8 +415,6 @@ void QWaylandXdgSurface::setPopup(QWaylandWindow *parent) + { + Q_ASSERT(!m_toplevel && !m_popup); + +- auto parentXdgSurface = static_cast<QWaylandXdgSurface *>(parent->shellSurface()); +- + auto positioner = new QtWayland::xdg_positioner(m_shell->create_positioner()); + // set_popup expects a position relative to the parent + QPoint transientPos = m_window->geometry().topLeft(); // this is absolute +@@ -422,8 +429,9 @@ void QWaylandXdgSurface::setPopup(QWaylandWindow *parent) + positioner->set_size(m_window->geometry().width(), m_window->geometry().height()); + positioner->set_constraint_adjustment(QtWayland::xdg_positioner::constraint_adjustment_slide_x + | QtWayland::xdg_positioner::constraint_adjustment_slide_y); +- m_popup = new Popup(this, parentXdgSurface, positioner); ++ m_popup = new Popup(this, parent, positioner); + positioner->destroy(); ++ + delete positioner; + } + +diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h +index 96785205..4b518f0a 100644 +--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h ++++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h +@@ -131,14 +131,15 @@ private: + + class Popup : public QtWayland::xdg_popup { + public: +- Popup(QWaylandXdgSurface *xdgSurface, QWaylandXdgSurface *parent, QtWayland::xdg_positioner *positioner); ++ Popup(QWaylandXdgSurface *xdgSurface, QWaylandWindow *parent, QtWayland::xdg_positioner *positioner); + ~Popup() override; + + void grab(QWaylandInputDevice *seat, uint serial); + void xdg_popup_popup_done() override; + + QWaylandXdgSurface *m_xdgSurface = nullptr; +- QWaylandXdgSurface *m_parent = nullptr; ++ QWaylandXdgSurface *m_parentXdgSurface = nullptr; ++ QWaylandWindow *m_parent = nullptr; + bool m_grabbing = false; + }; + +diff --git a/tests/auto/client/xdgshell/tst_xdgshell.cpp b/tests/auto/client/xdgshell/tst_xdgshell.cpp +index 1da70ff2..c5271f63 100644 +--- a/tests/auto/client/xdgshell/tst_xdgshell.cpp ++++ b/tests/auto/client/xdgshell/tst_xdgshell.cpp +@@ -46,6 +46,7 @@ private slots: + void configureStates(); + void popup(); + void tooltipOnPopup(); ++ void tooltipAndSiblingPopup(); + void switchPopups(); + void hidePopupParent(); + void pongs(); +@@ -346,6 +347,92 @@ void tst_xdgshell::tooltipOnPopup() + QCOMPOSITOR_TRY_COMPARE(xdgPopup(0), nullptr); + } + ++void tst_xdgshell::tooltipAndSiblingPopup() ++{ ++ class ToolTip : public QRasterWindow { ++ public: ++ explicit ToolTip(QWindow *parent) { ++ setTransientParent(parent); ++ setFlags(Qt::ToolTip); ++ resize(100, 100); ++ show(); ++ } ++ void mousePressEvent(QMouseEvent *event) override { ++ QRasterWindow::mousePressEvent(event); ++ m_popup = new QRasterWindow; ++ m_popup->setTransientParent(transientParent()); ++ m_popup->setFlags(Qt::Popup); ++ m_popup->resize(100, 100); ++ m_popup->show(); ++ } ++ ++ QRasterWindow *m_popup = nullptr; ++ }; ++ ++ class Window : public QRasterWindow { ++ public: ++ void mousePressEvent(QMouseEvent *event) override { ++ QRasterWindow::mousePressEvent(event); ++ m_tooltip = new ToolTip(this); ++ } ++ ToolTip *m_tooltip = nullptr; ++ }; ++ ++ Window window; ++ window.resize(200, 200); ++ window.show(); ++ ++ QCOMPOSITOR_TRY_VERIFY(xdgToplevel()); ++ exec([=] { xdgToplevel()->sendCompleteConfigure(); }); ++ QCOMPOSITOR_TRY_VERIFY(xdgToplevel()->m_xdgSurface->m_committedConfigureSerial); ++ ++ exec([=] { ++ auto *surface = xdgToplevel()->surface(); ++ auto *p = pointer(); ++ auto *c = client(); ++ p->sendEnter(surface, {100, 100}); ++ p->sendFrame(c); ++ p->sendButton(client(), BTN_LEFT, Pointer::button_state_pressed); ++ p->sendButton(client(), BTN_LEFT, Pointer::button_state_released); ++ p->sendFrame(c); ++ p->sendLeave(surface); ++ p->sendFrame(c); ++ }); ++ ++ QCOMPOSITOR_TRY_VERIFY(xdgPopup()); ++ exec([=] { xdgPopup()->sendCompleteConfigure(QRect(100, 100, 100, 100)); }); ++ QCOMPOSITOR_TRY_VERIFY(xdgPopup()->m_xdgSurface->m_committedConfigureSerial); ++ QCOMPOSITOR_TRY_VERIFY(!xdgPopup()->m_grabbed); ++ ++ exec([=] { ++ auto *surface = xdgPopup()->surface(); ++ auto *p = pointer(); ++ auto *c = client(); ++ p->sendEnter(surface, {100, 100}); ++ p->sendFrame(c); ++ p->sendButton(client(), BTN_LEFT, Pointer::button_state_pressed); ++ p->sendButton(client(), BTN_LEFT, Pointer::button_state_released); ++ p->sendFrame(c); ++ }); ++ ++ QCOMPOSITOR_TRY_VERIFY(xdgPopup(1)); ++ exec([=] { xdgPopup(1)->sendCompleteConfigure(QRect(100, 100, 100, 100)); }); ++ QCOMPOSITOR_TRY_VERIFY(xdgPopup(1)->m_xdgSurface->m_committedConfigureSerial); ++ QCOMPOSITOR_TRY_VERIFY(xdgPopup(1)->m_grabbed); ++ ++ // Close the middle tooltip (it should not close the sibling popup) ++ window.m_tooltip->close(); ++ ++ QCOMPOSITOR_TRY_COMPARE(xdgPopup(1), nullptr); ++ // Verify the remaining xdg surface is a grab popup.. ++ QCOMPOSITOR_TRY_VERIFY(xdgPopup(0)); ++ QCOMPOSITOR_TRY_VERIFY(xdgPopup(0)->m_grabbed); ++ ++ window.m_tooltip->m_popup->close(); ++ QCOMPOSITOR_TRY_COMPARE(xdgPopup(1), nullptr); ++ QCOMPOSITOR_TRY_COMPARE(xdgPopup(0), nullptr); ++} ++ + // QTBUG-65680 + void tst_xdgshell::switchPopups() + { +-- +2.49.0 + +From dd9a2f1e29ed3ecbbaf9362cdccda7f25dc51b29 Mon Sep 17 00:00:00 2001 +From: Roman Genkhel <roman.genhel@lge.com> +Date: Thu, 12 Nov 2020 12:21:51 +0300 +Subject: [PATCH 29/57] Check pointer for null before use in ASSERT + +Task-number: QTBUG-85195 +Change-Id: I331e54f6e58aa9d536351a55223610c60b3cb414 +Reviewed-by: David Edmundson <davidedmundson@kde.org> +(cherry picked from commit e235e8ddb1fc3cc5ab3b70b1fb285770b2c8c9ca) +--- + src/client/qwaylandwindow.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp +index 1e916ca1..d98a70e4 100644 +--- a/src/client/qwaylandwindow.cpp ++++ b/src/client/qwaylandwindow.cpp +@@ -536,12 +536,12 @@ void QWaylandWindow::sendRecursiveExposeEvent() + + void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y) + { +- Q_ASSERT(!buffer->committed()); + QReadLocker locker(&mSurfaceLock); + if (mSurface == nullptr) + return; + + if (buffer) { ++ Q_ASSERT(!buffer->committed()); + handleUpdate(); + buffer->setBusy(); + +-- +2.49.0 + +From f77a9af68b6b3d2827c6942fec8607d4b57ffdd7 Mon Sep 17 00:00:00 2001 +From: Paul Olav Tvete <paul.tvete@qt.io> +Date: Mon, 6 Jul 2020 14:37:35 +0200 +Subject: [PATCH 30/57] Use wl_surface.damage_buffer on the client side + +Prefer the newer, recommended damage_buffer when the compositor +supports it. + +Fixes: QTBUG-74929 +Change-Id: I9107966910b616a666931404a7b41bfac14c22c0 +Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> +(cherry picked from commit 314fd6db51277224cdc799b039ef79db1101f5cd) +--- + src/client/qwaylanddisplay.cpp | 2 +- + src/client/qwaylandwindow.cpp | 16 +++++++++++++--- + tests/auto/client/shared/coreprotocol.h | 2 +- + tests/auto/client/shared_old/mockcompositor.cpp | 2 +- + tests/auto/client/shared_old/mocksurface.cpp | 10 ++++++++++ + tests/auto/client/shared_old/mocksurface.h | 2 ++ + 6 files changed, 28 insertions(+), 6 deletions(-) + +diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp +index 4a331a4c..f23c459d 100644 +--- a/src/client/qwaylanddisplay.cpp ++++ b/src/client/qwaylanddisplay.cpp +@@ -493,7 +493,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin + if (interface == QStringLiteral("wl_output")) { + mWaitingScreens << new QWaylandScreen(this, version, id); + } else if (interface == QStringLiteral("wl_compositor")) { +- mCompositorVersion = qMin((int)version, 3); ++ mCompositorVersion = qMin((int)version, 4); + mCompositor.init(registry, id, mCompositorVersion); + } else if (interface == QStringLiteral("wl_shm")) { + mShm.reset(new QWaylandShm(this, version, id)); +diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp +index d98a70e4..60665394 100644 +--- a/src/client/qwaylandwindow.cpp ++++ b/src/client/qwaylandwindow.cpp +@@ -563,7 +563,11 @@ void QWaylandWindow::damage(const QRect &rect) + if (mSurface == nullptr) + return; + +- mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height()); ++ const int s = scale(); ++ if (mDisplay->compositorVersion() >= 4) ++ mSurface->damage_buffer(s * rect.x(), s * rect.y(), s * rect.width(), s * rect.height()); ++ else ++ mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height()); + } + + void QWaylandWindow::safeCommit(QWaylandBuffer *buffer, const QRegion &damage) +@@ -599,8 +603,14 @@ void QWaylandWindow::commit(QWaylandBuffer *buffer, const QRegion &damage) + return; + + attachOffset(buffer); +- for (const QRect &rect: damage) +- mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height()); ++ if (mDisplay->compositorVersion() >= 4) { ++ const int s = scale(); ++ for (const QRect &rect: damage) ++ mSurface->damage_buffer(s * rect.x(), s * rect.y(), s * rect.width(), s * rect.height()); ++ } else { ++ for (const QRect &rect: damage) ++ mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height()); ++ } + Q_ASSERT(!buffer->committed()); + buffer->setCommitted(); + mSurface->commit(); +diff --git a/tests/auto/client/shared/coreprotocol.h b/tests/auto/client/shared/coreprotocol.h +index a1af137a..296dbf47 100644 +--- a/tests/auto/client/shared/coreprotocol.h ++++ b/tests/auto/client/shared/coreprotocol.h +@@ -158,7 +158,7 @@ class WlCompositor : public Global, public QtWaylandServer::wl_compositor + { + Q_OBJECT + public: +- explicit WlCompositor(CoreCompositor *compositor, int version = 3) ++ explicit WlCompositor(CoreCompositor *compositor, int version = 4) + : QtWaylandServer::wl_compositor(compositor->m_display, version) + , m_compositor(compositor) + {} +diff --git a/tests/auto/client/shared_old/mockcompositor.cpp b/tests/auto/client/shared_old/mockcompositor.cpp +index a415cbf5..b1d3d07d 100644 +--- a/tests/auto/client/shared_old/mockcompositor.cpp ++++ b/tests/auto/client/shared_old/mockcompositor.cpp +@@ -342,7 +342,7 @@ Compositor::Compositor(MockCompositor *mockCompositor) + exit(EXIT_FAILURE); + } + +- wl_global_create(m_display, &wl_compositor_interface, 1, this, bindCompositor); ++ wl_global_create(m_display, &wl_compositor_interface, 4, this, bindCompositor); + + m_data_device_manager.reset(new DataDeviceManager(this, m_display)); + +diff --git a/tests/auto/client/shared_old/mocksurface.cpp b/tests/auto/client/shared_old/mocksurface.cpp +index e9df5f90..c3246e4a 100644 +--- a/tests/auto/client/shared_old/mocksurface.cpp ++++ b/tests/auto/client/shared_old/mocksurface.cpp +@@ -125,6 +125,16 @@ void Surface::surface_damage(Resource *resource, + Q_UNUSED(height); + } + ++void Surface::surface_damage_buffer(Resource *resource, ++ int32_t x, int32_t y, int32_t width, int32_t height) ++{ ++ Q_UNUSED(resource); ++ Q_UNUSED(x); ++ Q_UNUSED(y); ++ Q_UNUSED(width); ++ Q_UNUSED(height); ++} ++ + void Surface::surface_frame(Resource *resource, + uint32_t callback) + { +diff --git a/tests/auto/client/shared_old/mocksurface.h b/tests/auto/client/shared_old/mocksurface.h +index 949dc23d..d176837e 100644 +--- a/tests/auto/client/shared_old/mocksurface.h ++++ b/tests/auto/client/shared_old/mocksurface.h +@@ -65,6 +65,8 @@ protected: + struct wl_resource *buffer, int x, int y) override; + void surface_damage(Resource *resource, + int32_t x, int32_t y, int32_t width, int32_t height) override; ++ void surface_damage_buffer(Resource *resource, ++ int32_t x, int32_t y, int32_t width, int32_t height) override; + void surface_frame(Resource *resource, + uint32_t callback) override; + void surface_commit(Resource *resource) override; +-- +2.49.0 + +From 0935e540b8a35f451cd473665c81deb8ccc7cc89 Mon Sep 17 00:00:00 2001 +From: David Edmundson <davidedmundson@kde.org> +Date: Fri, 5 Aug 2022 15:00:31 +0100 +Subject: [PATCH 31/57] Client: clear focus on touch cancel + +When we get a touch_cancel event all touches should be treated as +lifted. + +The next frame call focus is set, with no pending touch points but +without having gone through touch_up. We call mPendingTouchPoints.last() +without guards even though it is potentially now empty. + +Change-Id: I3719f9507c5d397d8641692271d878076b7c23b8 +Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> +Reviewed-by: Liang Qi <liang.qi@qt.io> +Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> +(cherry picked from commit dbdcd92363b44d89440dcb195d8cb9e6c34f0ddf) +--- + src/client/qwaylandinputdevice.cpp | 1 + + tests/auto/client/seatv5/tst_seatv5.cpp | 30 +++++++++++++++++++++++ + tests/auto/client/shared/coreprotocol.cpp | 7 ++++++ + tests/auto/client/shared/coreprotocol.h | 1 + + 4 files changed, 39 insertions(+) + +diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp +index 5ec64faf..76cbfb1f 100644 +--- a/src/client/qwaylandinputdevice.cpp ++++ b/src/client/qwaylandinputdevice.cpp +@@ -1391,6 +1391,7 @@ void QWaylandInputDevice::Touch::touch_cancel() + if (touchExt) + touchExt->touchCanceled(); + ++ mFocus = nullptr; + QWindowSystemInterface::handleTouchCancelEvent(nullptr, mParent->mTouchDevice); + } + +diff --git a/tests/auto/client/seatv5/tst_seatv5.cpp b/tests/auto/client/seatv5/tst_seatv5.cpp +index 9312c2e5..b063e0d9 100644 +--- a/tests/auto/client/seatv5/tst_seatv5.cpp ++++ b/tests/auto/client/seatv5/tst_seatv5.cpp +@@ -73,6 +73,7 @@ private slots: + void multiTouch(); + void multiTouchUpAndMotionFrame(); + void tapAndMoveInSameFrame(); ++ void cancelTouch(); + }; + + void tst_seatv5::bindsToSeat() +@@ -646,5 +647,34 @@ void tst_seatv5::tapAndMoveInSameFrame() + QTRY_COMPARE(window.m_events.last().touchPoints.first().state(), Qt::TouchPointState::TouchPointReleased); + } + ++void tst_seatv5::cancelTouch() ++{ ++ TouchWindow window; ++ QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial); ++ ++ exec([=] { ++ auto *t = touch(); ++ auto *c = client(); ++ t->sendDown(xdgToplevel()->surface(), {32, 32}, 1); ++ t->sendFrame(c); ++ t->sendCancel(c); ++ t->sendFrame(c); ++ }); ++ ++ QTRY_VERIFY(!window.m_events.empty()); ++ { ++ auto e = window.m_events.takeFirst(); ++ QCOMPARE(e.type, QEvent::TouchBegin); ++ QCOMPARE(e.touchPointStates, QEventPoint::State::Pressed); ++ QCOMPARE(e.touchPoints.length(), 1); ++ QCOMPARE(e.touchPoints.first().position(), QPointF(32-window.frameMargins().left(), 32-window.frameMargins().top())); ++ } ++ { ++ auto e = window.m_events.takeFirst(); ++ QCOMPARE(e.type, QEvent::TouchCancel); ++ QCOMPARE(e.touchPoints.length(), 0); ++ } ++} ++ + QCOMPOSITOR_TEST_MAIN(tst_seatv5) + #include "tst_seatv5.moc" +diff --git a/tests/auto/client/shared/coreprotocol.cpp b/tests/auto/client/shared/coreprotocol.cpp +index 0d988521..d1a2e7cb 100644 +--- a/tests/auto/client/shared/coreprotocol.cpp ++++ b/tests/auto/client/shared/coreprotocol.cpp +@@ -451,6 +451,13 @@ void Touch::sendFrame(wl_client *client) + send_frame(r->handle); + } + ++void Touch::sendCancel(wl_client *client) ++{ ++ const auto touchResources = resourceMap().values(client); ++ for (auto *r : touchResources) ++ send_cancel(r->handle); ++} ++ + uint Keyboard::sendEnter(Surface *surface) + { + auto serial = m_seat->m_compositor->nextSerial(); +diff --git a/tests/auto/client/shared/coreprotocol.h b/tests/auto/client/shared/coreprotocol.h +index 296dbf47..210d8ddb 100644 +--- a/tests/auto/client/shared/coreprotocol.h ++++ b/tests/auto/client/shared/coreprotocol.h +@@ -364,6 +364,7 @@ public: + uint sendUp(wl_client *client, int id); + void sendMotion(wl_client *client, const QPointF &position, int id); + void sendFrame(wl_client *client); ++ void sendCancel(wl_client *client); + + Seat *m_seat = nullptr; + }; +-- +2.49.0 + +From 1eba2ed4c7a45c4cf6098dac9c4e578da2880be2 Mon Sep 17 00:00:00 2001 +From: David Edmundson <davidedmundson@kde.org> +Date: Thu, 3 Feb 2022 19:42:33 +0000 +Subject: [PATCH 32/57] Guard mResizeDirty by the correctMutex + +mResizeDirty is used in the GUI thread in setCanResize which can be +called from the GUI thread. It is queried and set whilst the resizeLock +is held. We need to guard our usage. + +Change-Id: I5f8dcf8aa2cb2c4bb6274103df1da9e3e268605a +Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> +(cherry picked from commit 4ac96662c936821efff2875bbe555b40612caf8a) +--- + src/client/qwaylandwindow.cpp | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp +index 60665394..e5d1a97d 100644 +--- a/src/client/qwaylandwindow.cpp ++++ b/src/client/qwaylandwindow.cpp +@@ -358,11 +358,12 @@ void QWaylandWindow::setGeometry(const QRect &rect) + if (mWindowDecoration) + mWindowDecoration->update(); + +- if (mResizeAfterSwap && windowType() == Egl && mSentInitialResize) ++ if (mResizeAfterSwap && windowType() == Egl && mSentInitialResize) { ++ QMutexLocker lock(&mResizeLock); + mResizeDirty = true; +- else ++ } else { + QWindowSystemInterface::handleGeometryChange(window(), geometry()); +- ++ } + mSentInitialResize = true; + } + QRect exposeGeometry(QPoint(), geometry().size()); +-- +2.49.0 + +From 276082c73945b024ac603f65fad8699c5a70a17c Mon Sep 17 00:00:00 2001 +From: Albert Astals Cid <aacid@kde.org> +Date: Fri, 9 Sep 2022 15:37:49 +0200 +Subject: [PATCH 33/57] Fix compile tests + +Broken in c618467da4c06528537026e2b78f92265bce446f +--- + tests/auto/client/seatv5/tst_seatv5.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tests/auto/client/seatv5/tst_seatv5.cpp b/tests/auto/client/seatv5/tst_seatv5.cpp +index b063e0d9..2ea382f1 100644 +--- a/tests/auto/client/seatv5/tst_seatv5.cpp ++++ b/tests/auto/client/seatv5/tst_seatv5.cpp +@@ -665,9 +665,9 @@ void tst_seatv5::cancelTouch() + { + auto e = window.m_events.takeFirst(); + QCOMPARE(e.type, QEvent::TouchBegin); +- QCOMPARE(e.touchPointStates, QEventPoint::State::Pressed); ++ QCOMPARE(e.touchPointStates, Qt::TouchPointPressed); + QCOMPARE(e.touchPoints.length(), 1); +- QCOMPARE(e.touchPoints.first().position(), QPointF(32-window.frameMargins().left(), 32-window.frameMargins().top())); ++ QCOMPARE(e.touchPoints.first().pos(), QPointF(32-window.frameMargins().left(), 32-window.frameMargins().top())); + } + { + auto e = window.m_events.takeFirst(); +-- +2.49.0 + +From 9052ae44c73bcf9b538f1a37e8797848492b4cd2 Mon Sep 17 00:00:00 2001 +From: Fushan Wen <qydwhotmail@gmail.com> +Date: Sun, 18 Sep 2022 18:17:18 +0800 +Subject: [PATCH 34/57] 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@qt.io> +(cherry picked from commit c92282b865efcf8c571bb52b5f96d8ad260a1cda) + +BUG: 446111 +--- + src/client/qwaylanddatadevice.cpp | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp +index 89e4e372..5c5b8485 100644 +--- a/src/client/qwaylanddatadevice.cpp ++++ b/src/client/qwaylanddatadevice.cpp +@@ -302,6 +302,7 @@ void QWaylandDataDevice::selectionSourceCancelled() + #if QT_CONFIG(draganddrop) + void QWaylandDataDevice::dragSourceCancelled() + { ++ static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->finishDrag(); + m_dragSource.reset(); + } + +-- +2.49.0 + +From cdea3b7e5f10e0f9c55135ba27a62f2677231160 Mon Sep 17 00:00:00 2001 +From: David Edmundson <davidedmundson@kde.org> +Date: Mon, 12 Sep 2022 13:28:08 +0100 +Subject: [PATCH 35/57] 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@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(-) + +diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h +index 2be87bc0..ea3d1995 100644 +--- 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; + }; + +diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp +index 64f7caeb..dbe2845a 100644 +--- 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> +@@ -115,6 +116,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(); +@@ -129,8 +131,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; + } + +-- +2.49.0 + +From cb024141363e56cca76304457098ff7fbe7dd3e2 Mon Sep 17 00:00:00 2001 +From: David Redondo <qt@david-redondo.de> +Date: Wed, 8 Jun 2022 11:25:59 +0200 +Subject: [PATCH 36/57] 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@qt-project.org> +Reviewed-by: David Edmundson <davidedmundson@kde.org> +Reviewed-by: Aleix Pol Gonzalez <aleixpol@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(-) + +diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp +index fbf00c6b..54861600 100644 +--- 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() +diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp +index e5d1a97d..464441b1 100644 +--- a/src/client/qwaylandwindow.cpp ++++ b/src/client/qwaylandwindow.cpp +@@ -350,8 +350,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()) { +@@ -1033,6 +1038,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) { +diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h +index ea3d1995..487a91a6 100644 +--- 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; +-- +2.49.0 + +From f04b16e84979b8ec576adf5bdfdc3abf5aab696b Mon Sep 17 00:00:00 2001 +From: Vlad Zahorodnii <vlad.zahorodnii@kde.org> +Date: Thu, 17 Nov 2022 15:25:37 +0200 +Subject: [PATCH 37/57] 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@qt-project.org> +Reviewed-by: David Edmundson <davidedmundson@kde.org> +(cherry picked from commit 0c1cbb376e0cf878e3a91ab4917fe784a3b4c547) +--- + src/client/qwaylandshmbackingstore.cpp | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/client/qwaylandshmbackingstore.cpp b/src/client/qwaylandshmbackingstore.cpp +index dc7ff670..98acd42d 100644 +--- 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; +-- +2.49.0 + +From a18c3a89bd7dc8d9b7acc1cbde157147479731d6 Mon Sep 17 00:00:00 2001 +From: Vlad Zahorodnii <vlad.zahorodnii@kde.org> +Date: Mon, 21 Nov 2022 18:39:40 +0200 +Subject: [PATCH 38/57] Client: Call wl_output_release() upon QWaylandScreen + destruction + +It ensures that the proxy gets destroyed. + +Change-Id: I915cc8814e33dd3b0405b2bf82bd12ce6b5f785b +Reviewed-by: David Edmundson <davidedmundson@kde.org> +(cherry picked from commit 054e54759dbd6c3e76b55d5c4a9a54f62967ad1a) +--- + src/client/qwaylandscreen.cpp | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/client/qwaylandscreen.cpp b/src/client/qwaylandscreen.cpp +index 7c2d9be3..64ae4fe7 100644 +--- 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 +-- +2.49.0 + +From 9af4a53aa7a1ec0dad74d115527eeec18b5f4075 Mon Sep 17 00:00:00 2001 +From: Vlad Zahorodnii <vlad.zahorodnii@kde.org> +Date: Tue, 22 Nov 2022 12:33:41 +0200 +Subject: [PATCH 39/57] Client: Bump wl_output version + +wl_output_release is available starting with wl_output v3. + +Change-Id: I21822b26728ffb9318f1f8b4bd82ef7329682838 +Reviewed-by: David Edmundson <davidedmundson@kde.org> +(cherry picked from commit c14916f5fd84f6b5483024b3df77592661a0f04e) +--- + src/client/qwaylandscreen.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/client/qwaylandscreen.cpp b/src/client/qwaylandscreen.cpp +index 64ae4fe7..5537dafd 100644 +--- 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)) +-- +2.49.0 + +From eade2f1f746d239410d185d88404c203fed7ebdf Mon Sep 17 00:00:00 2001 +From: Weng Xuetian <wengxt@gmail.com> +Date: Sun, 27 Nov 2022 12:44:40 -0800 +Subject: [PATCH 40/57] 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(-) + +diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp +index 464441b1..96de798b 100644 +--- 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(); +@@ -1172,19 +1178,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() +@@ -1227,15 +1238,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()); +diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h +index 487a91a6..2f219d8c 100644 +--- 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; + +-- +2.49.0 + +From 029095e9efb0c296771d3df6c68b03a3e8de791e Mon Sep 17 00:00:00 2001 +From: Vlad Zahorodnii <vlad.zahorodnii@kde.org> +Date: Tue, 27 Sep 2022 22:05:07 +0300 +Subject: [PATCH 41/57] Client: Handle zwp_primary_selection_device_manager_v1 + global removal + +The zwp_primary_selection_device_manager_v1 global can be withdrawn if +the compositor disables the primary selection, i.e. middle click to +paste selected text. QtWayland needs to handle that; otherwise the app +can crash. + +Pick-to: 6.5 +Change-Id: Idbb4db18b605f85a5951fa12c1bdf61898b0d123 +Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> +(cherry picked from commit 45163234a4e4baad0012d3ee07501093d98ba91c) +--- + src/client/qwaylanddisplay.cpp | 9 +++++++++ + src/client/qwaylandprimaryselectionv1.cpp | 5 ----- + 2 files changed, 9 insertions(+), 5 deletions(-) + +diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp +index f23c459d..cc321497 100644 +--- a/src/client/qwaylanddisplay.cpp ++++ b/src/client/qwaylanddisplay.cpp +@@ -519,6 +519,8 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin + #if QT_CONFIG(wayland_client_primary_selection) + } else if (interface == QStringLiteral("zwp_primary_selection_device_manager_v1")) { + mPrimarySelectionManager.reset(new QWaylandPrimarySelectionDeviceManagerV1(this, id, 1)); ++ for (QWaylandInputDevice *inputDevice : qAsConst(mInputDevices)) ++ inputDevice->setPrimarySelectionDevice(mPrimarySelectionManager->createDevice(inputDevice)); + #endif + } else if (interface == QStringLiteral("zwp_text_input_manager_v2") && !mClientSideInputContextRequested) { + mTextInputManager.reset(new QtWayland::zwp_text_input_manager_v2(registry, id, 1)); +@@ -577,6 +579,13 @@ void QWaylandDisplay::registry_global_remove(uint32_t id) + inputDevice->setTextInput(nullptr); + mWaylandIntegration->reconfigureInputContext(); + } ++#if QT_CONFIG(wayland_client_primary_selection) ++ if (global.interface == QStringLiteral("zwp_primary_selection_device_manager_v1")) { ++ mPrimarySelectionManager.reset(); ++ for (QWaylandInputDevice *inputDevice : qAsConst(mInputDevices)) ++ inputDevice->setPrimarySelectionDevice(nullptr); ++ } ++#endif + mGlobals.removeAt(i); + break; + } +diff --git a/src/client/qwaylandprimaryselectionv1.cpp b/src/client/qwaylandprimaryselectionv1.cpp +index 7805dd73..dac532b2 100644 +--- a/src/client/qwaylandprimaryselectionv1.cpp ++++ b/src/client/qwaylandprimaryselectionv1.cpp +@@ -54,11 +54,6 @@ QWaylandPrimarySelectionDeviceManagerV1::QWaylandPrimarySelectionDeviceManagerV1 + : zwp_primary_selection_device_manager_v1(display->wl_registry(), id, qMin(version, uint(1))) + , m_display(display) + { +- // Create devices for all seats. +- // This only works if we get the global before all devices +- const auto seats = m_display->inputDevices(); +- for (auto *seat : seats) +- seat->setPrimarySelectionDevice(createDevice(seat)); + } + + QWaylandPrimarySelectionDeviceV1 *QWaylandPrimarySelectionDeviceManagerV1::createDevice(QWaylandInputDevice *seat) +-- +2.49.0 + +From 42fead566aa704237efa3c883597d4df32b56c3c Mon Sep 17 00:00:00 2001 +From: Aleix Pol <aleixpol@kde.org> +Date: Mon, 19 Dec 2022 15:31:03 +0100 +Subject: [PATCH 42/57] Fixes the build on CentOS + +Change-Id: I3c21972e7681be99b0f45c3ea3a57be285e4ff8e +--- + src/client/qwaylandshmbackingstore.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/client/qwaylandshmbackingstore.cpp b/src/client/qwaylandshmbackingstore.cpp +index 98acd42d..41cffdf7 100644 +--- a/src/client/qwaylandshmbackingstore.cpp ++++ b/src/client/qwaylandshmbackingstore.cpp +@@ -78,7 +78,7 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display, + int alloc = stride * size.height(); + int fd = -1; + +-#ifdef SYS_memfd_create ++#if defined(SYS_memfd_create) && defined(F_SEAL_SEAL) + 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); +-- +2.49.0 + +From 14ae8c7d0375693ab15b7642876a2114495a2d56 Mon Sep 17 00:00:00 2001 +From: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> +Date: Mon, 23 May 2022 09:47:24 +0200 +Subject: [PATCH 43/57] client: Avoid protocol error with invalid min/max size + +If the application sets an invalid minimum and maximum size +(where the minimum is higher than the maximum), then we +would blindly send this over the protocol, which is a protocol +error according to the spec. Qt compositors will warn about +this and ignore the size, but mainly because "but there's no +matching error defined" according to the comment. Other +compositors may close the connection when this happens. + +To avoid crashing the app based on bogus min/max size, we +make sure we never send a maximum size which is less than +the minimum size. This corresponds to the behavior of +compositors which accept the size without raising an error: +the minimum size takes precedence. + +Note that 0 means "no maximum size" in the protocol, so we +cap the value before applying this logic. + +[ChangeLog][Client] Fixed an issue where setting an invalid +minimum and maximum size on a window would cause some +compositors to raise a protocol error. + +Pick-to: 6.2 6.3 +Fixes: QTBUG-102626 +Fixes: QTBUG-103391 +Change-Id: I4004a4550a9fe3dae6a27169b4d1a9a616e21841 +Reviewed-by: David Edmundson <davidedmundson@kde.org> +(cherry picked from commit 487de47277ccc31891f6340ce4c971c91336d9a4) +--- + src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp +index c79b0e49..6ddcc410 100644 +--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp ++++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp +@@ -387,10 +387,10 @@ void QWaylandXdgSurface::setSizeHints() + const int minHeight = qMax(0, m_window->windowMinimumSize().height()); + m_toplevel->set_min_size(minWidth, minHeight); + +- int maxWidth = qMax(0, m_window->windowMaximumSize().width()); ++ int maxWidth = qMax(minWidth, m_window->windowMaximumSize().width()); + if (maxWidth == QWINDOWSIZE_MAX) + maxWidth = 0; +- int maxHeight = qMax(0, m_window->windowMaximumSize().height()); ++ int maxHeight = qMax(minHeight, m_window->windowMaximumSize().height()); + if (maxHeight == QWINDOWSIZE_MAX) + maxHeight = 0; + m_toplevel->set_max_size(maxWidth, maxHeight); +-- +2.49.0 + +From e4922c95446cf0693da5c47d1064a5120e6287ce Mon Sep 17 00:00:00 2001 +From: Vlad Zahorodnii <vlad.zahorodnii@kde.org> +Date: Tue, 22 Nov 2022 23:27:34 +0200 +Subject: [PATCH 44/57] Client: Fix handling of Qt::BlankCursor + +The cursor may not be properly set when a window has Qt::BlankCursor and +it's shown. In that case, the cursor surface may not be present and +wl_pointer.set_cursor won't be called. + +On the other hand, wl_pointer.set_cursor must be always called when +wl_pointer.enter is received. + +Pick-to: 6.5 +Change-Id: I8540e7a02df1579b3380a1a1d4cfab42c1ab3104 +Reviewed-by: David Edmundson <davidedmundson@kde.org> +Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> +(cherry picked from commit e954853f0e68d78ac1a98bc3533713881496064c) +--- + src/client/qwaylandinputdevice.cpp | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp +index 76cbfb1f..278e31f9 100644 +--- a/src/client/qwaylandinputdevice.cpp ++++ b/src/client/qwaylandinputdevice.cpp +@@ -311,8 +311,7 @@ void QWaylandInputDevice::Pointer::updateCursor() + auto shape = seat()->mCursor.shape; + + if (shape == Qt::BlankCursor) { +- if (mCursor.surface) +- mCursor.surface->hide(); ++ getOrCreateCursorSurface()->hide(); + return; + } + +-- +2.49.0 + +From 78b46c8d7045a8f4d40d55a959c995cdfabbe4d9 Mon Sep 17 00:00:00 2001 +From: Marco Martin <notmart@gmail.com> +Date: Fri, 24 Feb 2023 17:40:48 +0100 +Subject: [PATCH 45/57] client: Force a roundtrip when an XdgOutput is not + ready yet + +Is possible that the server sends a surface_enter before +all the information of the XdgOutput have been processed by the client. +in this case the associated QScreen doesn't exist yet, causing a +QWindow::SetScreen(nullptr), which will fall back to +QGuiApplication::primaryScreen(), having the QWindow being assigned the +wrong screen + +Change-Id: I923d5d3a35484deafa6f0572f79c16c27b1f87f0 +Reviewed-by: David Edmundson <davidedmundson@kde.org> +--- + src/client/qwaylandwindow.cpp | 2 ++ + tests/auto/client/shared/coreprotocol.cpp | 2 ++ + tests/auto/client/shared/coreprotocol.h | 3 ++ + tests/auto/client/xdgoutput/tst_xdgoutput.cpp | 35 +++++++++++++++++++ + 4 files changed, 42 insertions(+) + +diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp +index 96de798b..5280a9f7 100644 +--- a/src/client/qwaylandwindow.cpp ++++ b/src/client/qwaylandwindow.cpp +@@ -1042,6 +1042,8 @@ void QWaylandWindow::handleScreensChanged() + if (newScreen == mLastReportedScreen) + return; + ++ if (!newScreen->isPlaceholder() && !newScreen->QPlatformScreen::screen()) ++ mDisplay->forceRoundTrip(); + QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen()); + mLastReportedScreen = newScreen; + if (fixedToplevelPositions && !QPlatformWindow::parent() && window()->type() != Qt::Popup +diff --git a/tests/auto/client/shared/coreprotocol.cpp b/tests/auto/client/shared/coreprotocol.cpp +index d1a2e7cb..53e12291 100644 +--- a/tests/auto/client/shared/coreprotocol.cpp ++++ b/tests/auto/client/shared/coreprotocol.cpp +@@ -185,6 +185,8 @@ void Output::output_bind_resource(QtWaylandServer::wl_output::Resource *resource + + if (m_version >= WL_OUTPUT_DONE_SINCE_VERSION) + wl_output::send_done(resource->handle); ++ ++ Q_EMIT outputBound(resource); + } + + // Seat stuff +diff --git a/tests/auto/client/shared/coreprotocol.h b/tests/auto/client/shared/coreprotocol.h +index 210d8ddb..00c439e1 100644 +--- a/tests/auto/client/shared/coreprotocol.h ++++ b/tests/auto/client/shared/coreprotocol.h +@@ -273,6 +273,9 @@ public: + OutputData m_data; + int m_version = 1; // TODO: remove on libwayland upgrade + ++Q_SIGNALS: ++ void outputBound(Resource *resource); ++ + protected: + void output_bind_resource(Resource *resource) override; + }; +diff --git a/tests/auto/client/xdgoutput/tst_xdgoutput.cpp b/tests/auto/client/xdgoutput/tst_xdgoutput.cpp +index 20f762e0..2a0cad1d 100644 +--- a/tests/auto/client/xdgoutput/tst_xdgoutput.cpp ++++ b/tests/auto/client/xdgoutput/tst_xdgoutput.cpp +@@ -55,6 +55,7 @@ private slots: + void primaryScreen(); + void overrideGeometry(); + void changeGeometry(); ++ void outputCreateEnterRace(); + }; + + void tst_xdgoutput::cleanup() +@@ -134,5 +135,39 @@ void tst_xdgoutput::changeGeometry() + exec([&] { remove(output(1)); }); + } + ++void tst_xdgoutput::outputCreateEnterRace() ++{ ++ m_config.autoConfigure = true; ++ m_config.autoEnter = false; ++ QRasterWindow window; ++ QSignalSpy screenChanged(&window, &QWindow::screenChanged); ++ window.resize(400, 320); ++ window.show(); ++ QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial); ++ exec([=] { xdgToplevel()->surface()->sendEnter(output(0));}); ++ ++ QTRY_COMPARE(QGuiApplication::screens().size(), 1); ++ QScreen *primaryScreen = QGuiApplication::screens().first(); ++ QCOMPARE(window.screen(), primaryScreen); ++ ++ auto *out = exec([=] { ++ return add<Output>(); ++ }); ++ ++ // In Compositor Thread ++ connect(out, &Output::outputBound, this, [this](QtWaylandServer::wl_output::Resource *resource){ ++ auto surface = xdgToplevel()->surface(); ++ surface->sendLeave(output(0)); ++ surface->QtWaylandServer::wl_surface::send_enter(surface->resource()->handle, resource->handle); ++ }, Qt::DirectConnection); ++ ++ QTRY_COMPARE(QGuiApplication::screens().size(), 2); ++ QTRY_COMPARE(window.screen(), QGuiApplication::screens()[1]); ++ ++ exec([=] { remove(out); }); ++ m_config.autoConfigure = false; ++ m_config.autoEnter = true; ++} ++ + QCOMPOSITOR_TEST_MAIN(tst_xdgoutput) + #include "tst_xdgoutput.moc" +-- +2.49.0 + +From d6fc2f8ddc1eb2d016b7bbeccef5f433e9d8e0b6 Mon Sep 17 00:00:00 2001 +From: David Redondo <qt@david-redondo.de> +Date: Tue, 11 Apr 2023 14:27:27 +0200 +Subject: [PATCH 46/57] Destroy frame queue before display + +wl_event_queue_destroy accesses the display. +Found by running a test under valgrind. + +Pick-to: 6.5 +Change-Id: Ic89cbd3b6e98b4fc9561b0e63b5fab4886a1ec50 +Reviewed-by: David Edmundson <davidedmundson@kde.org> +(cherry picked from commit a76bf824fcd1cc3789f0d3454a0423c0241d9718) +--- + src/client/qwaylanddisplay.cpp | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp +index cc321497..737b539d 100644 +--- a/src/client/qwaylanddisplay.cpp ++++ b/src/client/qwaylanddisplay.cpp +@@ -379,11 +379,12 @@ QWaylandDisplay::~QWaylandDisplay(void) + #if QT_CONFIG(cursor) + qDeleteAll(mCursorThemes); + #endif +- if (mDisplay) +- wl_display_disconnect(mDisplay); + + if (m_frameEventQueue) + wl_event_queue_destroy(m_frameEventQueue); ++ ++ if (mDisplay) ++ wl_display_disconnect(mDisplay); + } + + // Steps which is called just after constructor. This separates registry_global() out of the constructor +-- +2.49.0 + +From 80bce1e6a818ee86011cfdad6b2a9a79cd4e0300 Mon Sep 17 00:00:00 2001 +From: David Edmundson <davidedmundson@kde.org> +Date: Wed, 7 Jun 2023 22:12:15 +0100 +Subject: [PATCH 47/57] client: Fix crash on dnd updates after client facing + drag ends + +A platform drag and a application-facing drag have two different +lifespans. + +The platform drag lasts until all mimedata is transferred and the client +receiving the drops marks it as finished. + +The application facing QDrag lasts until the client deletes it. We can +get a crash if we get updates during this time. + +The drop event is guarded, but not the action negotiation. + +Pick-to: 6.6 +Change-Id: Ib9c047f04d65883105d4cd3f169637d0e038a63f +Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> +(cherry picked from commit 22daca49b807fefba58113a06b86df4274e49f62) +--- + src/client/qwaylanddatadevice.cpp | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp +index 5c5b8485..c57f1a49 100644 +--- a/src/client/qwaylanddatadevice.cpp ++++ b/src/client/qwaylanddatadevice.cpp +@@ -138,6 +138,9 @@ bool QWaylandDataDevice::startDrag(QMimeData *mimeData, Qt::DropActions supporte + connect(m_dragSource.data(), &QWaylandDataSource::cancelled, this, &QWaylandDataDevice::dragSourceCancelled); + connect(m_dragSource.data(), &QWaylandDataSource::dndResponseUpdated, this, [this](bool accepted, Qt::DropAction action) { + auto drag = static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag()); ++ if (!drag->currentDrag()) { ++ return; ++ } + // in old versions drop action is not set, so we guess + if (wl_data_source_get_version(m_dragSource->object()) < 3) { + drag->setResponse(accepted); +-- +2.49.0 + +From 5223ce7a3620a35197d98be95d7d8ffbe1565979 Mon Sep 17 00:00:00 2001 +From: Michael Weghorn <m.weghorn@posteo.de> +Date: Mon, 20 Feb 2023 14:02:23 +0100 +Subject: [PATCH 48/57] Convert cursor bitmap to supported format + +The 1-bit image formats QImage::Format_Mono and +QImage::Format_MonoLSB used by cursor bitmaps don't have +a corresponding wl_shm_format. + +Therefore, convert to a supported image format as necessary +to make such bitmap cursors work on Wayland as well. + +Fixes: QTBUG-95434 +Change-Id: I402fd870b301ddc01075251b66f2cf7cc1923133 +Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> +(cherry picked from commit 45ec1362f8fcb5ade92f4d2d4985b1c24e78c8ba) + +Backport changes: Use Qt::ReturnByValue version for QCursor::mask() and QCursor::bitmap() +--- + src/client/qwaylandcursor.cpp | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + +diff --git a/src/client/qwaylandcursor.cpp b/src/client/qwaylandcursor.cpp +index e4eca9d4..ba76ba2d 100644 +--- a/src/client/qwaylandcursor.cpp ++++ b/src/client/qwaylandcursor.cpp +@@ -44,6 +44,7 @@ + #include "qwaylandshmbackingstore_p.h" + + #include <QtGui/QImageReader> ++#include <QBitmap> + #include <QDebug> + + #include <wayland-cursor.h> +@@ -250,7 +251,27 @@ QWaylandCursor::QWaylandCursor(QWaylandDisplay *display) + QSharedPointer<QWaylandBuffer> QWaylandCursor::cursorBitmapBuffer(QWaylandDisplay *display, const QCursor *cursor) + { + Q_ASSERT(cursor->shape() == Qt::BitmapCursor); +- const QImage &img = cursor->pixmap().toImage(); ++ ++ const QBitmap mask = cursor->mask(Qt::ReturnByValue); ++ QImage img; ++ if (cursor->pixmap().isNull()) ++ img = cursor->bitmap(Qt::ReturnByValue).toImage(); ++ else ++ img = cursor->pixmap().toImage(); ++ ++ // convert to supported format if necessary ++ if (!display->shm()->formatSupported(img.format())) { ++ if (mask.isNull()) { ++ img.convertTo(QImage::Format_RGB32); ++ } else { ++ // preserve mask ++ img.convertTo(QImage::Format_ARGB32); ++ QPixmap pixmap = QPixmap::fromImage(img); ++ pixmap.setMask(mask); ++ img = pixmap.toImage(); ++ } ++ } ++ + QSharedPointer<QWaylandShmBuffer> buffer(new QWaylandShmBuffer(display, img.size(), img.format())); + memcpy(buffer->image()->bits(), img.bits(), size_t(img.sizeInBytes())); + return buffer; +-- +2.49.0 + +From 9214e8235fa31123e83fda8b2a6bc32999863c1d Mon Sep 17 00:00:00 2001 +From: Jungi Byun <jungi.byun@lge.com> +Date: Wed, 27 Jan 2021 08:24:23 +0900 +Subject: [PATCH 49/57] Replace scale with devicePixelRatio for non-integer + scaling + +The 'scale' event from wayland cannot support non-integer scaling +which was originally supported in Qt. + +As default, devicePixelRatio follows the 'scale' so that the high DPI +still works as the mechanism in Wayland. But if non-integer scaling +factor such as 150% is needed, it can be supported to override the +devicePixelRatio. + +Change-Id: I63a04db27bd521264b6d0904e1ddd05a572dc970 +Reviewed-by: Elvis Lee <kwangwoong.lee@lge.com> +Reviewed-by: Jungi Byun <jungi.byun@lge.com> +Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> +(cherry picked from commit cf98abbc6ae9ba9373803ffe193f839324e0c80b) +--- + src/client/qwaylandabstractdecoration.cpp | 2 +- + src/client/qwaylandshmbackingstore.cpp | 6 +++--- + src/client/qwaylandshmbackingstore_p.h | 2 +- + src/client/qwaylandwindow.cpp | 16 ++++++++-------- + src/client/qwaylandwindow_p.h | 2 +- + .../client/wayland-egl/qwaylandglcontext.cpp | 2 +- + 6 files changed, 15 insertions(+), 15 deletions(-) + +diff --git a/src/client/qwaylandabstractdecoration.cpp b/src/client/qwaylandabstractdecoration.cpp +index b628930d..d15a7f9f 100644 +--- a/src/client/qwaylandabstractdecoration.cpp ++++ b/src/client/qwaylandabstractdecoration.cpp +@@ -122,7 +122,7 @@ const QImage &QWaylandAbstractDecoration::contentImage() + if (d->m_isDirty) { + // Update the decoration backingstore + +- const int bufferScale = waylandWindow()->scale(); ++ const qreal bufferScale = waylandWindow()->scale(); + const QSize imageSize = waylandWindow()->surfaceSize() * bufferScale; + d->m_decorationContentImage = QImage(imageSize, QImage::Format_ARGB32_Premultiplied); + // Only scale by buffer scale, not QT_SCALE_FACTOR etc. +diff --git a/src/client/qwaylandshmbackingstore.cpp b/src/client/qwaylandshmbackingstore.cpp +index 41cffdf7..90e37e95 100644 +--- a/src/client/qwaylandshmbackingstore.cpp ++++ b/src/client/qwaylandshmbackingstore.cpp +@@ -72,7 +72,7 @@ QT_BEGIN_NAMESPACE + namespace QtWaylandClient { + + QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display, +- const QSize &size, QImage::Format format, int scale) ++ const QSize &size, QImage::Format format, qreal scale) + { + int stride = size.width() * 4; + int alloc = stride * size.height(); +@@ -114,7 +114,7 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display, + QWaylandShm* shm = display->shm(); + wl_shm_format wl_format = shm->formatFrom(format); + mImage = QImage(data, size.width(), size.height(), stride, format); +- mImage.setDevicePixelRatio(qreal(scale)); ++ mImage.setDevicePixelRatio(scale); + + mShmPool = wl_shm_create_pool(shm->object(), fd, alloc); + init(wl_shm_pool_create_buffer(mShmPool,0, size.width(), size.height(), +@@ -277,7 +277,7 @@ QWaylandShmBuffer *QWaylandShmBackingStore::getBuffer(const QSize &size) + void QWaylandShmBackingStore::resize(const QSize &size) + { + QMargins margins = windowDecorationMargins(); +- int scale = waylandWindow()->scale(); ++ qreal scale = waylandWindow()->scale(); + QSize sizeWithMargins = (size + QSize(margins.left()+margins.right(),margins.top()+margins.bottom())) * scale; + + // We look for a free buffer to draw into. If the buffer is not the last buffer we used, +diff --git a/src/client/qwaylandshmbackingstore_p.h b/src/client/qwaylandshmbackingstore_p.h +index e01632da..f3fae438 100644 +--- a/src/client/qwaylandshmbackingstore_p.h ++++ b/src/client/qwaylandshmbackingstore_p.h +@@ -71,7 +71,7 @@ class QWaylandWindow; + class Q_WAYLAND_CLIENT_EXPORT QWaylandShmBuffer : public QWaylandBuffer { + public: + QWaylandShmBuffer(QWaylandDisplay *display, +- const QSize &size, QImage::Format format, int scale = 1); ++ const QSize &size, QImage::Format format, qreal scale = 1); + ~QWaylandShmBuffer() override; + QSize size() const override { return mImage.size(); } + int scale() const override { return int(mImage.devicePixelRatio()); } +diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp +index 5280a9f7..38b10269 100644 +--- a/src/client/qwaylandwindow.cpp ++++ b/src/client/qwaylandwindow.cpp +@@ -185,7 +185,7 @@ void QWaylandWindow::initWindow() + // typically be integer 1 (normal-dpi) or 2 (high-dpi). Call set_buffer_scale() + // to inform the compositor that high-resolution buffers will be provided. + if (mDisplay->compositorVersion() >= 3) +- mSurface->set_buffer_scale(scale()); ++ mSurface->set_buffer_scale(mScale); + + if (QScreen *s = window()->screen()) + setOrientationMask(s->orientationUpdateMask()); +@@ -572,9 +572,9 @@ void QWaylandWindow::damage(const QRect &rect) + if (mSurface == nullptr) + return; + +- const int s = scale(); ++ const qreal s = scale(); + if (mDisplay->compositorVersion() >= 4) +- mSurface->damage_buffer(s * rect.x(), s * rect.y(), s * rect.width(), s * rect.height()); ++ mSurface->damage_buffer(qFloor(s * rect.x()), qFloor(s * rect.y()), qCeil(s * rect.width()), qCeil(s * rect.height())); + else + mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height()); + } +@@ -613,9 +613,9 @@ void QWaylandWindow::commit(QWaylandBuffer *buffer, const QRegion &damage) + + attachOffset(buffer); + if (mDisplay->compositorVersion() >= 4) { +- const int s = scale(); ++ const qreal s = scale(); + for (const QRect &rect: damage) +- mSurface->damage_buffer(s * rect.x(), s * rect.y(), s * rect.width(), s * rect.height()); ++ mSurface->damage_buffer(qFloor(s * rect.x()), qFloor(s * rect.y()), qCeil(s * rect.width()), qCeil(s * rect.height())); + } else { + for (const QRect &rect: damage) + mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height()); +@@ -1106,14 +1106,14 @@ bool QWaylandWindow::isActive() const + return mDisplay->isWindowActivated(this); + } + +-int QWaylandWindow::scale() const ++qreal QWaylandWindow::scale() const + { +- return mScale; ++ return devicePixelRatio(); + } + + qreal QWaylandWindow::devicePixelRatio() const + { +- return mScale; ++ return qreal(mScale); + } + + bool QWaylandWindow::setMouseGrabEnabled(bool grab) +diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h +index 2f219d8c..741f9e5c 100644 +--- a/src/client/qwaylandwindow_p.h ++++ b/src/client/qwaylandwindow_p.h +@@ -158,7 +158,7 @@ public: + + void setMask(const QRegion ®ion) override; + +- int scale() const; ++ qreal scale() const; + qreal devicePixelRatio() const override; + + void requestActivateWindow() override; +diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp +index c1f45fa6..bbc63444 100644 +--- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp ++++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp +@@ -195,7 +195,7 @@ public: + QOpenGLTextureCache *cache = QOpenGLTextureCache::cacheForContext(m_context->context()); + + QSize surfaceSize = window->surfaceSize(); +- int scale = window->scale() ; ++ qreal scale = window->scale() ; + glViewport(0, 0, surfaceSize.width() * scale, surfaceSize.height() * scale); + + //Draw Decoration +-- +2.49.0 + +From 9792ec7b5edc421c7ca88bd10cadc8b6b8462128 Mon Sep 17 00:00:00 2001 +From: Vlad Zahorodnii <vlad.zahorodnii@kde.org> +Date: Thu, 3 Aug 2023 12:28:44 +0300 +Subject: [PATCH 50/57] Client: Fix buffer damage + +If the specified damage rectangle has fractional coordinates in the buffer +local coordinate space, the buffer damage needs to be expanded, i.e. + +- bufferRect.left = floor(rect.left * scale) +- bufferRect.right = ceil(rect.right * scale) = ceil((rect.x + rect.width) * scale) + +Flooring the coordinates and ceiling the size is not enough. It can +produce incorrect results. + +For example, consider that a rectangle with logical coordinates of +QRect(0, 23, 179, 46) has been damaged in a window with scale 1.5. When +flooring the coordinates and ceiling the size, the following buffer +damage rect will be produced: QRect(0, 34, 269, 69). Its height is off by +1, the expected height is 70 (ceil((23 + 46) * 1.5) - floor(23 * 1.5) = +ceil(103.5) - floor(34.5) = 104 - 34 = 70). + +Pick-to: 5.15 6.5 6.6 +Change-Id: I927e75a2224bb58b4634125011d1305dbdfbb3aa +Reviewed-by: David Edmundson <davidedmundson@kde.org> +(cherry picked from commit d79db699866b37bd3e3358ca18a210dfc5c0b4b9) +--- + src/client/qwaylandwindow.cpp | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) + +diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp +index 38b10269..5d01507d 100644 +--- a/src/client/qwaylandwindow.cpp ++++ b/src/client/qwaylandwindow.cpp +@@ -573,10 +573,15 @@ void QWaylandWindow::damage(const QRect &rect) + return; + + const qreal s = scale(); +- if (mDisplay->compositorVersion() >= 4) +- mSurface->damage_buffer(qFloor(s * rect.x()), qFloor(s * rect.y()), qCeil(s * rect.width()), qCeil(s * rect.height())); +- else ++ if (mDisplay->compositorVersion() >= 4) { ++ const QRect bufferRect = ++ QRectF(s * rect.x(), s * rect.y(), s * rect.width(), s * rect.height()) ++ .toAlignedRect(); ++ mSurface->damage_buffer(bufferRect.x(), bufferRect.y(), bufferRect.width(), ++ bufferRect.height()); ++ } else { + mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height()); ++ } + } + + void QWaylandWindow::safeCommit(QWaylandBuffer *buffer, const QRegion &damage) +@@ -614,8 +619,13 @@ void QWaylandWindow::commit(QWaylandBuffer *buffer, const QRegion &damage) + attachOffset(buffer); + if (mDisplay->compositorVersion() >= 4) { + const qreal s = scale(); +- for (const QRect &rect: damage) +- mSurface->damage_buffer(qFloor(s * rect.x()), qFloor(s * rect.y()), qCeil(s * rect.width()), qCeil(s * rect.height())); ++ for (const QRect &rect : damage) { ++ const QRect bufferRect = ++ QRectF(s * rect.x(), s * rect.y(), s * rect.width(), s * rect.height()) ++ .toAlignedRect(); ++ mSurface->damage_buffer(bufferRect.x(), bufferRect.y(), bufferRect.width(), ++ bufferRect.height()); ++ } + } else { + for (const QRect &rect: damage) + mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height()); +-- +2.49.0 + +From b2757109906778aee52f8fd97f129800b8b10139 Mon Sep 17 00:00:00 2001 +From: Vlad Zahorodnii <vlad.zahorodnii@kde.org> +Date: Fri, 25 Aug 2023 10:19:07 +0300 +Subject: [PATCH 51/57] Client: Commit the initial surface state explicitly + +QWaylandWindow lacks an explicit step to finish initializing the shell +surface by committing the surface. So far it used to work because of +hidden surface commits in +QWaylandWindow::handleContentOrientationChange(), +QWaylandWindow::setMask() and so on. + +This change adds an explicit step to commit the initial surface state to +make the shell surface initialization robust. + +Change-Id: Ibc38a4e0dbea689a727451c25a61af0270c7e548 +Reviewed-by: David Edmundson <davidedmundson@kde.org> +(cherry picked from commit 225432c2294bdfbf24856b2f155cd274b24543b2) +--- + src/client/qwaylandwindow.cpp | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp +index 5d01507d..5eee0414 100644 +--- a/src/client/qwaylandwindow.cpp ++++ b/src/client/qwaylandwindow.cpp +@@ -200,6 +200,8 @@ void QWaylandWindow::initWindow() + mShellSurface->requestWindowStates(window()->windowStates()); + handleContentOrientationChange(window()->contentOrientation()); + mFlags = window()->flags(); ++ ++ mSurface->commit(); + } + + void QWaylandWindow::initializeWlSurface() +-- +2.49.0 + +From cd324e2ff6130dbd2a17799e28a87743894e5d94 Mon Sep 17 00:00:00 2001 +From: Vlad Zahorodnii <vlad.zahorodnii@kde.org> +Date: Fri, 15 Sep 2023 10:06:32 +0300 +Subject: [PATCH 52/57] tests: Fix tst_xdgshell::minMaxSize() + +Amends e8cff6fb39c0fd01548bce18542820a6612dbe49. + +The new size hints will be committed when the surface is committed. + +Change-Id: I94e944fee7dac63d5e9ac86fb348b5d24d54abfc +Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> +(cherry picked from commit d8d3d6097afeac62f1b0285e3d5365c7cb580547) +--- + tests/auto/client/xdgshell/tst_xdgshell.cpp | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tests/auto/client/xdgshell/tst_xdgshell.cpp b/tests/auto/client/xdgshell/tst_xdgshell.cpp +index c5271f63..f2181fd6 100644 +--- a/tests/auto/client/xdgshell/tst_xdgshell.cpp ++++ b/tests/auto/client/xdgshell/tst_xdgshell.cpp +@@ -604,9 +604,11 @@ void tst_xdgshell::minMaxSize() + QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_committed.maxSize, QSize(1000, 1000)); + + window.setMaximumSize(QSize(500, 400)); ++ window.update(); + QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_committed.maxSize, QSize(500, 400)); + + window.setMinimumSize(QSize(50, 40)); ++ window.update(); + QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_committed.minSize, QSize(50, 40)); + } + +-- +2.49.0 + +From 1bbec113edfd6424f769a83b877541e5147f8233 Mon Sep 17 00:00:00 2001 +From: Vlad Zahorodnii <vlad.zahorodnii@kde.org> +Date: Fri, 25 Aug 2023 10:15:29 +0300 +Subject: [PATCH 53/57] Client: Remove some surface commits + +The buffer transform, input and opaque regions are double buffered +state. They will be applied on the next surface commit. + +But the issue with them is that the relevant code makes surface commits +too. It's undesired as it can lead to qtwayland committing partial +state, for example it can break xdg surface window geometry. + +This change removes hidden surface commits. The relevant properties will +be applied on the next frame. + +Change-Id: I1c40c9a5430fb6b91d7643b20d628f8a9a9d501a +Reviewed-by: David Edmundson <davidedmundson@kde.org> +(cherry picked from commit e8cff6fb39c0fd01548bce18542820a6612dbe49) +--- + src/client/qwaylandwindow.cpp | 4 ---- + src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp | 3 --- + 2 files changed, 7 deletions(-) + +diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp +index 5eee0414..7a9bccc1 100644 +--- a/src/client/qwaylandwindow.cpp ++++ b/src/client/qwaylandwindow.cpp +@@ -478,8 +478,6 @@ void QWaylandWindow::setMask(const QRegion &mask) + if (isOpaque()) + setOpaqueArea(mMask); + } +- +- mSurface->commit(); + } + + void QWaylandWindow::applyConfigureWhenPossible() +@@ -794,8 +792,6 @@ void QWaylandWindow::handleContentOrientationChange(Qt::ScreenOrientation orient + Q_UNREACHABLE(); + } + mSurface->set_buffer_transform(transform); +- // set_buffer_transform is double buffered, we need to commit. +- mSurface->commit(); + } + + void QWaylandWindow::setOrientationMask(Qt::ScreenOrientations mask) +diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp +index 6ddcc410..9c6cbb81 100644 +--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp ++++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp +@@ -370,9 +370,6 @@ bool QWaylandXdgSurface::wantsDecorations() const + void QWaylandXdgSurface::propagateSizeHints() + { + setSizeHints(); +- +- if (m_toplevel && m_window) +- m_window->commit(); + } + + void QWaylandXdgSurface::setWindowGeometry(const QRect &rect) +-- +2.49.0 + +From 686d1a0026a37f2fc3225b6f91ee30a73cb1c105 Mon Sep 17 00:00:00 2001 +From: Vlad Zahorodnii <vlad.zahorodnii@kde.org> +Date: Wed, 30 Aug 2023 09:49:41 +0300 +Subject: [PATCH 54/57] Client: Avoid locking resizing in + QWaylandShmBackingStore + +QWaylandWindow::setCanResize(false) will block applying configure +events. QWaylandWindow::setCanResize(true) will unblock configure events +and potentially apply a scheduled configure event if there's one. + +QWaylandWindow::setCanResize(true) has to be called **after** committing +the surface to ensure that the xdg window geometry matches the buffer. +We don't want the xdg window geometry change when painting. + +Unfortunately, setCanResize(true) can be called before the surface is +committed when using a RasterSurface, for example + + - QWaylandShmBackingStore::beginPaint(): calls setCanResize(false) + - QWaylandShmBackingStore::endPaint(): calls setCanResize(true) + - QWaylandWindow::setCanResize(true): applies pending configure event + - QWaylandShmBackingStore::flush(): commits the surface, but the xdg + window geometry is wrong now + +As is, beginPaint() and endPaint() are not entirely correct functions +where configure events can be blocked. We need functions that wrap both +painting and flushing, which are not feasible with the current backing +store design. + +On the other hand, it's worth noting that blocking configure events in +the backing store is not necessary because painting happens on the main +thread unlike OpenGL or Vulkan code paths. + +Given the lack of synchronization points and the fact that rendering +happens on the main thread, this change removes blocking configure +events in QWaylandShmBackingStore. It fixes dolphin and various other +applications that use QtWidgets jumping while being interactively +resized. + +Change-Id: I156e4fd5e04a6bba7e8d48171510d5ab0ec89713 +Reviewed-by: David Edmundson <davidedmundson@kde.org> +(cherry picked from commit 8828452bcf2ecf4e02a64380a1697d148c4366b0) +--- + src/client/qwaylandshmbackingstore.cpp | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/src/client/qwaylandshmbackingstore.cpp b/src/client/qwaylandshmbackingstore.cpp +index 90e37e95..145f933b 100644 +--- a/src/client/qwaylandshmbackingstore.cpp ++++ b/src/client/qwaylandshmbackingstore.cpp +@@ -186,8 +186,6 @@ void QWaylandShmBackingStore::beginPaint(const QRegion ®ion) + mPainting = true; + ensureSize(); + +- waylandWindow()->setCanResize(false); +- + if (mBackBuffer->image()->hasAlphaChannel()) { + QPainter p(paintDevice()); + p.setCompositionMode(QPainter::CompositionMode_Source); +@@ -202,7 +200,6 @@ void QWaylandShmBackingStore::endPaint() + mPainting = false; + if (mPendingFlush) + flush(window(), mPendingRegion, QPoint()); +- waylandWindow()->setCanResize(true); + } + + void QWaylandShmBackingStore::ensureSize() +-- +2.49.0 + +From 898f4f4b8761f54ba4f8ea15451ad22802ad6fc4 Mon Sep 17 00:00:00 2001 +From: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> +Date: Fri, 10 May 2024 13:20:30 +0200 +Subject: [PATCH 55/57] Fix race condition in drag and drop + +The data source may be deleted by libwayland while we hold a +reference to it. This could cause crashes when dragging +and dropping repeatedly and very rapidly between two +components. + +Tapping into sourceDestroyed() for this as well allows us to +recover more gracefully. + +This also required adding some null pointer checks to the code, +since it wasn't really prepared for the data source +disappearing. + +Pick-to: 5.15 6.2 6.5 6.7 6.8 +Fixes: QTBUG-124502 +Change-Id: Ic3df8bf70176c5424ac5c693f8456f61e7b2762b +Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io> +(cherry picked from commit 792bd8510e3bc6b47bcaedfb1386390ce3a10a3a) +--- + src/compositor/wayland_wrapper/qwldatadevice.cpp | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/src/compositor/wayland_wrapper/qwldatadevice.cpp b/src/compositor/wayland_wrapper/qwldatadevice.cpp +index a3a795f9..f301678e 100644 +--- a/src/compositor/wayland_wrapper/qwldatadevice.cpp ++++ b/src/compositor/wayland_wrapper/qwldatadevice.cpp +@@ -76,6 +76,9 @@ void DataDevice::sourceDestroyed(DataSource *source) + { + if (m_selectionSource == source) + m_selectionSource = nullptr; ++ ++ if (m_dragDataSource == source) ++ m_dragDataSource = nullptr; + } + + #if QT_CONFIG(draganddrop) +@@ -105,9 +108,11 @@ void DataDevice::setDragFocus(QWaylandSurface *focus, const QPointF &localPositi + if (m_dragDataSource && !offer) + return; + +- send_enter(resource->handle, serial, focus->resource(), +- wl_fixed_from_double(localPosition.x()), wl_fixed_from_double(localPosition.y()), +- offer->resource()->handle); ++ if (offer) { ++ send_enter(resource->handle, serial, focus->resource(), ++ wl_fixed_from_double(localPosition.x()), wl_fixed_from_double(localPosition.y()), ++ offer->resource()->handle); ++ } + + m_dragFocus = focus; + m_dragFocusResource = resource; +@@ -139,7 +144,7 @@ void DataDevice::drop() + if (m_dragFocusResource) { + send_drop(m_dragFocusResource->handle); + setDragFocus(nullptr, QPoint()); +- } else { ++ } else if (m_dragDataSource) { + m_dragDataSource->cancel(); + } + m_dragOrigin = nullptr; +@@ -155,6 +160,8 @@ void DataDevice::data_device_start_drag(Resource *resource, struct ::wl_resource + { + m_dragClient = resource->client(); + m_dragDataSource = source ? DataSource::fromResource(source) : nullptr; ++ if (m_dragDataSource) ++ m_dragDataSource->setDevice(this); + m_dragOrigin = QWaylandSurface::fromResource(origin); + QWaylandDrag *drag = m_seat->drag(); + setDragIcon(icon ? QWaylandSurface::fromResource(icon) : nullptr); +-- +2.49.0 + +From ec4fa1a0bf2981b7ef6d7caec84f3b1ac706d14b Mon Sep 17 00:00:00 2001 +From: Liu Zheng <liuzheng@uniontech.com> +Date: Wed, 24 Jul 2024 09:22:42 +0800 +Subject: [PATCH 56/57] fix: variable not initialized + +If the disableResizeCheck logic is not checked, initialization will fail. Problems will arise later. + +Pick-to: 6.8 6.7 6.5 6.2 5.15 +Change-Id: Ifffd4f7407b3ef616d436b81f3b2148c1139c3f7 +Reviewed-by: Liang Qi <liang.qi@qt.io> +(cherry picked from commit dc49720c135e0d59dff42c9fd28f57a6199c33b9) +--- + .../client/wayland-egl/qwaylandeglwindow.cpp | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp +index dbe2845a..95e8c666 100644 +--- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp ++++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp +@@ -118,7 +118,8 @@ void QWaylandEglWindow::updateSurface(bool create) + } else { + QReadLocker locker(&mSurfaceLock); + if (m_waylandEglWindow) { +- int current_width, current_height; ++ int current_width = 0; ++ int current_height = 0; + static bool disableResizeCheck = qgetenv("QT_WAYLAND_DISABLE_RESIZECHECK").toInt(); + + if (!disableResizeCheck) { +-- +2.49.0 + +From c1ac089f3f37ab172d8010b0fabf4007d62d1812 Mon Sep 17 00:00:00 2001 +From: Kai Uwe Broulik <kde@privat.broulik.de> +Date: Thu, 4 Jan 2024 20:30:33 +0100 +Subject: [PATCH 57/57] bradient: Use QWaylandWindow actual window title + +It may include a suffix containing the application name +and is also what's set on the XDG Toplevel, i.e. what +the rest of the environment (task switcher, etc) sees. + +This stores the title in QWaylandWindow and adds a +getter to retrieve it. + +Pick-to: 6.7 +Change-Id: I84f41c68b16b680cdbb5cf656c7078d1e41767d4 +Reviewed-by: David Edmundson <davidedmundson@kde.org> + +(cherry-picked from commit 34c1dca) +--- + src/client/qwaylandwindow.cpp | 35 ++++++++++++++--------- + src/client/qwaylandwindow_p.h | 2 ++ + src/plugins/decorations/bradient/main.cpp | 2 +- + 3 files changed, 24 insertions(+), 15 deletions(-) + +diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp +index 7a9bccc1..7c338d27 100644 +--- a/src/client/qwaylandwindow.cpp ++++ b/src/client/qwaylandwindow.cpp +@@ -303,26 +303,33 @@ void QWaylandWindow::setParent(const QPlatformWindow *parent) + } + } + ++QString QWaylandWindow::windowTitle() const ++{ ++ return mWindowTitle; ++} ++ + void QWaylandWindow::setWindowTitle(const QString &title) + { +- if (mShellSurface) { +- const QString separator = QString::fromUtf8(" \xe2\x80\x94 "); // unicode character U+2014, EM DASH +- const QString formatted = formatWindowTitle(title, separator); ++ const QString separator = QString::fromUtf8(" \xe2\x80\x94 "); // unicode character U+2014, EM DASH ++ const QString formatted = formatWindowTitle(title, separator); + +- const int libwaylandMaxBufferSize = 4096; +- // Some parts of the buffer is used for metadata, so subtract 100 to be on the safe side. +- // Also, QString is in utf-16, which means that in the worst case each character will be +- // three bytes when converted to utf-8 (which is what libwayland uses), so divide by three. +- const int maxLength = libwaylandMaxBufferSize / 3 - 100; ++ const int libwaylandMaxBufferSize = 4096; ++ // Some parts of the buffer is used for metadata, so subtract 100 to be on the safe side. ++ // Also, QString is in utf-16, which means that in the worst case each character will be ++ // three bytes when converted to utf-8 (which is what libwayland uses), so divide by three. ++ const int maxLength = libwaylandMaxBufferSize / 3 - 100; + +- auto truncated = QStringRef(&formatted).left(maxLength); +- if (truncated.length() < formatted.length()) { +- qCWarning(lcQpaWayland) << "Window titles longer than" << maxLength << "characters are not supported." +- << "Truncating window title (from" << formatted.length() << "chars)"; +- } +- mShellSurface->setTitle(truncated.toString()); ++ auto truncated = QStringRef(&formatted).left(maxLength); ++ if (truncated.length() < formatted.length()) { ++ qCWarning(lcQpaWayland) << "Window titles longer than" << maxLength << "characters are not supported." ++ << "Truncating window title (from" << formatted.length() << "chars)"; + } + ++ mWindowTitle = truncated.toString(); ++ ++ if (mShellSurface) ++ mShellSurface->setTitle(mWindowTitle); ++ + if (mWindowDecoration && window()->isVisible()) + mWindowDecoration->update(); + } +diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h +index 741f9e5c..5e9f4ebf 100644 +--- a/src/client/qwaylandwindow_p.h ++++ b/src/client/qwaylandwindow_p.h +@@ -107,6 +107,7 @@ public: + void setVisible(bool visible) override; + void setParent(const QPlatformWindow *parent) override; + ++ QString windowTitle() const; + void setWindowTitle(const QString &title) override; + + inline QIcon windowIcon() const; +@@ -263,6 +264,7 @@ protected: + int mScale = 1; + QPlatformScreen *mLastReportedScreen = nullptr; + ++ QString mWindowTitle; + QIcon mWindowIcon; + + Qt::WindowFlags mFlags; +diff --git a/src/plugins/decorations/bradient/main.cpp b/src/plugins/decorations/bradient/main.cpp +index fa885143..fbdbe284 100644 +--- a/src/plugins/decorations/bradient/main.cpp ++++ b/src/plugins/decorations/bradient/main.cpp +@@ -171,7 +171,7 @@ void QWaylandBradientDecoration::paint(QPaintDevice *device) + } + + // Window title +- QString windowTitleText = window()->title(); ++ QString windowTitleText = waylandWindow()->windowTitle(); + if (!windowTitleText.isEmpty()) { + if (m_windowTitle.text() != windowTitleText) { + m_windowTitle.setText(windowTitleText); +-- +2.49.0 |