From bca341c70b85cc23494933327e31cdf993ca7f85 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Wed, 21 Aug 2024 12:22:24 +0300 Subject: [PATCH] Introduce Workspace::stackAbove() The main purpose is to simplify X11 Above stack mode implementation. --- src/focuschain.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ src/focuschain.h | 9 +++++++++ src/layers.cpp | 19 +++++++++++++++++++ src/workspace.h | 1 + 4 files changed, 71 insertions(+) diff --git a/src/focuschain.cpp b/src/focuschain.cpp index 57d5e240d5..048a40d13c 100644 --- a/src/focuschain.cpp +++ b/src/focuschain.cpp @@ -151,6 +151,26 @@ void FocusChain::moveAfterWindow(Window *window, Window *reference) moveAfterWindowInChain(window, reference, m_mostRecentlyUsed); } +void FocusChain::moveBeforeWindow(Window *window, Window *reference) +{ + if (window->isDeleted()) { + return; + } + if (!window->wantsTabFocus()) { + return; + } + + for (auto it = m_desktopFocusChains.begin(); + it != m_desktopFocusChains.end(); + ++it) { + if (!window->isOnDesktop(it.key())) { + continue; + } + moveBeforeWindowInChain(window, reference, it.value()); + } + moveBeforeWindowInChain(window, reference, m_mostRecentlyUsed); +} + void FocusChain::moveAfterWindowInChain(Window *window, Window *reference, Chain &chain) { if (window->isDeleted()) { @@ -173,6 +193,28 @@ void FocusChain::moveAfterWindowInChain(Window *window, Window *reference, Chain } } +void FocusChain::moveBeforeWindowInChain(Window *window, Window *reference, Chain &chain) +{ + if (window->isDeleted()) { + return; + } + if (!chain.contains(reference)) { + return; + } + if (Window::belongToSameApplication(reference, window)) { + chain.removeAll(window); + chain.insert(chain.indexOf(reference) + 1, window); + } else { + chain.removeAll(window); + for (int i = chain.size() - 1; i >= 0; --i) { + if (Window::belongToSameApplication(reference, chain.at(i))) { + chain.insert(i + 1, window); + break; + } + } + } +} + Window *FocusChain::firstMostRecentlyUsed() const { if (m_mostRecentlyUsed.isEmpty()) { diff --git a/src/focuschain.h b/src/focuschain.h index cc6b2ca3ec..50a4e6d378 100644 --- a/src/focuschain.h +++ b/src/focuschain.h @@ -79,6 +79,14 @@ public: * @return void */ void moveAfterWindow(Window *window, Window *reference); + /** + * @brief Moves @p window in front of the @p reference Window in all focus chains. + * + * @param window The Window to move in the chains + * @param reference The Window in front of which the @p window should be moved + * @return void + */ + void moveBeforeWindow(Window *window, Window *reference); /** * @brief Finds the best Window to become the new active Window in the focus chain for the given * virtual @p desktop. @@ -197,6 +205,7 @@ private: */ void makeLastInChain(Window *window, Chain &chain); void moveAfterWindowInChain(Window *window, Window *reference, Chain &chain); + void moveBeforeWindowInChain(Window *window, Window *reference, Chain &chain); void updateWindowInChain(Window *window, Change change, Chain &chain); void insertWindowIntoChain(Window *window, Chain &chain); Chain m_mostRecentlyUsed; diff --git a/src/layers.cpp b/src/layers.cpp index d5a6faf5c6..1ec607df03 100644 --- a/src/layers.cpp +++ b/src/layers.cpp @@ -464,6 +464,25 @@ void Workspace::stackBelow(Window *window, Window *reference) updateStackingOrder(); } +void Workspace::stackAbove(Window *window, Window *reference) +{ + if (window->isDeleted()) { + qCWarning(KWIN_CORE) << "Workspace::stackAbove: closed window" << window << "cannot be restacked"; + return; + } + + Q_ASSERT(unconstrained_stacking_order.contains(reference)); + if (reference == window) { + return; + } + + unconstrained_stacking_order.removeAll(window); + unconstrained_stacking_order.insert(unconstrained_stacking_order.indexOf(reference) + 1, window); + + m_focusChain->moveBeforeWindow(window, reference); + updateStackingOrder(); +} + void Workspace::restackWindowUnderActive(Window *window) { if (!m_activeWindow || m_activeWindow == window || m_activeWindow->layer() != window->layer()) { diff --git a/src/workspace.h b/src/workspace.h index 165001c09d..ad05bef6f7 100644 --- a/src/workspace.h +++ b/src/workspace.h @@ -236,6 +236,7 @@ public: void lowerWindowRequest(Window *window); void restackWindowUnderActive(Window *window); void stackBelow(Window *window, Window *reference); + void stackAbove(Window *window, Window *reference); void raiseOrLowerWindow(Window *window); void updateStackingOrder(bool propagate_new_windows = false); void forceRestacking();