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

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