diff options
author | Paul Olav Tvete <paul.tvete@qt.io> | 2024-04-11 15:03:42 +0200 |
---|---|---|
committer | Paul Olav Tvete <paul.tvete@qt.io> | 2024-04-12 13:19:47 +0000 |
commit | f6c4b2f0691ea0240566c068cf36ed95003153e1 (patch) | |
tree | beee29015a726f10f61bd973ca2ff590b3794a10 /src | |
parent | 0417a5f34a327be44a50b5164266b9f607776461 (diff) |
ShellSurfaceItem: Make sure modal dialogs stay on top
Use the new modal property from ShellSurface, and treat modal dialogs
as StaysOnTop.
[ChangeLog][QtWaylandCompositor] ShellSurfaceItem will keep modal
dialogs on top of other surfaces when using XdgShell.
Fixes: QTBUG-118813
Change-Id: Iaa0ca411dc4fec740e0fbe1db523b16b028c4c29
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp index cd0ac84f8..7eb1479f5 100644 --- a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp +++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp @@ -102,6 +102,9 @@ void QWaylandQuickShellSurfaceItem::setShellSurface(QWaylandShellSurface *shellS if (d->m_shellSurface == shellSurface) return; + if (Q_UNLIKELY(d->m_shellSurface)) + disconnect(d->m_shellSurface, &QWaylandShellSurface::modalChanged, this, nullptr); + d->m_shellSurface = shellSurface; if (d->m_shellIntegration) { @@ -115,6 +118,9 @@ void QWaylandQuickShellSurfaceItem::setShellSurface(QWaylandShellSurface *shellS installEventFilter(d->m_shellIntegration); } + connect(shellSurface, &QWaylandShellSurface::modalChanged, this, + [d](){ if (d->m_shellSurface->modal()) d->raise(); }); + emit shellSurfaceChanged(); } @@ -299,11 +305,22 @@ static QWaylandQuickShellSurfaceItem *findSurfaceItemFromMoveItem(QQuickItem *mo return nullptr; } +static inline bool onTop(QWaylandQuickShellSurfaceItem *surf) +{ + return surf->staysOnTop() || surf->shellSurface()->modal(); +} + +static inline bool onBottom(QWaylandQuickShellSurfaceItem *surf) +{ + return surf->staysOnBottom() && !surf->shellSurface()->modal(); +} + /* To raise a surface, find the topmost suitable surface and place above that. We start from the top and: If we don't have staysOnTop, skip all surfaces with staysOnTop If we have staysOnBottom, skip all surfaces that don't have staysOnBottom + A modal dialog is handled as if it had staysOnTop */ void QWaylandQuickShellSurfaceItemPrivate::raise() { @@ -312,10 +329,13 @@ void QWaylandQuickShellSurfaceItemPrivate::raise() QQuickItem *parent = moveItem->parentItem(); if (!parent) return; + const bool putOnTop = staysOnTop || m_shellSurface->modal(); + const bool putOnBottom = staysOnBottom && !m_shellSurface->modal(); + auto it = parent->childItems().crbegin(); - auto skip = [this](QQuickItem *item) { + auto skip = [=](QQuickItem *item) { if (auto *surf = findSurfaceItemFromMoveItem(item)) - return (!staysOnTop && surf->staysOnTop()) || (staysOnBottom && !surf->staysOnBottom()); + return (!putOnTop && onTop(surf)) || (putOnBottom && !onBottom(surf)); return true; // ignore any other Quick items that may be there }; auto end = parent->childItems().crend(); @@ -333,6 +353,7 @@ void QWaylandQuickShellSurfaceItemPrivate::raise() We start from the bottom and: If we don't have staysOnBottom, skip all surfaces with staysOnBottom If we have staysOnTop, skip all surfaces that don't have staysOnTop + A modal dialog is handled as if it had staysOnTop */ void QWaylandQuickShellSurfaceItemPrivate::lower() { @@ -341,11 +362,13 @@ void QWaylandQuickShellSurfaceItemPrivate::lower() QQuickItem *parent = moveItem->parentItem(); if (!parent) return; - auto it = parent->childItems().cbegin(); + const bool putOnTop = staysOnTop || m_shellSurface->modal(); + const bool putOnBottom = staysOnBottom && !m_shellSurface->modal(); - auto skip = [this](QQuickItem *item) { + auto it = parent->childItems().cbegin(); + auto skip = [=](QQuickItem *item) { if (auto *surf = findSurfaceItemFromMoveItem(item)) - return (!staysOnBottom && surf->staysOnBottom()) || (staysOnTop && !surf->staysOnTop()); + return (!putOnBottom && onBottom(surf)) || (putOnTop && !onTop(surf)); return true; // ignore any other Quick items that may be there }; while (skip(*it)) |