diff options
Diffstat (limited to 'src/plugins/platforms/wasm/qwasmwindowstack.cpp')
-rw-r--r-- | src/plugins/platforms/wasm/qwasmwindowstack.cpp | 178 |
1 files changed, 129 insertions, 49 deletions
diff --git a/src/plugins/platforms/wasm/qwasmwindowstack.cpp b/src/plugins/platforms/wasm/qwasmwindowstack.cpp index 9ce6689c8d..d3769c7a1b 100644 --- a/src/plugins/platforms/wasm/qwasmwindowstack.cpp +++ b/src/plugins/platforms/wasm/qwasmwindowstack.cpp @@ -5,119 +5,199 @@ QT_BEGIN_NAMESPACE -QWasmWasmWindowStack::QWasmWasmWindowStack(TopWindowChangedCallbackType topWindowChangedCallback) - : m_topWindowChangedCallback(std::move(topWindowChangedCallback)) +QWasmWindowStack::QWasmWindowStack(WindowOrderChangedCallbackType windowOrderChangedCallback) + : m_windowOrderChangedCallback(std::move(windowOrderChangedCallback)), + m_regularWindowsBegin(m_windowStack.begin()), + m_alwaysOnTopWindowsBegin(m_windowStack.begin()) { } -QWasmWasmWindowStack::~QWasmWasmWindowStack() = default; +QWasmWindowStack::~QWasmWindowStack() = default; -void QWasmWasmWindowStack::pushWindow(QWasmWindow *window) +void QWasmWindowStack::pushWindow(QWasmWindow *window, PositionPreference position) { Q_ASSERT(m_windowStack.count(window) == 0); - m_windowStack.push_back(window); - - m_topWindowChangedCallback(window); -} - -void QWasmWasmWindowStack::removeWindow(QWasmWindow *window) + if (position == PositionPreference::StayOnTop) { + const auto stayOnTopDistance = + std::distance(m_windowStack.begin(), m_alwaysOnTopWindowsBegin); + const auto regularDistance = std::distance(m_windowStack.begin(), m_regularWindowsBegin); + m_windowStack.push_back(window); + m_alwaysOnTopWindowsBegin = m_windowStack.begin() + stayOnTopDistance; + m_regularWindowsBegin = m_windowStack.begin() + regularDistance; + } else if (position == PositionPreference::Regular) { + const auto regularDistance = std::distance(m_windowStack.begin(), m_regularWindowsBegin); + m_alwaysOnTopWindowsBegin = m_windowStack.insert(m_alwaysOnTopWindowsBegin, window) + 1; + m_regularWindowsBegin = m_windowStack.begin() + regularDistance; + } else { + const auto stayOnTopDistance = + std::distance(m_windowStack.begin(), m_alwaysOnTopWindowsBegin); + m_regularWindowsBegin = m_windowStack.insert(m_regularWindowsBegin, window) + 1; + m_alwaysOnTopWindowsBegin = m_windowStack.begin() + stayOnTopDistance + 1; + } + + m_windowOrderChangedCallback(); +} + +void QWasmWindowStack::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; + const auto position = getWindowPositionPreference(it); + const auto stayOnTopDistance = std::distance(m_windowStack.begin(), m_alwaysOnTopWindowsBegin); + const auto regularDistance = std::distance(m_windowStack.begin(), m_regularWindowsBegin); m_windowStack.erase(it); - if (removingTop) - m_topWindowChangedCallback(topWindow()); + m_alwaysOnTopWindowsBegin = m_windowStack.begin() + stayOnTopDistance + - (position != PositionPreference::StayOnTop ? 1 : 0); + m_regularWindowsBegin = m_windowStack.begin() + regularDistance + - (position == PositionPreference::StayOnBottom ? 1 : 0); + + m_windowOrderChangedCallback(); } -void QWasmWasmWindowStack::raise(QWasmWindow *window) +void QWasmWindowStack::raise(QWasmWindow *window) { Q_ASSERT(m_windowStack.count(window) == 1); - if (window == rootWindow() || window == topWindow()) + if (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) + auto it = std::find(m_windowStack.begin(), m_windowStack.end(), window); + auto itEnd = ([this, position = getWindowPositionPreference(it)]() { + switch (position) { + case PositionPreference::StayOnTop: + return m_windowStack.end(); + case PositionPreference::Regular: + return m_alwaysOnTopWindowsBegin; + case PositionPreference::StayOnBottom: + return m_regularWindowsBegin; + } + })(); + std::rotate(it, it + 1, itEnd); + m_windowOrderChangedCallback(); +} + +void QWasmWindowStack::lower(QWasmWindow *window) { Q_ASSERT(m_windowStack.count(window) == 1); - if (window == rootWindow()) + if (window == *m_windowStack.begin()) 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()); + auto it = std::find(m_windowStack.begin(), m_windowStack.end(), window); + auto itBegin = ([this, position = getWindowPositionPreference(it)]() { + switch (position) { + case PositionPreference::StayOnTop: + return m_alwaysOnTopWindowsBegin; + case PositionPreference::Regular: + return m_regularWindowsBegin; + case PositionPreference::StayOnBottom: + return m_windowStack.begin(); + } + })(); + + std::rotate(itBegin, it, it + 1); + m_windowOrderChangedCallback(); } -QWasmWasmWindowStack::iterator QWasmWasmWindowStack::begin() +void QWasmWindowStack::windowPositionPreferenceChanged(QWasmWindow *window, + PositionPreference position) +{ + auto it = std::find(m_windowStack.begin(), m_windowStack.end(), window); + const auto currentPosition = getWindowPositionPreference(it); + + const auto zones = static_cast<int>(position) - static_cast<int>(currentPosition); + Q_ASSERT(zones != 0); + + if (zones < 0) { + // Perform right rotation so that the window lands on top of regular windows + const auto begin = std::make_reverse_iterator(it + 1); + const auto end = position == PositionPreference::Regular + ? std::make_reverse_iterator(m_alwaysOnTopWindowsBegin) + : std::make_reverse_iterator(m_regularWindowsBegin); + std::rotate(begin, begin + 1, end); + if (zones == -2) { + ++m_alwaysOnTopWindowsBegin; + ++m_regularWindowsBegin; + } else if (position == PositionPreference::Regular) { + ++m_alwaysOnTopWindowsBegin; + } else { + ++m_regularWindowsBegin; + } + } else { + // Perform left rotation so that the window lands at the bottom of always on top windows + const auto begin = it; + const auto end = position == PositionPreference::Regular ? m_regularWindowsBegin + : m_alwaysOnTopWindowsBegin; + std::rotate(begin, begin + 1, end); + if (zones == 2) { + --m_alwaysOnTopWindowsBegin; + --m_regularWindowsBegin; + } else if (position == PositionPreference::Regular) { + --m_regularWindowsBegin; + } else { + --m_alwaysOnTopWindowsBegin; + } + } + m_windowOrderChangedCallback(); +} + +QWasmWindowStack::iterator QWasmWindowStack::begin() { return m_windowStack.rbegin(); } -QWasmWasmWindowStack::iterator QWasmWasmWindowStack::end() +QWasmWindowStack::iterator QWasmWindowStack::end() { return m_windowStack.rend(); } -QWasmWasmWindowStack::const_iterator QWasmWasmWindowStack::begin() const +QWasmWindowStack::const_iterator QWasmWindowStack::begin() const { return m_windowStack.rbegin(); } -QWasmWasmWindowStack::const_iterator QWasmWasmWindowStack::end() const +QWasmWindowStack::const_iterator QWasmWindowStack::end() const { return m_windowStack.rend(); } -QWasmWasmWindowStack::const_reverse_iterator QWasmWasmWindowStack::rbegin() const +QWasmWindowStack::const_reverse_iterator QWasmWindowStack::rbegin() const { return m_windowStack.begin(); } -QWasmWasmWindowStack::const_reverse_iterator QWasmWasmWindowStack::rend() const +QWasmWindowStack::const_reverse_iterator QWasmWindowStack::rend() const { return m_windowStack.end(); } -bool QWasmWasmWindowStack::empty() const +bool QWasmWindowStack::empty() const { return m_windowStack.empty(); } -size_t QWasmWasmWindowStack::size() const +size_t QWasmWindowStack::size() const { return m_windowStack.size(); } -QWasmWindow *QWasmWasmWindowStack::rootWindow() const -{ - return m_firstWindowTreatment == FirstWindowTreatment::AlwaysAtBottom ? m_windowStack.first() - : nullptr; -} - -QWasmWindow *QWasmWasmWindowStack::topWindow() const +QWasmWindow *QWasmWindowStack::topWindow() const { - return m_windowStack.last(); + return m_windowStack.empty() ? nullptr : m_windowStack.last(); } -QWasmWasmWindowStack::StorageType::iterator QWasmWasmWindowStack::regularWindowsBegin() +QWasmWindowStack::PositionPreference +QWasmWindowStack::getWindowPositionPreference(StorageType::iterator windowIt) const { - return m_windowStack.begin() - + (m_firstWindowTreatment == FirstWindowTreatment::AlwaysAtBottom ? 1 : 0); + if (windowIt >= m_alwaysOnTopWindowsBegin) + return PositionPreference::StayOnTop; + if (windowIt >= m_regularWindowsBegin) + return PositionPreference::Regular; + return PositionPreference::StayOnBottom; } QT_END_NAMESPACE |