diff options
| author | Even Oscar Andersen <even.oscar.andersen@qt.io> | 2025-05-23 12:37:25 +0200 |
|---|---|---|
| committer | Even Oscar Andersen <even.oscar.andersen@qt.io> | 2025-05-26 13:27:17 +0200 |
| commit | e48c19449e3856661f4fe2ccd30d94ba9d61301f (patch) | |
| tree | 91ca8efd1b4072dcdfc55c83eca67095a7b50de5 /src/plugins/platforms/wasm/qwasmwindowtreenode.cpp | |
| parent | 3ad9d5777fe0771d14e89bb5601d602f2451bd49 (diff) | |
wasm: Fix stacking order problem for transient parent windows
Windows with a transient parent does not reflect the relationship
in the stacking order. Essentially AboveTransientParent is missing
as a configuration choice.
What makes this slightly convoluted is that the window stack
does not depend on the window (for testability).
We solve this problem by making the stack and treenode templates,
and provide test class as arguments when testing.
QWasmWindow and QWasmScreen are not templated as before.
There is also a new order type StayAboveTransientParent. Which
means that we can no longer use order type to get to the
group location (Since StayAboveTransientParent can map to either
of the three types).
The window stack tests have been updated to handle the
StayAboveTransientParent type.
Finally, we do not do anything with a normal parent
child relationship as this should already work
correctly.
Fixes: QTBUG-131699
Change-Id: Ie08e18f9e0a2339175c4a09da0a831f031df71e1
Reviewed-by: Lorn Potter <lorn.potter@qt.io>
Diffstat (limited to 'src/plugins/platforms/wasm/qwasmwindowtreenode.cpp')
| -rw-r--r-- | src/plugins/platforms/wasm/qwasmwindowtreenode.cpp | 147 |
1 files changed, 1 insertions, 146 deletions
diff --git a/src/plugins/platforms/wasm/qwasmwindowtreenode.cpp b/src/plugins/platforms/wasm/qwasmwindowtreenode.cpp index 08eb7e327b1..6f068b82a39 100644 --- a/src/plugins/platforms/wasm/qwasmwindowtreenode.cpp +++ b/src/plugins/platforms/wasm/qwasmwindowtreenode.cpp @@ -3,149 +3,4 @@ #include "qwasmwindowtreenode.h" -#include "qwasmwindow.h" -#include "qwasmscreen.h" - -uint64_t QWasmWindowTreeNode::s_nextActiveIndex = 0; - -QWasmWindowTreeNode::QWasmWindowTreeNode() - : m_childStack(std::bind(&QWasmWindowTreeNode::onTopWindowChanged, this)) -{ -} - -QWasmWindowTreeNode::~QWasmWindowTreeNode() = default; - -void QWasmWindowTreeNode::shutdown() -{ - QWasmWindow *window = asWasmWindow(); - if (!window || - !window->window() || - (QGuiApplication::focusWindow() && // Don't act if we have a focus window different from this - QGuiApplication::focusWindow() != window->window())) - return; - - // Make a list of all windows sorted on active index. - // Skip windows with active index 0 as they have - // never been active. - std::map<uint64_t, QWasmWindow *> allWindows; - for (const auto &w : window->platformScreen()->allWindows()) { - if (w->getActiveIndex() > 0) - allWindows.insert({w->getActiveIndex(), w}); - } - - // window is not in all windows - if (window->getActiveIndex() > 0) - allWindows.insert({window->getActiveIndex(), window}); - - if (allWindows.size() >= 2) { - const auto lastIt = std::prev(allWindows.end()); - const auto prevIt = std::prev(lastIt); - const auto lastW = lastIt->second; - const auto prevW = prevIt->second; - - if (lastW == window) // Only act if window is last to be active - prevW->requestActivateWindow(); - } -} - -void QWasmWindowTreeNode::onParentChanged(QWasmWindowTreeNode *previousParent, - QWasmWindowTreeNode *currentParent, - QWasmWindowStack::PositionPreference positionPreference) -{ - auto *window = asWasmWindow(); - if (previousParent) { - previousParent->m_childStack.removeWindow(window); - previousParent->onSubtreeChanged(QWasmWindowTreeNodeChangeType::NodeRemoval, previousParent, - window); - } - - if (currentParent) { - currentParent->m_childStack.pushWindow(window, positionPreference); - currentParent->onSubtreeChanged(QWasmWindowTreeNodeChangeType::NodeInsertion, currentParent, - window); - } -} - -QWasmWindow *QWasmWindowTreeNode::asWasmWindow() -{ - return nullptr; -} - -void QWasmWindowTreeNode::onSubtreeChanged(QWasmWindowTreeNodeChangeType changeType, - QWasmWindowTreeNode *parent, QWasmWindow *child) -{ - if (changeType == QWasmWindowTreeNodeChangeType::NodeInsertion && parent == this - && m_childStack.topWindow() - && m_childStack.topWindow()->window()) { - - const auto flags = m_childStack.topWindow()->window()->flags(); - const bool notToolOrPopup = ((flags & Qt::ToolTip) != Qt::ToolTip) && ((flags & Qt::Popup) != Qt::Popup); - const QVariant showWithoutActivating = m_childStack.topWindow()->window()->property("_q_showWithoutActivating"); - if (!showWithoutActivating.isValid() || !showWithoutActivating.toBool()) { - if (notToolOrPopup) - m_childStack.topWindow()->requestActivateWindow(); - } - } - - if (parentNode()) - parentNode()->onSubtreeChanged(changeType, parent, child); -} - -void QWasmWindowTreeNode::setWindowZOrder(QWasmWindow *window, int z) -{ - window->setZOrder(z); -} - -void QWasmWindowTreeNode::onPositionPreferenceChanged( - QWasmWindowStack::PositionPreference positionPreference) -{ - if (parentNode()) { - parentNode()->m_childStack.windowPositionPreferenceChanged(asWasmWindow(), - positionPreference); - } -} - -void QWasmWindowTreeNode::setAsActiveNode() -{ - if (parentNode()) - parentNode()->setActiveChildNode(asWasmWindow()); - - // At the end, this is a recursive function - m_activeIndex = ++s_nextActiveIndex; -} - -void QWasmWindowTreeNode::bringToTop() -{ - if (!parentNode()) - return; - parentNode()->m_childStack.raise(asWasmWindow()); - parentNode()->bringToTop(); -} - -void QWasmWindowTreeNode::sendToBottom() -{ - if (!parentNode()) - return; - m_childStack.lower(asWasmWindow()); -} - -void QWasmWindowTreeNode::onTopWindowChanged() -{ - constexpr int zOrderForElementInFrontOfScreen = 3; - int z = zOrderForElementInFrontOfScreen; - std::for_each(m_childStack.rbegin(), m_childStack.rend(), - [this, &z](QWasmWindow *window) { setWindowZOrder(window, z++); }); -} - -void QWasmWindowTreeNode::setActiveChildNode(QWasmWindow *activeChild) -{ - m_activeChild = activeChild; - - auto it = m_childStack.begin(); - if (it == m_childStack.end()) - return; - for (; it != m_childStack.end(); ++it) - (*it)->onActivationChanged(*it == m_activeChild); - - setAsActiveNode(); -} +uint64_t QWasmWindowTreeNodeBase::s_nextActiveIndex = 0; |
