diff options
author | Sérgio Martins <sergio.martins@kdab.com> | 2022-07-29 17:13:24 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2022-08-05 10:31:59 +0000 |
commit | 7d92a8009defa108a5da11131fed4d2ae1d6c152 (patch) | |
tree | acd3ea22dc51c4b1b9bd1176661343e6a7d65c85 /src/opengl | |
parent | ad2a55f8df66c191d750366c5dc8d8eab0c7d506 (diff) | |
download | qtbase-7d92a8009defa108a5da11131fed4d2ae1d6c152.tar.gz |
eglfs: Ensure correct z-order of windows
- The main window needs to be at the back always, since it's fullscreen. If the root
window gets in front then there's no way to retrieve the secondary windows.
- Qt::Tool and transient child windows go to front as in other QPAs
Change-Id: I4a2793628250756bc07daaee0763ea7174a7bebd
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
(cherry picked from commit 9ccbbeecbd76ba7dbc73737528ea613c8b21bd98)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/opengl')
-rw-r--r-- | src/opengl/qopenglcompositor.cpp | 54 | ||||
-rw-r--r-- | src/opengl/qopenglcompositor_p.h | 1 |
2 files changed, 52 insertions, 3 deletions
diff --git a/src/opengl/qopenglcompositor.cpp b/src/opengl/qopenglcompositor.cpp index ae500181e4..2c2facd4b9 100644 --- a/src/opengl/qopenglcompositor.cpp +++ b/src/opengl/qopenglcompositor.cpp @@ -246,7 +246,9 @@ void QOpenGLCompositor::addWindow(QOpenGLCompositorWindow *window) { if (!m_windows.contains(window)) { m_windows.append(window); - emit topWindowChanged(window); + ensureCorrectZOrder(); + if (window == m_windows.constLast()) + emit topWindowChanged(window); } } @@ -259,9 +261,17 @@ void QOpenGLCompositor::removeWindow(QOpenGLCompositorWindow *window) void QOpenGLCompositor::moveToTop(QOpenGLCompositorWindow *window) { + if (!m_windows.isEmpty() && window == m_windows.constLast()) { + // Already on top + return; + } + m_windows.removeOne(window); m_windows.append(window); - emit topWindowChanged(window); + ensureCorrectZOrder(); + + if (window == m_windows.constLast()) + emit topWindowChanged(window); } void QOpenGLCompositor::changeWindowIndex(QOpenGLCompositorWindow *window, int newIdx) @@ -269,11 +279,49 @@ void QOpenGLCompositor::changeWindowIndex(QOpenGLCompositorWindow *window, int n int idx = m_windows.indexOf(window); if (idx != -1 && idx != newIdx) { m_windows.move(idx, newIdx); - if (newIdx == m_windows.size() - 1) + ensureCorrectZOrder(); + if (window == m_windows.constLast()) emit topWindowChanged(m_windows.last()); } } +void QOpenGLCompositor::ensureCorrectZOrder() +{ + const auto originalOrder = m_windows; + + std::sort(m_windows.begin(), m_windows.end(), + [this, &originalOrder](QOpenGLCompositorWindow *cw1, QOpenGLCompositorWindow *cw2) { + QWindow *w1 = cw1->sourceWindow(); + QWindow *w2 = cw2->sourceWindow(); + + // Case #1: The main window needs to have less z-order. It can never be in + // front of our tool windows, popups etc, because it's fullscreen! + if (w1 == m_targetWindow || w2 == m_targetWindow) + return w1 == m_targetWindow; + + // Case #2: + if (w2->isAncestorOf(w1)) { + // w1 is transient child of w2. W1 goes in front then. + return false; + } + + if (w1->isAncestorOf(w2)) { + // Or the other way around + return true; + } + + // Case #3: One of the window is a Tool, that goes to front, as done in other QPAs + const bool isTool1 = (w1->flags() & Qt::Tool) == Qt::Tool; + const bool isTool2 = (w2->flags() & Qt::Tool) == Qt::Tool; + if (isTool1 != isTool2) { + return !isTool1; + } + + // Case #4: Just preserve original sorting: + return originalOrder.indexOf(cw1) < originalOrder.indexOf(cw2); + }); +} + QT_END_NAMESPACE #include "moc_qopenglcompositor_p.cpp" diff --git a/src/opengl/qopenglcompositor_p.h b/src/opengl/qopenglcompositor_p.h index 6ab738c58e..abe8d4959e 100644 --- a/src/opengl/qopenglcompositor_p.h +++ b/src/opengl/qopenglcompositor_p.h @@ -74,6 +74,7 @@ private: void renderAll(QOpenGLFramebufferObject *fbo); void render(QOpenGLCompositorWindow *window); + void ensureCorrectZOrder(); QOpenGLContext *m_context; QWindow *m_targetWindow; |