diff options
Diffstat (limited to 'src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp')
-rw-r--r-- | src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp | 55 |
1 files changed, 40 insertions, 15 deletions
diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp index 28806f622..7eb1479f5 100644 --- a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp +++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp @@ -18,9 +18,8 @@ QWaylandQuickShellSurfaceItem *QWaylandQuickShellSurfaceItemPrivate::maybeCreate auto *popupItem = new QWaylandQuickShellSurfaceItem(q); popupItem->setShellSurface(shellSurface); popupItem->setAutoCreatePopupItems(true); - QObject::connect(popupItem, &QWaylandQuickShellSurfaceItem::surfaceDestroyed, [popupItem](){ - popupItem->deleteLater(); - }); + QObject::connect(popupItem, &QWaylandQuickShellSurfaceItem::surfaceDestroyed, + popupItem, &QObject::deleteLater); return popupItem; } @@ -77,7 +76,7 @@ QWaylandQuickShellSurfaceItem::QWaylandQuickShellSurfaceItem(QWaylandQuickShellS } /*! - * \qmlproperty ShellSurface QtWaylandCompositor::ShellSurfaceItem::shellSurface + * \qmlproperty ShellSurface QtWayland.Compositor::ShellSurfaceItem::shellSurface * * This property holds the ShellSurface rendered by this ShellSurfaceItem. * It may either be an XdgSurfaceV5, WlShellSurface or IviSurface depending on which shell protocol @@ -103,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) { @@ -116,11 +118,14 @@ void QWaylandQuickShellSurfaceItem::setShellSurface(QWaylandShellSurface *shellS installEventFilter(d->m_shellIntegration); } + connect(shellSurface, &QWaylandShellSurface::modalChanged, this, + [d](){ if (d->m_shellSurface->modal()) d->raise(); }); + emit shellSurfaceChanged(); } /*! - * \qmlproperty Item QtWaylandCompositor::ShellSurfaceItem::moveItem + * \qmlproperty Item QtWayland.Compositor::ShellSurfaceItem::moveItem * * This property holds the move item for this ShellSurfaceItem. This is the item that will be moved * when the clients request the ShellSurface to be moved, maximized, resized etc. This property is @@ -151,7 +156,7 @@ void QWaylandQuickShellSurfaceItem::setMoveItem(QQuickItem *moveItem) } /*! - * \qmlproperty bool QtWaylandCompositor::ShellSurfaceItem::autoCreatePopupItems + * \qmlproperty bool QtWayland.Compositor::ShellSurfaceItem::autoCreatePopupItems * * This property holds whether ShellSurfaceItems for popups parented to the shell * surface managed by this item should automatically be created. @@ -300,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() { @@ -313,17 +329,23 @@ 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 }; - while (skip(*it)) + auto end = parent->childItems().crend(); + while (it != end && skip(*it)) ++it; - QQuickItem *top = *it; - if (moveItem != top) - moveItem->stackAfter(top); + if (it != end) { + QQuickItem *top = *it; + if (moveItem != top) + moveItem->stackAfter(top); + } } /* @@ -331,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() { @@ -339,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)) |