Blame SOURCES/0019-Client-Don-t-always-recreate-frame-callbacks.patch

869fe3
From bdd2dacf2d8668b3a1f59db3c6cc859f95868eb2 Mon Sep 17 00:00:00 2001
147f94
From: Georges Basile Stavracas Neto <gbsneto@gnome.org>
147f94
Date: Thu, 27 May 2021 19:55:04 -0300
869fe3
Subject: [PATCH 19/40] Client: Don't always recreate frame callbacks
147f94
147f94
The main QWaylandWindow method that is executed when handling updates is
147f94
QWaylandWindow::handleUpdate(). This method always, unconditionally queues
147f94
a frame callback, regardless of whether any other one is already queued.
147f94
147f94
On some circumstances, e.g. when a window is hidden or completely obscured
147f94
by other windows, it stops receiving frame callbacks from the compositor.
147f94
However, QWaylandWindow would continue to request for them, which eventually
147f94
fills up the Wayland socket, and causes the application to crash.
147f94
147f94
This can be avoided by checking if the platform window is already waiting
147f94
for a frame callback, before queueing another one.
147f94
147f94
In QWaylandWindow::handleUpdate(), check if mWaitingForFrameCallback is true
147f94
before queueing frame callbacks, and early return if that's the case.
147f94
147f94
The XDG-shell test needed to be updated for this: The mock compositor is
147f94
not responding to any frame callbacks, so the window will be unexposed,
147f94
no longer get paint events and therefore not trigger any commit. This
147f94
worked by accident before because we were issuing updates quickly enough
147f94
to reset the timer before it had a chance to unexpose the window. The
147f94
easiest fix is just to disable the dependency on frame callbacks in
147f94
this test, since that is clearly not what it's testing.
147f94
147f94
Task-number: QTBUG-81504
147f94
Change-Id: Ieacb05c7d5a5fcf662243d9177ebcc308cb9ca84
147f94
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
147f94
Reviewed-by: Georges Basile Stavracas Neto <gbsneto@gnome.org>
147f94
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
147f94
(cherry picked from commit cbc74ba6d7186457d8d07183272e952dee5f34f9)
147f94
---
147f94
 src/client/qwaylandwindow.cpp               | 4 ++++
147f94
 tests/auto/client/xdgshell/tst_xdgshell.cpp | 2 ++
147f94
 2 files changed, 6 insertions(+)
147f94
147f94
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
147f94
index bd70f4af..85307875 100644
147f94
--- a/src/client/qwaylandwindow.cpp
147f94
+++ b/src/client/qwaylandwindow.cpp
147f94
@@ -1170,6 +1170,10 @@ void QWaylandWindow::requestUpdate()
147f94
 void QWaylandWindow::handleUpdate()
147f94
 {
147f94
     qCDebug(lcWaylandBackingstore) << "handleUpdate" << QThread::currentThread();
147f94
+
147f94
+    if (mWaitingForFrameCallback)
147f94
+        return;
147f94
+
147f94
     // TODO: Should sync subsurfaces avoid requesting frame callbacks?
147f94
     QReadLocker lock(&mSurfaceLock);
147f94
     if (!mSurface)
147f94
diff --git a/tests/auto/client/xdgshell/tst_xdgshell.cpp b/tests/auto/client/xdgshell/tst_xdgshell.cpp
147f94
index 2fdd0a7c..e2593314 100644
147f94
--- a/tests/auto/client/xdgshell/tst_xdgshell.cpp
147f94
+++ b/tests/auto/client/xdgshell/tst_xdgshell.cpp
147f94
@@ -138,6 +138,7 @@ void tst_xdgshell::configureSize()
147f94
 
147f94
 void tst_xdgshell::configureStates()
147f94
 {
147f94
+    QVERIFY(qputenv("QT_WAYLAND_FRAME_CALLBACK_TIMEOUT", "0"));
147f94
     QRasterWindow window;
147f94
     window.resize(64, 48);
147f94
     window.show();
147f94
@@ -186,6 +187,7 @@ void tst_xdgshell::configureStates()
147f94
     QCOMPARE(window.windowStates(), Qt::WindowNoState);
147f94
     QCOMPARE(window.frameGeometry().size(), windowedSize);
147f94
 //    QCOMPARE(window.frameGeometry().topLeft(), QPoint()); // TODO: this doesn't currently work when window decorations are enabled
147f94
+    QVERIFY(qunsetenv("QT_WAYLAND_FRAME_CALLBACK_TIMEOUT"));
147f94
 }
147f94
 
147f94
 void tst_xdgshell::popup()
147f94
-- 
9fb289
2.35.1
147f94