Introduce Workspace::stackAbove()

The main purpose is to simplify X11 Above stack mode implementation.
This commit is contained in:
Vlad Zahorodnii 2024-08-21 12:22:24 +03:00
parent 1ff2846579
commit bca341c70b
4 changed files with 71 additions and 0 deletions

View file

@ -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()) {

View file

@ -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;

View file

@ -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()) {

View file

@ -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();