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

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