From c0b388c64b73d7760eed8238f869bda6566c251e Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Fri, 11 Feb 2022 12:12:05 +0100 Subject: [PATCH] - Pull in latest kde/5.15 branch fixes + backport a fix to crashes caused by patch 0043 --- ...-socket-polling-to-a-separate-event-.patch | 4 +- ...ointer-for-null-before-use-in-ASSERT.patch | 30 ++++ ...corations-when-the-shellSurface-is-n.patch | 39 ++++++ ...ace.damage_buffer-on-the-client-side.patch | 131 ++++++++++++++++++ ...-input-method-module-could-be-loaded.patch | 29 ++++ ...ent-Remove-mWaitingForUpdateDelivery.patch | 31 +++-- ...-client-simplify-round-trip-behavior.patch | 74 ++++++++++ 7 files changed, 324 insertions(+), 14 deletions(-) create mode 100644 0045-Check-pointer-for-null-before-use-in-ASSERT.patch create mode 100644 0046-Do-not-create-decorations-when-the-shellSurface-is-n.patch create mode 100644 0047-Use-wl_surface.damage_buffer-on-the-client-side.patch create mode 100644 0048-Fix-crash-if-no-input-method-module-could-be-loaded.patch rename qtwayland-client-remove-mwaitingforupdatedelivery.patch => 0049-Client-Remove-mWaitingForUpdateDelivery.patch (78%) create mode 100644 qtwayland-client-simplify-round-trip-behavior.patch diff --git a/0044-Move-the-wayland-socket-polling-to-a-separate-event-.patch b/0044-Move-the-wayland-socket-polling-to-a-separate-event-.patch index ae4e8fa..17cd072 100644 --- a/0044-Move-the-wayland-socket-polling-to-a-separate-event-.patch +++ b/0044-Move-the-wayland-socket-polling-to-a-separate-event-.patch @@ -1,7 +1,7 @@ From 4644d51f4b52e83fc1b4d02b380d80d9d57e76fa Mon Sep 17 00:00:00 2001 From: Adrien Faveraux Date: Fri, 26 Nov 2021 09:18:58 +0100 -Subject: [PATCH 44/44] Move the wayland socket polling to a separate event +Subject: [PATCH 44/49] Move the wayland socket polling to a separate event thread New event threads is introduced which calls poll() on the wayland fd, @@ -570,5 +570,5 @@ index e0687962..d45980a8 100644 // True when we have called deliverRequestUpdate, but the client has not yet attached a new buffer -- -2.34.1 +2.35.1 diff --git a/0045-Check-pointer-for-null-before-use-in-ASSERT.patch b/0045-Check-pointer-for-null-before-use-in-ASSERT.patch new file mode 100644 index 0000000..cd3d6ed --- /dev/null +++ b/0045-Check-pointer-for-null-before-use-in-ASSERT.patch @@ -0,0 +1,30 @@ +From 460a2bb54d8377586dff6d561646f3929c71370d Mon Sep 17 00:00:00 2001 +From: Roman Genkhel +Date: Thu, 12 Nov 2020 12:21:51 +0300 +Subject: [PATCH 45/49] Check pointer for null before use in ASSERT + +Task-number: QTBUG-85195 +Change-Id: I331e54f6e58aa9d536351a55223610c60b3cb414 +Reviewed-by: David Edmundson +(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.35.1 + diff --git a/0046-Do-not-create-decorations-when-the-shellSurface-is-n.patch b/0046-Do-not-create-decorations-when-the-shellSurface-is-n.patch new file mode 100644 index 0000000..6f505c1 --- /dev/null +++ b/0046-Do-not-create-decorations-when-the-shellSurface-is-n.patch @@ -0,0 +1,39 @@ +From b6d85c2a75f5618e87267f5b5c361455be257a17 Mon Sep 17 00:00:00 2001 +From: Inho Lee +Date: Mon, 1 Nov 2021 14:23:58 +0100 +Subject: [PATCH 46/49] 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 +(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.35.1 + diff --git a/0047-Use-wl_surface.damage_buffer-on-the-client-side.patch b/0047-Use-wl_surface.damage_buffer-on-the-client-side.patch new file mode 100644 index 0000000..680aac0 --- /dev/null +++ b/0047-Use-wl_surface.damage_buffer-on-the-client-side.patch @@ -0,0 +1,131 @@ +From 7200a1ad8488f157ef8ce9d5ed81a0a1c1cd1eda Mon Sep 17 00:00:00 2001 +From: Paul Olav Tvete +Date: Mon, 6 Jul 2020 14:37:35 +0200 +Subject: [PATCH 47/49] 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 +(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.35.1 + diff --git a/0048-Fix-crash-if-no-input-method-module-could-be-loaded.patch b/0048-Fix-crash-if-no-input-method-module-could-be-loaded.patch new file mode 100644 index 0000000..e564b74 --- /dev/null +++ b/0048-Fix-crash-if-no-input-method-module-could-be-loaded.patch @@ -0,0 +1,29 @@ +From ce2caf493a1343fbd9f8e4c85baf6a61c057f242 Mon Sep 17 00:00:00 2001 +From: Joni Poikelin +Date: Thu, 3 Feb 2022 14:01:50 +0200 +Subject: [PATCH 48/49] 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 +(cherry picked from commit 49fb7248f6ab7de046e2179c7861951ea1169e9b) +--- + src/client/qwaylandintegration.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +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() : ""); + } + + QWaylandShellIntegration *QWaylandIntegration::createShellIntegration(const QString &integrationName) +-- +2.35.1 + diff --git a/qtwayland-client-remove-mwaitingforupdatedelivery.patch b/0049-Client-Remove-mWaitingForUpdateDelivery.patch similarity index 78% rename from qtwayland-client-remove-mwaitingforupdatedelivery.patch rename to 0049-Client-Remove-mWaitingForUpdateDelivery.patch index 18e8386..040b0b5 100644 --- a/qtwayland-client-remove-mwaitingforupdatedelivery.patch +++ b/0049-Client-Remove-mWaitingForUpdateDelivery.patch @@ -1,12 +1,12 @@ -From 591d38d21cdd215677c6e9e8e6e0cfa9acd9c48c Mon Sep 17 00:00:00 2001 +From 214f7ab9d3384a4123f14d9f6cd0205cf0aaa794 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii -Date: Tue, 01 Feb 2022 13:05:36 +0200 -Subject: [PATCH] Client: Remove mWaitingForUpdateDelivery +Date: Tue, 1 Feb 2022 13:05:36 +0200 +Subject: [PATCH 49/49] Client: Remove mWaitingForUpdateDelivery Currently, mWaitingForUpdateDelivery is shared between the main thread (doHandleFrameCallback()) and the frame callback event thread (handleFrameCallback()), however the access to it is not synchronized -between neither both threads. On the other hand, QWaylandWindow +between both threads. On the other hand, QWaylandWindow already ensures not to create a frame callback if there's already one pending. @@ -15,17 +15,21 @@ already covered by mWaitingForFrameCallback and to remove unsynchronized shared state between threads. Change-Id: I0e5a25d18d1e66c4d7683e7e972330c4d7cbbf38 +Reviewed-by: David Edmundson +(cherry picked from commit feb1a5c207c13d0bf87c0d8ad039279dbf8cee9e) --- + src/client/qwaylandwindow.cpp | 29 ++++++++++++----------------- + src/client/qwaylandwindow_p.h | 1 - + 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp -index 0415ca9..8e321b6 100644 +index 4c5711a0..949374b1 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp -@@ -637,24 +637,18 @@ void QWaylandWindow::handleFrameCallback() - mWaitingForFrameCallback = false; +@@ -648,23 +648,18 @@ void QWaylandWindow::handleFrameCallback() mFrameCallbackElapsedTimer.invalidate(); - -- // The rest can wait until we can run it on the correct thread + + // The rest can wait until we can run it on the correct thread - if (!mWaitingForUpdateDelivery) { - auto doHandleExpose = [this]() { - bool wasExposed = isExposed(); @@ -55,14 +59,14 @@ index 0415ca9..8e321b6 100644 + // Queued connection, to make sure we don't call handleUpdate() from inside waitForFrameSync() + // in the single-threaded case. + QMetaObject::invokeMethod(this, doHandleExpose, Qt::QueuedConnection); - + mFrameSyncWait.notify_all(); } diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h -index 990e46b..2b17f89 100644 +index d45980a8..3ff68ccb 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h -@@ -240,7 +240,6 @@ protected: +@@ -228,7 +228,6 @@ protected: WId mWindowId; bool mWaitingForFrameCallback = false; bool mFrameCallbackTimedOut = false; // Whether the frame callback has timed out @@ -70,3 +74,6 @@ index 990e46b..2b17f89 100644 int mFrameCallbackCheckIntervalTimerId = -1; QElapsedTimer mFrameCallbackElapsedTimer; struct ::wl_callback *mFrameCallback = nullptr; +-- +2.35.1 + diff --git a/qtwayland-client-simplify-round-trip-behavior.patch b/qtwayland-client-simplify-round-trip-behavior.patch new file mode 100644 index 0000000..93ee0e6 --- /dev/null +++ b/qtwayland-client-simplify-round-trip-behavior.patch @@ -0,0 +1,74 @@ +From e6bef7c8770afe484425280af8e26e05bfeef53a Mon Sep 17 00:00:00 2001 +From: David Edmundson +Date: Wed, 09 Feb 2022 17:20:48 +0000 +Subject: [PATCH] client: Simplify round trip behavior + +The custom event queue was removed in +302d4ffb8549214eb4028dc3e47ec4ee4e12ffbd (2015) so the comment about not +being able to use the inbuilt round trip method no longer applies. + +This fixes a real world problem. Use of a blocking round trip should not +process non wayland events. Doing so can lead to misbehaviour client +side as things happen out of order. The move to the event thread created +several regressions as we now get events before the QGuiApplication is +fully constructed. + +Change-Id: I650481f49a47ed1a9778c7e1bc3c48db6e8f0031 +--- + +diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp +index 5937172..414fe3f 100644 +--- a/src/client/qwaylanddisplay.cpp ++++ b/src/client/qwaylanddisplay.cpp +@@ -728,50 +728,9 @@ + return 0; + } + +-static void +-sync_callback(void *data, struct wl_callback *callback, uint32_t serial) +-{ +- Q_UNUSED(serial); +- bool *done = static_cast(data); +- +- *done = true; +- +- // If the wl_callback done event is received after the condition check in the while loop in +- // forceRoundTrip(), but before the call to processEvents, the call to processEvents may block +- // forever if no more events are posted (eventhough the callback is handled in response to the +- // aboutToBlock signal). Hence, we wake up the event dispatcher so forceRoundTrip may return. +- // (QTBUG-64696) +- if (auto *dispatcher = QThread::currentThread()->eventDispatcher()) +- dispatcher->wakeUp(); +- +- wl_callback_destroy(callback); +-} +- +-static const struct wl_callback_listener sync_listener = { +- sync_callback +-}; +- + void QWaylandDisplay::forceRoundTrip() + { +- // wl_display_roundtrip() works on the main queue only, +- // but we use a separate one, so basically reimplement it here +- int ret = 0; +- bool done = false; +- wl_callback *callback = wl_display_sync(mDisplay); +- wl_callback_add_listener(callback, &sync_listener, &done); +- flushRequests(); +- if (QThread::currentThread()->eventDispatcher()) { +- while (!done && ret >= 0) { +- QThread::currentThread()->eventDispatcher()->processEvents(QEventLoop::WaitForMoreEvents); +- ret = wl_display_dispatch_pending(mDisplay); +- } +- } else { +- while (!done && ret >= 0) +- ret = wl_display_dispatch(mDisplay); +- } +- +- if (ret == -1 && !done) +- wl_callback_destroy(callback); ++ wl_display_roundtrip(mDisplay); + } + + bool QWaylandDisplay::supportsWindowDecoration() const