diff options
author | David Redondo <[email protected]> | 2024-10-30 16:57:55 +0100 |
---|---|---|
committer | David Redondo <[email protected]> | 2024-11-13 08:41:58 +0100 |
commit | 2753bf6b6b1ed4c0b51bb257559f44d60a3a9497 (patch) | |
tree | 33b3323c7b498fcbd69dce14858a98272530a9f7 | |
parent | 9aa5f633d4ec77c7f5ecea2254bcf398ef02bfb9 (diff) |
Adapt window recreation to wl_surface as winId and lifetime changes
Returning wl_surface as winId broke widget windows after reconnect.
When fetching globals from the new connection new screens are added,
this results in QWidget being notified of a screen change. It then
refreshes its cached winId which at this point in time will be 0
since the window does not have a new window yet. Then when a widget
repainting the backing store will never be flushed because it doesnt
find a native parent anymore by going up the parent chain and looking
for a widget with non-null winId.
Fix this by recreating the wl_surface after fetching the globals
but before the initital roundtrip.
While at it dont recreate role objects for windows that dont need
them. With the changes that also now hidden windows have wl_surfaces
we would recreate them along with closed popups.
Change-Id: Ib7ed27d1f25df84c85cce4802726178586c19d55
Reviewed-by: David Edmundson <[email protected]>
-rw-r--r-- | src/plugins/platforms/wayland/qwaylanddisplay.cpp | 27 | ||||
-rw-r--r-- | src/plugins/platforms/wayland/qwaylandwindow.cpp | 1 | ||||
-rw-r--r-- | src/plugins/platforms/wayland/qwaylandwindow_p.h | 2 |
3 files changed, 21 insertions, 9 deletions
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp index dfdf88c0b4a..d585c194bd6 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp @@ -455,18 +455,21 @@ void QWaylandDisplay::reconnect() mActiveWindows.clear(); const auto windows = QGuiApplication::allWindows(); + QList<QWaylandWindow *> allPlatformWindows; for (auto window : windows) { - if (auto waylandWindow = static_cast<QWaylandWindow *>(window->handle())) + if (auto waylandWindow = static_cast<QWaylandWindow *>(window->handle())) { waylandWindow->closeChildPopups(); + allPlatformWindows.push_back(waylandWindow); + } } + // Remove windows that do not need to be recreated and now closed popups QList<QWaylandWindow *> recreateWindows; - for (auto window : std::as_const(windows)) { - auto waylandWindow = static_cast<QWaylandWindow*>(window->handle()); - if (waylandWindow && waylandWindow->wlSurface()) { - waylandWindow->reset(); - recreateWindows.push_back(waylandWindow); + for (auto window : std::as_const(allPlatformWindows)) { + if (window->subSurfaceWindow() || window->shellSurface()) { + recreateWindows.push_back(window); } + window->reset(); } if (mSyncCallback) { @@ -480,6 +483,15 @@ void QWaylandDisplay::reconnect() if (!mDisplay) _exit(1); + connect( + this, &QWaylandDisplay::connected, this, + [&allPlatformWindows] { + for (auto &window : std::as_const(allPlatformWindows)) { + window->initializeWlSurface(); + } + }, + Qt::SingleShotConnection); + setupConnection(); initialize(); @@ -488,7 +500,8 @@ void QWaylandDisplay::reconnect() initEventThread(); auto needsRecreate = [](QPlatformWindow *window) { - return window && !static_cast<QWaylandWindow *>(window)->wlSurface(); + auto waylandWindow = static_cast<QWaylandWindow *>(window); + return waylandWindow && !waylandWindow->subSurfaceWindow() && !waylandWindow->shellSurface(); }; auto window = recreateWindows.begin(); while (!recreateWindows.isEmpty()) { diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index cb6c07f9799..6d4f11e8d83 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -1803,7 +1803,6 @@ void QWaylandWindow::closeChildPopups() { void QWaylandWindow::reinit() { - initializeWlSurface(); if (window()->isVisible()) { initWindow(); if (hasPendingUpdateRequest()) diff --git a/src/plugins/platforms/wayland/qwaylandwindow_p.h b/src/plugins/platforms/wayland/qwaylandwindow_p.h index e4ce2af700f..592125c6839 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow_p.h +++ b/src/plugins/platforms/wayland/qwaylandwindow_p.h @@ -239,6 +239,7 @@ public: virtual void reinit(); void reset(); + void initializeWlSurface(); bool windowEvent(QEvent *event) override; @@ -340,7 +341,6 @@ protected: private: void setGeometry_helper(const QRect &rect); void initWindow(); - void initializeWlSurface(); bool shouldCreateShellSurface() const; bool shouldCreateSubSurface() const; void resetSurfaceRole(); |