summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/wasm/qwasmwindowstack.cpp
diff options
context:
space:
mode:
authorMikolaj Boc <mikolaj.boc@qt.io>2022-07-25 10:43:07 +0200
committerMikołaj Boc <Mikolaj.Boc@qt.io>2022-08-16 16:08:38 +0000
commit1007964f2d571d5a864015846025bb35c6d79ec2 (patch)
tree4fb525ad4e4305e6282b47bec511e6696a6401c4 /src/plugins/platforms/wasm/qwasmwindowstack.cpp
parent878328c6ab0367b7e7c1762d7f495b2c00c32496 (diff)
Maintain the window z-order properly in wasm compositor
The old stack structure used to keep track of windows has been improved to conform to the actual windowing assumptions: there shall be one root window, which is always at the bottom. The first created window immediately becomes the root window. Should the root window be removed, all windows are non-root, i.e. any of them can become the top-level window Fixes: QTBUG-105094 Pick-to: 6.4 Change-Id: Ic553244fa9f5bc3ee590b702935e66cfc62d5f8f Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
Diffstat (limited to 'src/plugins/platforms/wasm/qwasmwindowstack.cpp')
-rw-r--r--src/plugins/platforms/wasm/qwasmwindowstack.cpp123
1 files changed, 123 insertions, 0 deletions
diff --git a/src/plugins/platforms/wasm/qwasmwindowstack.cpp b/src/plugins/platforms/wasm/qwasmwindowstack.cpp
new file mode 100644
index 00000000000..9ce6689c8d3
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmwindowstack.cpp
@@ -0,0 +1,123 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include "qwasmwindowstack.h"
+
+QT_BEGIN_NAMESPACE
+
+QWasmWasmWindowStack::QWasmWasmWindowStack(TopWindowChangedCallbackType topWindowChangedCallback)
+ : m_topWindowChangedCallback(std::move(topWindowChangedCallback))
+{
+}
+
+QWasmWasmWindowStack::~QWasmWasmWindowStack() = default;
+
+void QWasmWasmWindowStack::pushWindow(QWasmWindow *window)
+{
+ Q_ASSERT(m_windowStack.count(window) == 0);
+
+ m_windowStack.push_back(window);
+
+ m_topWindowChangedCallback(window);
+}
+
+void QWasmWasmWindowStack::removeWindow(QWasmWindow *window)
+{
+ Q_ASSERT(m_windowStack.count(window) == 1);
+
+ auto it = std::find(m_windowStack.begin(), m_windowStack.end(), window);
+ const bool removingBottom = m_windowStack.begin() == it;
+ const bool removingTop = m_windowStack.end() - 1 == it;
+ if (removingBottom)
+ m_firstWindowTreatment = FirstWindowTreatment::Regular;
+
+ m_windowStack.erase(it);
+
+ if (removingTop)
+ m_topWindowChangedCallback(topWindow());
+}
+
+void QWasmWasmWindowStack::raise(QWasmWindow *window)
+{
+ Q_ASSERT(m_windowStack.count(window) == 1);
+
+ if (window == rootWindow() || window == topWindow())
+ return;
+
+ auto it = std::find(regularWindowsBegin(), m_windowStack.end(), window);
+ std::rotate(it, it + 1, m_windowStack.end());
+ m_topWindowChangedCallback(topWindow());
+}
+
+void QWasmWasmWindowStack::lower(QWasmWindow *window)
+{
+ Q_ASSERT(m_windowStack.count(window) == 1);
+
+ if (window == rootWindow())
+ return;
+
+ const bool loweringTopWindow = topWindow() == window;
+ auto it = std::find(regularWindowsBegin(), m_windowStack.end(), window);
+ std::rotate(regularWindowsBegin(), it, it + 1);
+ if (loweringTopWindow && topWindow() != window)
+ m_topWindowChangedCallback(topWindow());
+}
+
+QWasmWasmWindowStack::iterator QWasmWasmWindowStack::begin()
+{
+ return m_windowStack.rbegin();
+}
+
+QWasmWasmWindowStack::iterator QWasmWasmWindowStack::end()
+{
+ return m_windowStack.rend();
+}
+
+QWasmWasmWindowStack::const_iterator QWasmWasmWindowStack::begin() const
+{
+ return m_windowStack.rbegin();
+}
+
+QWasmWasmWindowStack::const_iterator QWasmWasmWindowStack::end() const
+{
+ return m_windowStack.rend();
+}
+
+QWasmWasmWindowStack::const_reverse_iterator QWasmWasmWindowStack::rbegin() const
+{
+ return m_windowStack.begin();
+}
+
+QWasmWasmWindowStack::const_reverse_iterator QWasmWasmWindowStack::rend() const
+{
+ return m_windowStack.end();
+}
+
+bool QWasmWasmWindowStack::empty() const
+{
+ return m_windowStack.empty();
+}
+
+size_t QWasmWasmWindowStack::size() const
+{
+ return m_windowStack.size();
+}
+
+QWasmWindow *QWasmWasmWindowStack::rootWindow() const
+{
+ return m_firstWindowTreatment == FirstWindowTreatment::AlwaysAtBottom ? m_windowStack.first()
+ : nullptr;
+}
+
+QWasmWindow *QWasmWasmWindowStack::topWindow() const
+{
+ return m_windowStack.last();
+}
+
+QWasmWasmWindowStack::StorageType::iterator QWasmWasmWindowStack::regularWindowsBegin()
+{
+ return m_windowStack.begin()
+ + (m_firstWindowTreatment == FirstWindowTreatment::AlwaysAtBottom ? 1 : 0);
+}
+
+QT_END_NAMESPACE