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 <davidedmundson@kde.org>
This commit is contained in:
Vlad Zahorodnii 2024-05-20 16:12:09 +03:00
parent 4611355d69
commit 76f8559ca6

View File

@ -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;
}