summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
authorSérgio Martins <sergio.martins@kdab.com>2022-07-29 17:13:24 +0100
committerSergio Martins <sergio.martins@kdab.com>2022-08-04 02:55:27 +0100
commit9ccbbeecbd76ba7dbc73737528ea613c8b21bd98 (patch)
tree14b31dacc5b39132ee8c15a96ca5e92ba08064f0 /src/opengl
parent40d781b7b5e7925e4559cd725ddbfef307d5f455 (diff)
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 Pick-to: 6.3 6.4 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Diffstat (limited to 'src/opengl')
-rw-r--r--src/opengl/qopenglcompositor.cpp54
-rw-r--r--src/opengl/qopenglcompositor_p.h1
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;