From 76f8559ca67001fcf05295f1c68d45d5bd2bfa30 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Mon, 20 May 2024 16:12:09 +0300 Subject: [PATCH] Client: Try harder to guess the transient parent window xdg_popup requires a parent surface. On the other hand, Qt is quite permissive, it allows showing a popup window without specifying the transient parent window. Things have been slowly changing and more controls specify the transient parent, but there are still apps that don't do it. For that particular reason, QWaylandWindow has some heuristics to guess the transient parent. Currently, that heuristic works as follows: - If QWindow::transientParent() is set, use that - otherwise use the focus window However, this heuristic doesn't consider that a window can be inactive. For example, user hovers an element in the window while the window has no focus. This change proposes a heuristic that considers the last interacted input device, i.e. - if QWindow::transientParent() is specified, prefer that - if there's a "top" popup, use it - otherwise check the last interacted window With the proposed heuristic, tooltips are less likely to be backed by xdg-toplevel in inactive apps. Pick-to: 6.7 Change-Id: I7e6a607dc38f9e8adce316d3540a9bd9c37cfed4 Reviewed-by: David Edmundson --- src/plugins/platforms/wayland/qwaylandwindow.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index 73fb331ebb1..237676921ec 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -1185,8 +1185,13 @@ QWaylandWindow *QWaylandWindow::guessTransientParent() const if (auto transientParent = closestShellSurfaceWindow(window()->transientParent())) return transientParent; - if (QGuiApplication::focusWindow() && (window()->type() == Qt::ToolTip || window()->type() == Qt::Popup)) - return closestShellSurfaceWindow(QGuiApplication::focusWindow()); + if (window()->type() == Qt::Popup) { + if (mTopPopup) + return mTopPopup; + } + + if (window()->type() == Qt::ToolTip || window()->type() == Qt::Popup) + return display()->lastInputWindow(); return nullptr; }