From 723870337f299d4c80aa0048144f3a1ca1c885bd Mon Sep 17 00:00:00 2001 From: Vaxry <43317083+vaxerski@users.noreply.github.com> Date: Sat, 21 Feb 2026 21:30:39 +0000 Subject: layout: rethonk layouts from the ground up (#12890) Rewrites layouts to be much smaller, and deal with much less annoying BS. Improves the overall architecture, unifies handling of pseudotiling, and various other improvements. --- src/managers/KeybindManager.cpp | 539 ++++++++++++++-------------------------- 1 file changed, 182 insertions(+), 357 deletions(-) (limited to 'src/managers/KeybindManager.cpp') diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 74da3572..777f6bbe 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -19,13 +19,19 @@ #include "../managers/HookSystemManager.hpp" #include "../managers/input/InputManager.hpp" #include "../managers/animation/DesktopAnimationManager.hpp" -#include "../managers/LayoutManager.hpp" #include "../managers/EventManager.hpp" #include "../render/Renderer.hpp" #include "../hyprerror/HyprError.hpp" #include "../config/ConfigManager.hpp" #include "../desktop/rule/windowRule/WindowRule.hpp" #include "../desktop/rule/Engine.hpp" +#include "../desktop/view/Group.hpp" +#include "../layout/LayoutManager.hpp" +#include "../layout/target/WindowTarget.hpp" +#include "../layout/space/Space.hpp" +#include "../layout/algorithm/Algorithm.hpp" +#include "../layout/algorithm/tiled/master/MasterAlgorithm.hpp" +#include "../layout/algorithm/tiled/monocle/MonocleAlgorithm.hpp" #include #include @@ -322,10 +328,10 @@ void CKeybindManager::updateXKBTranslationState() { } bool CKeybindManager::ensureMouseBindState() { - if (!g_pInputManager->m_currentlyDraggedWindow) + if (!g_layoutManager->dragController()->target()) return false; - if (!g_pInputManager->m_currentlyDraggedWindow.expired()) { + if (g_layoutManager->dragController()->target()) { changeMouseBindMode(MBIND_INVALID); return true; } @@ -368,7 +374,7 @@ bool CKeybindManager::tryMoveFocusToMonitor(PHLMONITOR monitor) { const auto PNEWWINDOW = PNEWWORKSPACE->getLastFocusedWindow(); if (PNEWWINDOW) { updateRelativeCursorCoords(); - Desktop::focusState()->fullWindowFocus(PNEWWINDOW); + Desktop::focusState()->fullWindowFocus(PNEWWINDOW, Desktop::FOCUS_REASON_KEYBIND); PNEWWINDOW->warpCursor(); if (*PNOWARPS == 0 || *PFOLLOWMOUSE < 2) { @@ -377,7 +383,7 @@ bool CKeybindManager::tryMoveFocusToMonitor(PHLMONITOR monitor) { g_pInputManager->m_forcedFocus.reset(); } } else { - Desktop::focusState()->rawWindowFocus(nullptr); + Desktop::focusState()->rawWindowFocus(nullptr, Desktop::FOCUS_REASON_KEYBIND); g_pCompositor->warpCursorTo(monitor->middle()); } Desktop::focusState()->rawMonitorFocus(monitor); @@ -398,10 +404,10 @@ void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO, bool forceFSCy g_pInputManager->unconstrainMouse(); if (PLASTWINDOW && PLASTWINDOW->m_workspace == PWINDOWTOCHANGETO->m_workspace && PLASTWINDOW->isFullscreen()) - Desktop::focusState()->fullWindowFocus(PWINDOWTOCHANGETO, nullptr, forceFSCycle); + Desktop::focusState()->fullWindowFocus(PWINDOWTOCHANGETO, Desktop::FOCUS_REASON_KEYBIND, nullptr, forceFSCycle); else { updateRelativeCursorCoords(); - Desktop::focusState()->fullWindowFocus(PWINDOWTOCHANGETO, nullptr, forceFSCycle); + Desktop::focusState()->fullWindowFocus(PWINDOWTOCHANGETO, Desktop::FOCUS_REASON_KEYBIND, nullptr, forceFSCycle); PWINDOWTOCHANGETO->warpCursor(); // Move mouse focus to the new window if required by current follow_mouse and warp modes @@ -751,9 +757,9 @@ SDispatchResult CKeybindManager::handleKeybinds(const uint32_t modmask, const SP // Require mouse to stay inside drag_threshold for clicks, outside for drags // Check if either a mouse bind has triggered or currently over the threshold (maybe there is no mouse bind on the same key) const auto THRESHOLDREACHED = key.mousePosAtPress.distanceSq(g_pInputManager->getMouseCoordsInternal()) > std::pow(*PDRAGTHRESHOLD, 2); - if (k->click && (g_pInputManager->m_dragThresholdReached || THRESHOLDREACHED)) + if (k->click && (g_layoutManager->dragController()->dragThresholdReached() || THRESHOLDREACHED)) continue; - else if (k->drag && !g_pInputManager->m_dragThresholdReached && !THRESHOLDREACHED) + else if (k->drag && !g_layoutManager->dragController()->dragThresholdReached() && !THRESHOLDREACHED) continue; } @@ -810,7 +816,7 @@ SDispatchResult CKeybindManager::handleKeybinds(const uint32_t modmask, const SP found = true; } - g_pInputManager->m_dragThresholdReached = false; + g_layoutManager->dragController()->resetDragThresholdReached(); // if keybind wasn't found (or dispatcher said to) then pass event res.passEvent |= !found; @@ -1112,32 +1118,16 @@ static SDispatchResult toggleActiveFloatingCore(std::string args, std::optional< return {}; // remove drag status - if (!g_pInputManager->m_currentlyDraggedWindow.expired()) + if (g_layoutManager->dragController()->target()) CKeybindManager::changeMouseBindMode(MBIND_INVALID); - if (PWINDOW->m_groupData.pNextWindow.lock() && PWINDOW->m_groupData.pNextWindow.lock() != PWINDOW) { - const auto PCURRENT = PWINDOW->getGroupCurrent(); - - PCURRENT->m_isFloating = !PCURRENT->m_isFloating; - g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(PCURRENT); - - PHLWINDOW curr = PCURRENT->m_groupData.pNextWindow.lock(); - while (curr != PCURRENT) { - curr->m_isFloating = PCURRENT->m_isFloating; - curr = curr->m_groupData.pNextWindow.lock(); - } - } else { - PWINDOW->m_isFloating = !PWINDOW->m_isFloating; - - g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(PWINDOW); - } + g_layoutManager->changeFloatingMode(PWINDOW->layoutTarget()); if (PWINDOW->m_workspace) { PWINDOW->m_workspace->updateWindows(); PWINDOW->m_workspace->updateWindowData(); } - g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PWINDOW->monitorID()); g_pCompositor->updateAllWindowsAnimatedDecorationValues(); return {}; @@ -1163,8 +1153,7 @@ SDispatchResult CKeybindManager::centerWindow(std::string args) { const auto PMONITOR = PWINDOW->m_monitor.lock(); - *PWINDOW->m_realPosition = PMONITOR->logicalBoxMinusReserved().middle() - PWINDOW->m_realSize->goal() / 2.f; - PWINDOW->m_position = PWINDOW->m_realPosition->goal(); + PWINDOW->layoutTarget()->setPositionGlobal(CBox{PMONITOR->logicalBoxMinusReserved().middle() - PWINDOW->m_realSize->goal() / 2.F, PWINDOW->layoutTarget()->position().size()}); return {}; } @@ -1180,10 +1169,7 @@ SDispatchResult CKeybindManager::toggleActivePseudo(std::string args) { if (!PWINDOW) return {.success = false, .error = "Window not found"}; - PWINDOW->m_isPseudotiled = !PWINDOW->m_isPseudotiled; - - if (!PWINDOW->isFullscreen()) - g_pLayoutManager->getCurrentLayout()->recalculateWindow(PWINDOW); + PWINDOW->layoutTarget()->setPseudo(!PWINDOW->layoutTarget()->isPseudo()); return {}; } @@ -1276,7 +1262,7 @@ SDispatchResult CKeybindManager::changeworkspace(std::string args) { if (PMONITOR != PMONITORWORKSPACEOWNER) { Vector2D middle = PMONITORWORKSPACEOWNER->middle(); if (const auto PLAST = pWorkspaceToChangeTo->getLastFocusedWindow(); PLAST) { - Desktop::focusState()->fullWindowFocus(PLAST); + Desktop::focusState()->fullWindowFocus(PLAST, Desktop::FOCUS_REASON_KEYBIND); if (*PWORKSPACECENTERON == 1) middle = PLAST->middle(); } @@ -1421,7 +1407,7 @@ SDispatchResult CKeybindManager::moveActiveToWorkspace(std::string args) { pMonitor->changeWorkspace(pWorkspace); - Desktop::focusState()->fullWindowFocus(PWINDOW); + Desktop::focusState()->fullWindowFocus(PWINDOW, Desktop::FOCUS_REASON_KEYBIND); PWINDOW->warpCursor(); return {}; @@ -1465,7 +1451,7 @@ SDispatchResult CKeybindManager::moveActiveToWorkspaceSilent(std::string args) { if (const auto PATCOORDS = g_pCompositor->vectorToWindowUnified(OLDMIDDLE, Desktop::View::RESERVED_EXTENTS | Desktop::View::INPUT_EXTENTS | Desktop::View::ALLOW_FLOATING, PWINDOW); PATCOORDS) - Desktop::focusState()->fullWindowFocus(PATCOORDS); + Desktop::focusState()->fullWindowFocus(PATCOORDS, Desktop::FOCUS_REASON_KEYBIND); else g_pInputManager->refocus(); } @@ -1474,38 +1460,35 @@ SDispatchResult CKeybindManager::moveActiveToWorkspaceSilent(std::string args) { } SDispatchResult CKeybindManager::moveFocusTo(std::string args) { - static auto PFULLCYCLE = CConfigValue("binds:movefocus_cycles_fullscreen"); - static auto PMONITORFALLBACK = CConfigValue("binds:window_direction_monitor_fallback"); - static auto PGROUPCYCLE = CConfigValue("binds:movefocus_cycles_groupfirst"); - char arg = args[0]; + static auto PFULLCYCLE = CConfigValue("binds:movefocus_cycles_fullscreen"); + static auto PGROUPCYCLE = CConfigValue("binds:movefocus_cycles_groupfirst"); + Math::eDirection dir = Math::fromChar(args[0]); - if (!isDirection(args)) { - Log::logger->log(Log::ERR, "Cannot move focus in direction {}, unsupported direction. Supported: l,r,u/t,d/b", arg); - return {.success = false, .error = std::format("Cannot move focus in direction {}, unsupported direction. Supported: l,r,u/t,d/b", arg)}; + if (dir == Math::DIRECTION_DEFAULT) { + Log::logger->log(Log::ERR, "Cannot move focus in direction {}, unsupported direction. Supported: l,r,u/t,d/b", args[0]); + return {.success = false, .error = std::format("Cannot move focus in direction {}, unsupported direction. Supported: l,r,u/t,d/b", args[0])}; } const auto PLASTWINDOW = Desktop::focusState()->window(); if (!PLASTWINDOW || !PLASTWINDOW->aliveAndVisible()) { - if (*PMONITORFALLBACK) - tryMoveFocusToMonitor(g_pCompositor->getMonitorInDirection(arg)); - + tryMoveFocusToMonitor(g_pCompositor->getMonitorInDirection(dir)); return {}; } const auto PWINDOWTOCHANGETO = *PFULLCYCLE && PLASTWINDOW->isFullscreen() ? - g_pCompositor->getWindowCycle(PLASTWINDOW, true, {}, false, arg != 'd' && arg != 'b' && arg != 'r') : - g_pCompositor->getWindowInDirection(PLASTWINDOW, arg); + g_pCompositor->getWindowCycle(PLASTWINDOW, true, {}, false, dir != Math::DIRECTION_DOWN && dir != Math::DIRECTION_RIGHT) : + g_pCompositor->getWindowInDirection(PLASTWINDOW, dir); // Prioritize focus change within groups if the window is a part of it. - if (*PGROUPCYCLE && PLASTWINDOW->m_groupData.pNextWindow) { + if (*PGROUPCYCLE && PLASTWINDOW->m_group) { auto isTheOnlyGroupOnWs = !PWINDOWTOCHANGETO && g_pCompositor->m_monitors.size() == 1; - if (arg == 'l' && (PLASTWINDOW != PLASTWINDOW->getGroupHead() || isTheOnlyGroupOnWs)) { - PLASTWINDOW->setGroupCurrent(PLASTWINDOW->getGroupPrevious()); + if (dir == Math::DIRECTION_LEFT && (PLASTWINDOW != PLASTWINDOW->m_group->head() || isTheOnlyGroupOnWs)) { + PLASTWINDOW->m_group->moveCurrent(false); return {}; } - else if (arg == 'r' && (PLASTWINDOW != PLASTWINDOW->getGroupTail() || isTheOnlyGroupOnWs)) { - PLASTWINDOW->setGroupCurrent(PLASTWINDOW->m_groupData.pNextWindow.lock()); + else if (dir == Math::DIRECTION_RIGHT && (PLASTWINDOW != PLASTWINDOW->m_group->tail() || isTheOnlyGroupOnWs)) { + PLASTWINDOW->m_group->moveCurrent(true); return {}; } } @@ -1516,52 +1499,51 @@ SDispatchResult CKeybindManager::moveFocusTo(std::string args) { return {}; } - Log::logger->log(Log::DEBUG, "No window found in direction {}, looking for a monitor", arg); + Log::logger->log(Log::DEBUG, "No window found in direction {}, looking for a monitor", Math::toString(dir)); - if (*PMONITORFALLBACK && tryMoveFocusToMonitor(g_pCompositor->getMonitorInDirection(arg))) + if (tryMoveFocusToMonitor(g_pCompositor->getMonitorInDirection(dir))) return {}; static auto PNOFALLBACK = CConfigValue("general:no_focus_fallback"); if (*PNOFALLBACK) - return {.success = false, .error = std::format("Nothing to focus to in direction {}", arg)}; + return {.success = false, .error = std::format("Nothing to focus to in direction {}", Math::toString(dir))}; - Log::logger->log(Log::DEBUG, "No monitor found in direction {}, getting the inverse edge", arg); + Log::logger->log(Log::DEBUG, "No monitor found in direction {}, getting the inverse edge", Math::toString(dir)); const auto PMONITOR = PLASTWINDOW->m_monitor.lock(); if (!PMONITOR) return {.success = false, .error = "last window has no monitor?"}; - if (arg == 'l' || arg == 'r') { + if (dir == Math::DIRECTION_LEFT || dir == Math::DIRECTION_RIGHT) { if (STICKS(PLASTWINDOW->m_position.x, PMONITOR->m_position.x) && STICKS(PLASTWINDOW->m_size.x, PMONITOR->m_size.x)) return {.success = false, .error = "move does not make sense, would return back"}; } else if (STICKS(PLASTWINDOW->m_position.y, PMONITOR->m_position.y) && STICKS(PLASTWINDOW->m_size.y, PMONITOR->m_size.y)) return {.success = false, .error = "move does not make sense, would return back"}; CBox box = PMONITOR->logicalBox(); - switch (arg) { - case 'l': + switch (dir) { + case Math::DIRECTION_LEFT: box.x += box.w; box.w = 1; break; - case 'r': + case Math::DIRECTION_RIGHT: box.x -= 1; box.w = 1; break; - case 'u': - case 't': + case Math::DIRECTION_UP: box.y += box.h; box.h = 1; break; - case 'd': - case 'b': + case Math::DIRECTION_DOWN: box.y -= 1; box.h = 1; break; + default: break; } const auto PWINDOWCANDIDATE = g_pCompositor->getWindowInDirection(box, PMONITOR->m_activeSpecialWorkspace ? PMONITOR->m_activeSpecialWorkspace : PMONITOR->m_activeWorkspace, - arg, PLASTWINDOW, PLASTWINDOW->m_isFloating); + dir, PLASTWINDOW, PLASTWINDOW->m_isFloating); if (PWINDOWCANDIDATE) switchToWindow(PWINDOWCANDIDATE); @@ -1598,7 +1580,6 @@ SDispatchResult CKeybindManager::focusCurrentOrLast(std::string args) { } SDispatchResult CKeybindManager::swapActive(std::string args) { - char arg = args[0]; const auto PLASTWINDOW = Desktop::focusState()->window(); PHLWINDOW PWINDOWTOCHANGETO = nullptr; @@ -1608,9 +1589,10 @@ SDispatchResult CKeybindManager::swapActive(std::string args) { if (PLASTWINDOW->isFullscreen()) return {.success = false, .error = "Can't swap fullscreen window"}; - if (isDirection(args)) - PWINDOWTOCHANGETO = g_pCompositor->getWindowInDirection(PLASTWINDOW, arg); - else + if (isDirection(args)) { + Math::eDirection dir = Math::fromChar(args[0]); + PWINDOWTOCHANGETO = g_pCompositor->getWindowInDirection(PLASTWINDOW, dir); + } else PWINDOWTOCHANGETO = g_pCompositor->getWindowByRegex(args); if (!PWINDOWTOCHANGETO || PWINDOWTOCHANGETO == PLASTWINDOW) { @@ -1621,13 +1603,12 @@ SDispatchResult CKeybindManager::swapActive(std::string args) { Log::logger->log(Log::DEBUG, "Swapping active window with {}", args); updateRelativeCursorCoords(); - g_pLayoutManager->getCurrentLayout()->switchWindows(PLASTWINDOW, PWINDOWTOCHANGETO); + g_layoutManager->switchTargets(PLASTWINDOW->layoutTarget(), PWINDOWTOCHANGETO->layoutTarget(), true); PLASTWINDOW->warpCursor(); return {}; } SDispatchResult CKeybindManager::moveActiveTo(std::string args) { - char arg = args[0]; bool silent = args.ends_with(" silent"); if (silent) args = args.substr(0, args.length() - 7); @@ -1645,9 +1626,10 @@ SDispatchResult CKeybindManager::moveActiveTo(std::string args) { return {}; } - if (!isDirection(args)) { - Log::logger->log(Log::ERR, "Cannot move window in direction {}, unsupported direction. Supported: l,r,u/t,d/b", arg); - return {.success = false, .error = std::format("Cannot move window in direction {}, unsupported direction. Supported: l,r,u/t,d/b", arg)}; + Math::eDirection dir = Math::fromChar(args[0]); + if (dir == Math::DIRECTION_DEFAULT) { + Log::logger->log(Log::ERR, "Cannot move window in direction {}, unsupported direction. Supported: l,r,u/t,d/b", args[0]); + return {.success = false, .error = std::format("Cannot move window in direction {}, unsupported direction. Supported: l,r,u/t,d/b", args[0])}; } const auto PLASTWINDOW = Desktop::focusState()->window(); @@ -1658,59 +1640,11 @@ SDispatchResult CKeybindManager::moveActiveTo(std::string args) { if (PLASTWINDOW->isFullscreen()) return {.success = false, .error = "Can't move fullscreen window"}; - if (PLASTWINDOW->m_isFloating) { - std::optional vPosx, vPosy; - const auto PMONITOR = PLASTWINDOW->m_monitor.lock(); - const auto BORDERSIZE = PLASTWINDOW->getRealBorderSize(); - static auto PGAPSCUSTOMDATA = CConfigValue("general:float_gaps"); - static auto PGAPSOUTDATA = CConfigValue("general:gaps_out"); - auto* PGAPSOUT = sc(PGAPSCUSTOMDATA.ptr()->getData()); - if (PGAPSOUT->m_left < 0 || PGAPSOUT->m_right < 0 || PGAPSOUT->m_top < 0 || PGAPSOUT->m_bottom < 0) - PGAPSOUT = sc(PGAPSOUTDATA.ptr()->getData()); - - switch (arg) { - case 'l': vPosx = PMONITOR->m_reservedArea.left() + BORDERSIZE + PMONITOR->m_position.x + PGAPSOUT->m_left; break; - case 'r': - vPosx = PMONITOR->m_size.x - PMONITOR->m_reservedArea.right() - PLASTWINDOW->m_realSize->goal().x - BORDERSIZE + PMONITOR->m_position.x - PGAPSOUT->m_right; - break; - case 't': - case 'u': vPosy = PMONITOR->m_reservedArea.top() + BORDERSIZE + PMONITOR->m_position.y + PGAPSOUT->m_top; break; - case 'b': - case 'd': - vPosy = PMONITOR->m_size.y - PMONITOR->m_reservedArea.bottom() - PLASTWINDOW->m_realSize->goal().y - BORDERSIZE + PMONITOR->m_position.y - PGAPSOUT->m_bottom; - break; - } - - *PLASTWINDOW->m_realPosition = Vector2D(vPosx.value_or(PLASTWINDOW->m_realPosition->goal().x), vPosy.value_or(PLASTWINDOW->m_realPosition->goal().y)); - - return {}; - } - - // If the window to change to is on the same workspace, switch them - const auto PWINDOWTOCHANGETO = g_pCompositor->getWindowInDirection(PLASTWINDOW, arg); - if (PWINDOWTOCHANGETO) { - updateRelativeCursorCoords(); - - g_pLayoutManager->getCurrentLayout()->moveWindowTo(PLASTWINDOW, args, silent); - if (!silent) - PLASTWINDOW->warpCursor(); - return {}; - } - - static auto PMONITORFALLBACK = CConfigValue("binds:window_direction_monitor_fallback"); - if (!*PMONITORFALLBACK) - return {}; - - // Otherwise, we always want to move to the next monitor in that direction - const auto PMONITORTOCHANGETO = g_pCompositor->getMonitorInDirection(arg); - if (!PMONITORTOCHANGETO) - return {.success = false, .error = "Nowhere to move active window to"}; + updateRelativeCursorCoords(); - const auto PWORKSPACE = PMONITORTOCHANGETO->m_activeWorkspace; - if (silent) - moveActiveToWorkspaceSilent(PWORKSPACE->getConfigName()); - else - moveActiveToWorkspace(PWORKSPACE->getConfigName()); + g_layoutManager->moveInDirection(PLASTWINDOW->layoutTarget(), args, silent); + if (!silent) + PLASTWINDOW->warpCursor(); return {}; } @@ -1724,10 +1658,10 @@ SDispatchResult CKeybindManager::toggleGroup(std::string args) { if (PWINDOW->isFullscreen()) g_pCompositor->setWindowFullscreenInternal(PWINDOW, FSMODE_NONE); - if (PWINDOW->m_groupData.pNextWindow.expired()) - PWINDOW->createGroup(); + if (!PWINDOW->m_group) + PWINDOW->m_group = Desktop::View::CGroup::create({PWINDOW}); else - PWINDOW->destroyGroup(); + PWINDOW->m_group->destroy(); return {}; } @@ -1738,89 +1672,40 @@ SDispatchResult CKeybindManager::changeGroupActive(std::string args) { if (!PWINDOW) return {.success = false, .error = "Window not found"}; - if (PWINDOW->m_groupData.pNextWindow.expired()) - return {.success = false, .error = "No next window in group"}; + if (!PWINDOW->m_group) + return {.success = false, .error = "No group"}; - if (PWINDOW->m_groupData.pNextWindow.lock() == PWINDOW) + if (PWINDOW->m_group->size() == 1) return {.success = false, .error = "Only one window in group"}; if (isNumber(args, false)) { // index starts from '1'; '0' means last window - const int INDEX = std::stoi(args); - if (INDEX > PWINDOW->getGroupSize()) - return {.success = false, .error = "Index too big, there aren't that many windows in this group"}; - if (INDEX == 0) - PWINDOW->setGroupCurrent(PWINDOW->getGroupTail()); - else - PWINDOW->setGroupCurrent(PWINDOW->getGroupWindowByIndex(INDEX - 1)); + try { + const int INDEX = std::stoi(args); + PWINDOW->m_group->setCurrent(INDEX); + } catch (...) { return {.success = false, .error = "invalid idx"}; } + return {}; } if (args != "b" && args != "prev") - PWINDOW->setGroupCurrent(PWINDOW->m_groupData.pNextWindow.lock()); + PWINDOW->m_group->moveCurrent(true); else - PWINDOW->setGroupCurrent(PWINDOW->getGroupPrevious()); + PWINDOW->m_group->moveCurrent(false); return {}; } SDispatchResult CKeybindManager::toggleSplit(std::string args) { - SLayoutMessageHeader header; - header.pWindow = Desktop::focusState()->window(); - - if (!header.pWindow) - return {.success = false, .error = "Window not found"}; - - const auto PWORKSPACE = header.pWindow->m_workspace; - - if (PWORKSPACE->m_hasFullscreenWindow) - return {.success = false, .error = "Can't split windows that already split"}; - - g_pLayoutManager->getCurrentLayout()->layoutMessage(header, "togglesplit"); - - return {}; + return {.success = false, .error = "removed - use layoutmsg"}; } SDispatchResult CKeybindManager::swapSplit(std::string args) { - SLayoutMessageHeader header; - header.pWindow = Desktop::focusState()->window(); - - if (!header.pWindow) - return {.success = false, .error = "Window not found"}; - - const auto PWORKSPACE = header.pWindow->m_workspace; - - if (PWORKSPACE->m_hasFullscreenWindow) - return {.success = false, .error = "Can't split windows that already split"}; - - g_pLayoutManager->getCurrentLayout()->layoutMessage(header, "swapsplit"); - - return {}; + return {.success = false, .error = "removed - use layoutmsg"}; } SDispatchResult CKeybindManager::alterSplitRatio(std::string args) { - std::optional splitResult; - bool exact = false; - - if (args.starts_with("exact")) { - exact = true; - splitResult = getPlusMinusKeywordResult(args.substr(5), 0); - } else - splitResult = getPlusMinusKeywordResult(args, 0); - - if (!splitResult.has_value()) { - Log::logger->log(Log::ERR, "Splitratio invalid in alterSplitRatio!"); - return {.success = false, .error = "Splitratio invalid in alterSplitRatio!"}; - } - - const auto PLASTWINDOW = Desktop::focusState()->window(); - - if (!PLASTWINDOW) - return {.success = false, .error = "Window not found"}; - - g_pLayoutManager->getCurrentLayout()->alterSplitRatio(PLASTWINDOW, splitResult.value(), exact); - - return {}; + return {.success = false, .error = "removed - use layoutmsg"}; } SDispatchResult CKeybindManager::focusMonitor(std::string arg) { @@ -1903,58 +1788,7 @@ SDispatchResult CKeybindManager::moveCursor(std::string args) { } SDispatchResult CKeybindManager::workspaceOpt(std::string args) { - - // current workspace - const auto PWORKSPACE = Desktop::focusState()->monitor()->m_activeWorkspace; - - if (!PWORKSPACE) - return {.success = false, .error = "Workspace not found"}; // ???? - - if (args == "allpseudo") { - PWORKSPACE->m_defaultPseudo = !PWORKSPACE->m_defaultPseudo; - - // apply - for (auto const& w : g_pCompositor->m_windows) { - if (!w->m_isMapped || w->m_workspace != PWORKSPACE) - continue; - - w->m_isPseudotiled = PWORKSPACE->m_defaultPseudo; - } - } else if (args == "allfloat") { - PWORKSPACE->m_defaultFloating = !PWORKSPACE->m_defaultFloating; - // apply - - // we make a copy because changeWindowFloatingMode might invalidate the iterator - std::vector ptrs(g_pCompositor->m_windows.begin(), g_pCompositor->m_windows.end()); - - for (auto const& w : ptrs) { - if (!w->m_isMapped || w->m_workspace != PWORKSPACE || w->isHidden()) - continue; - - if (!w->m_requestsFloat && w->m_isFloating != PWORKSPACE->m_defaultFloating) { - const auto SAVEDPOS = w->m_realPosition->goal(); - const auto SAVEDSIZE = w->m_realSize->goal(); - - w->m_isFloating = PWORKSPACE->m_defaultFloating; - g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(w); - - if (PWORKSPACE->m_defaultFloating) { - w->m_realPosition->setValueAndWarp(SAVEDPOS); - w->m_realSize->setValueAndWarp(SAVEDSIZE); - *w->m_realSize = w->m_realSize->value() + Vector2D(4, 4); - *w->m_realPosition = w->m_realPosition->value() - Vector2D(2, 2); - } - } - } - } else { - Log::logger->log(Log::ERR, "Invalid arg in workspaceOpt, opt \"{}\" doesn't exist.", args); - return {.success = false, .error = std::format("Invalid arg in workspaceOpt, opt \"{}\" doesn't exist.", args)}; - } - - // recalc mon - g_pLayoutManager->getCurrentLayout()->recalculateMonitor(Desktop::focusState()->monitor()->m_id); - - return {}; + return {.success = false, .error = "workspaceopt is deprecated"}; } SDispatchResult CKeybindManager::renameWorkspace(std::string args) { @@ -2183,7 +2017,7 @@ SDispatchResult CKeybindManager::resizeActive(std::string args) { if (SIZ.x < 1 || SIZ.y < 1) return {.success = false, .error = "Invalid size provided"}; - g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(SIZ - PLASTWINDOW->m_realSize->goal()); + g_layoutManager->resizeTarget(SIZ - PLASTWINDOW->m_realSize->goal(), PLASTWINDOW->layoutTarget()); if (PLASTWINDOW->m_realSize->goal().x > 1 && PLASTWINDOW->m_realSize->goal().y > 1) PLASTWINDOW->setHidden(false); @@ -2202,7 +2036,7 @@ SDispatchResult CKeybindManager::moveActive(std::string args) { const auto POS = g_pCompositor->parseWindowVectorArgsRelative(args, PLASTWINDOW->m_realPosition->goal()); - g_pLayoutManager->getCurrentLayout()->moveActiveWindow(POS - PLASTWINDOW->m_realPosition->goal()); + g_layoutManager->moveTarget(POS - PLASTWINDOW->m_realPosition->goal(), PLASTWINDOW->layoutTarget()); return {}; } @@ -2224,7 +2058,7 @@ SDispatchResult CKeybindManager::moveWindow(std::string args) { const auto POS = g_pCompositor->parseWindowVectorArgsRelative(MOVECMD, PWINDOW->m_realPosition->goal()); - g_pLayoutManager->getCurrentLayout()->moveActiveWindow(POS - PWINDOW->m_realPosition->goal(), PWINDOW); + g_layoutManager->moveTarget(POS - PWINDOW->m_realPosition->goal(), PWINDOW->layoutTarget()); return {}; } @@ -2249,7 +2083,7 @@ SDispatchResult CKeybindManager::resizeWindow(std::string args) { if (SIZ.x < 1 || SIZ.y < 1) return {.success = false, .error = "Invalid size provided"}; - g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(SIZ - PWINDOW->m_realSize->goal(), CORNER_NONE, PWINDOW); + g_layoutManager->resizeTarget(SIZ - PWINDOW->m_realSize->goal(), PWINDOW->layoutTarget(), Layout::CORNER_NONE); if (PWINDOW->m_realSize->goal().x > 1 && PWINDOW->m_realSize->goal().y > 1) PWINDOW->setHidden(false); @@ -2271,14 +2105,32 @@ SDispatchResult CKeybindManager::circleNext(std::string arg) { CVarList args{arg, 0, 's', true}; + const auto PREV = args.contains("prev") || args.contains("p") || args.contains("last") || args.contains("l"); + std::optional floatStatus = {}; - if (args.contains("tile") || args.contains("tiled")) - floatStatus = false; - else if (args.contains("float") || args.contains("floating")) + if (args.contains("tile") || args.contains("tiled")) { + // if we want just tiled, and we are on a tiled window, use layoutmsg for layouts that support it + + if (!Desktop::focusState()->window()->m_isFloating) { + if (const auto SPACE = Desktop::focusState()->window()->layoutTarget()->space(); SPACE) { + + constexpr const std::array LAYOUTS_WITH_CYCLE_NEXT = { + &typeid(Layout::Tiled::CMonocleAlgorithm), + &typeid(Layout::Tiled::CMasterAlgorithm), + }; + + if (std::ranges::contains(LAYOUTS_WITH_CYCLE_NEXT, &typeid(*SPACE->algorithm()->tiledAlgo().get()))) { + CKeybindManager::layoutmsg(PREV ? "cyclenext, b" : "cyclenext"); + return {}; + } + } + } + } + + if (args.contains("float") || args.contains("floating")) floatStatus = true; const auto VISIBLE = args.contains("visible") || args.contains("v"); - const auto PREV = args.contains("prev") || args.contains("p") || args.contains("last") || args.contains("l"); const auto NEXT = args.contains("next") || args.contains("n"); // prev is default in classic alt+tab const auto HIST = args.contains("hist") || args.contains("h"); const auto& w = HIST ? g_pCompositor->getWindowCycleHist(Desktop::focusState()->window(), true, floatStatus, VISIBLE, NEXT) : @@ -2311,7 +2163,7 @@ SDispatchResult CKeybindManager::focusWindow(std::string regexp) { changeworkspace(PWORKSPACE->getConfigName()); } - Desktop::focusState()->fullWindowFocus(PWINDOW, nullptr, false); + Desktop::focusState()->fullWindowFocus(PWINDOW, Desktop::FOCUS_REASON_KEYBIND, nullptr, false); PWINDOW->warpCursor(); @@ -2347,12 +2199,12 @@ SDispatchResult CKeybindManager::toggleSwallow(std::string args) { // Unswallow pWindow->m_swallowed->m_currentlySwallowed = false; pWindow->m_swallowed->setHidden(false); - g_pLayoutManager->getCurrentLayout()->onWindowCreated(pWindow->m_swallowed.lock()); + g_layoutManager->newTarget(pWindow->m_swallowed->layoutTarget(), pWindow->m_workspace->m_space); } else { // Reswallow pWindow->m_swallowed->m_currentlySwallowed = true; pWindow->m_swallowed->setHidden(true); - g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pWindow->m_swallowed.lock()); + g_layoutManager->removeTarget(pWindow->m_swallowed->layoutTarget()); } return {}; @@ -2613,9 +2465,9 @@ SDispatchResult CKeybindManager::sendshortcut(std::string args) { } SDispatchResult CKeybindManager::layoutmsg(std::string msg) { - SLayoutMessageHeader hd = {Desktop::focusState()->window()}; - g_pLayoutManager->getCurrentLayout()->layoutMessage(hd, msg); - + auto ret = g_layoutManager->layoutMsg(msg); + if (!ret) + return {.success = false, .error = ret.error()}; return {}; } @@ -2669,11 +2521,11 @@ SDispatchResult CKeybindManager::swapnext(std::string arg) { if (toSwap == PLASTWINDOW) toSwap = g_pCompositor->getWindowCycle(PLASTWINDOW, true, std::nullopt, false, NEED_PREV); - g_pLayoutManager->getCurrentLayout()->switchWindows(PLASTWINDOW, toSwap); + g_layoutManager->switchTargets(PLASTWINDOW->layoutTarget(), toSwap->layoutTarget(), false); PLASTWINDOW->m_lastCycledWindow = toSwap; - Desktop::focusState()->fullWindowFocus(PLASTWINDOW); + Desktop::focusState()->fullWindowFocus(PLASTWINDOW, Desktop::FOCUS_REASON_KEYBIND); return {}; } @@ -2722,7 +2574,7 @@ SDispatchResult CKeybindManager::pinActive(std::string args) { return {.success = false, .error = "pin: window not found"}; } - PWINDOW->m_workspace = PMONITOR->m_activeWorkspace; + PWINDOW->moveToWorkspace(PMONITOR->m_activeWorkspace); PWINDOW->m_ruleApplicator->propertiesChanged(Desktop::Rule::RULE_PROP_PINNED); @@ -2734,6 +2586,8 @@ SDispatchResult CKeybindManager::pinActive(std::string args) { g_pEventManager->postEvent(SHyprIPCEvent{"pin", std::format("{:x},{}", rc(PWINDOW.get()), sc(PWINDOW->m_pinned))}); EMIT_HOOK_EVENT("pin", PWINDOW); + g_pHyprRenderer->damageWindow(PWINDOW, true); + return {}; } @@ -2760,7 +2614,7 @@ SDispatchResult CKeybindManager::mouse(std::string args) { SDispatchResult CKeybindManager::changeMouseBindMode(const eMouseBindMode MODE) { if (MODE != MBIND_INVALID) { - if (!g_pInputManager->m_currentlyDraggedWindow.expired() || g_pInputManager->m_dragMode != MBIND_INVALID) + if (g_layoutManager->dragController()->target()) return {}; const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal(); @@ -2769,21 +2623,17 @@ SDispatchResult CKeybindManager::changeMouseBindMode(const eMouseBindMode MODE) if (!PWINDOW) return SDispatchResult{.passEvent = true}; - if (!PWINDOW->isFullscreen() && MODE == MBIND_MOVE) - PWINDOW->checkInputOnDecos(INPUT_TYPE_DRAG_START, MOUSECOORDS); - - if (g_pInputManager->m_currentlyDraggedWindow.expired()) - g_pInputManager->m_currentlyDraggedWindow = PWINDOW; - - g_pInputManager->m_dragMode = MODE; + if (!PWINDOW->isFullscreen() && MODE == MBIND_MOVE) { + if (PWINDOW->checkInputOnDecos(INPUT_TYPE_DRAG_START, MOUSECOORDS)) + return SDispatchResult{.passEvent = false}; + } - g_pLayoutManager->getCurrentLayout()->onBeginDragWindow(); + g_layoutManager->beginDragTarget(PWINDOW->layoutTarget(), MODE); } else { - if (g_pInputManager->m_currentlyDraggedWindow.expired() || g_pInputManager->m_dragMode == MBIND_INVALID) + if (!g_layoutManager->dragController()->target()) return {}; - g_pLayoutManager->getCurrentLayout()->onEndDragWindow(); - g_pInputManager->m_dragMode = MODE; + g_layoutManager->endDragTarget(); } return {}; @@ -2845,17 +2695,15 @@ SDispatchResult CKeybindManager::lockActiveGroup(std::string args) { if (!PWINDOW) return {.success = false, .error = "No window found"}; - if (!PWINDOW->m_groupData.pNextWindow.lock()) + if (!PWINDOW->m_group) return {.success = false, .error = "Not a group"}; - const auto PHEAD = PWINDOW->getGroupHead(); - if (args == "lock") - PHEAD->m_groupData.locked = true; + PWINDOW->m_group->setLocked(true); else if (args == "toggle") - PHEAD->m_groupData.locked = !PHEAD->m_groupData.locked; + PWINDOW->m_group->setLocked(!PWINDOW->m_group->locked()); else - PHEAD->m_groupData.locked = false; + PWINDOW->m_group->setLocked(false); PWINDOW->updateDecorationValues(); @@ -2863,25 +2711,21 @@ SDispatchResult CKeybindManager::lockActiveGroup(std::string args) { } void CKeybindManager::moveWindowIntoGroup(PHLWINDOW pWindow, PHLWINDOW pWindowInDirection) { - if (pWindow->m_groupData.deny) + if (!pWindowInDirection->m_group || pWindowInDirection->m_group->denied()) return; updateRelativeCursorCoords(); - g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pWindow); // This removes grouped property! - if (pWindow->m_monitor != pWindowInDirection->m_monitor) { pWindow->moveToWorkspace(pWindowInDirection->m_workspace); pWindow->m_monitor = pWindowInDirection->m_monitor; } - static auto USECURRPOS = CConfigValue("group:insert_after_current"); - (*USECURRPOS ? pWindowInDirection : pWindowInDirection->getGroupTail())->insertWindowToGroup(pWindow); + pWindowInDirection->m_group->add(pWindow); - pWindowInDirection->setGroupCurrent(pWindow); + pWindowInDirection->m_group->setCurrent(pWindow); pWindow->updateWindowDecos(); - g_pLayoutManager->getCurrentLayout()->recalculateWindow(pWindow); - Desktop::focusState()->fullWindowFocus(pWindow); + Desktop::focusState()->fullWindowFocus(pWindow, Desktop::FOCUS_REASON_KEYBIND); pWindow->warpCursor(); g_pEventManager->postEvent(SHyprIPCEvent{"moveintogroup", std::format("{:x}", rc(pWindow.get()))}); @@ -2889,70 +2733,51 @@ void CKeybindManager::moveWindowIntoGroup(PHLWINDOW pWindow, PHLWINDOW pWindowIn void CKeybindManager::moveWindowOutOfGroup(PHLWINDOW pWindow, const std::string& dir) { static auto BFOCUSREMOVEDWINDOW = CConfigValue("group:focus_removed_window"); - const auto PWINDOWPREV = pWindow->getGroupPrevious(); - eDirection direction; - - switch (dir[0]) { - case 't': - case 'u': direction = DIRECTION_UP; break; - case 'd': - case 'b': direction = DIRECTION_DOWN; break; - case 'l': direction = DIRECTION_LEFT; break; - case 'r': direction = DIRECTION_RIGHT; break; - default: direction = DIRECTION_DEFAULT; - } - - updateRelativeCursorCoords(); - if (pWindow->m_groupData.pNextWindow.lock() == pWindow) { - pWindow->destroyGroup(); - } else { - g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pWindow); + if (!pWindow->m_group) + return; - const auto GROUPSLOCKEDPREV = g_pKeybindManager->m_groupsLocked; - g_pKeybindManager->m_groupsLocked = true; + WP group = pWindow->m_group; - g_pLayoutManager->getCurrentLayout()->onWindowCreated(pWindow, direction); + pWindow->m_group->remove(pWindow); - g_pKeybindManager->m_groupsLocked = GROUPSLOCKEDPREV; - } - - if (*BFOCUSREMOVEDWINDOW) { - Desktop::focusState()->fullWindowFocus(pWindow); + if (*BFOCUSREMOVEDWINDOW || !group) { + Desktop::focusState()->fullWindowFocus(pWindow, Desktop::FOCUS_REASON_KEYBIND); pWindow->warpCursor(); } else { - Desktop::focusState()->fullWindowFocus(PWINDOWPREV); - PWINDOWPREV->warpCursor(); + Desktop::focusState()->fullWindowFocus(group->current(), Desktop::FOCUS_REASON_KEYBIND); + group->current()->warpCursor(); } g_pEventManager->postEvent(SHyprIPCEvent{"moveoutofgroup", std::format("{:x}", rc(pWindow.get()))}); } SDispatchResult CKeybindManager::moveIntoGroup(std::string args) { - char arg = args[0]; - static auto PIGNOREGROUPLOCK = CConfigValue("binds:ignore_group_lock"); if (!*PIGNOREGROUPLOCK && g_pKeybindManager->m_groupsLocked) return {}; - if (!isDirection(args)) { - Log::logger->log(Log::ERR, "Cannot move into group in direction {}, unsupported direction. Supported: l,r,u/t,d/b", arg); - return {.success = false, .error = std::format("Cannot move into group in direction {}, unsupported direction. Supported: l,r,u/t,d/b", arg)}; + Math::eDirection dir = Math::fromChar(args[0]); + if (dir == Math::DIRECTION_DEFAULT) { + Log::logger->log(Log::ERR, "Cannot move into group in direction {}, unsupported direction. Supported: l,r,u/t,d/b", args[0]); + return {.success = false, .error = std::format("Cannot move into group in direction {}, unsupported direction. Supported: l,r,u/t,d/b", args[0])}; } const auto PWINDOW = Desktop::focusState()->window(); - if (!PWINDOW || PWINDOW->m_groupData.deny) + if (!PWINDOW) return {}; - auto PWINDOWINDIR = g_pCompositor->getWindowInDirection(PWINDOW, arg); + auto PWINDOWINDIR = g_pCompositor->getWindowInDirection(PWINDOW, dir); - if (!PWINDOWINDIR || !PWINDOWINDIR->m_groupData.pNextWindow.lock()) + if (!PWINDOWINDIR || !PWINDOWINDIR->m_group) return {}; + const auto GROUP = PWINDOWINDIR->m_group; + // Do not move window into locked group if binds:ignore_group_lock is false - if (!*PIGNOREGROUPLOCK && (PWINDOWINDIR->getGroupHead()->m_groupData.locked || (PWINDOW->m_groupData.pNextWindow.lock() && PWINDOW->getGroupHead()->m_groupData.locked))) + if (!*PIGNOREGROUPLOCK && (GROUP->locked() || (PWINDOW->m_group && PWINDOW->m_group->locked()))) return {}; moveWindowIntoGroup(PWINDOW, PWINDOWINDIR); @@ -2976,7 +2801,7 @@ SDispatchResult CKeybindManager::moveOutOfGroup(std::string args) { if (!PWINDOW) return {.success = false, .error = "No window found"}; - if (!PWINDOW->m_groupData.pNextWindow.lock()) + if (!PWINDOW->m_group) return {.success = false, .error = "Window not in a group"}; moveWindowOutOfGroup(PWINDOW); @@ -2985,13 +2810,12 @@ SDispatchResult CKeybindManager::moveOutOfGroup(std::string args) { } SDispatchResult CKeybindManager::moveWindowOrGroup(std::string args) { - char arg = args[0]; - - static auto PIGNOREGROUPLOCK = CConfigValue("binds:ignore_group_lock"); + static auto PIGNOREGROUPLOCK = CConfigValue("binds:ignore_group_lock"); - if (!isDirection(args)) { - Log::logger->log(Log::ERR, "Cannot move into group in direction {}, unsupported direction. Supported: l,r,u/t,d/b", arg); - return {.success = false, .error = std::format("Cannot move into group in direction {}, unsupported direction. Supported: l,r,u/t,d/b", arg)}; + Math::eDirection dir = Math::fromChar(args[0]); + if (dir == Math::DIRECTION_DEFAULT) { + Log::logger->log(Log::ERR, "Cannot move into group in direction {}, unsupported direction. Supported: l,r,u/t,d/b", args[0]); + return {.success = false, .error = std::format("Cannot move into group in direction {}, unsupported direction. Supported: l,r,u/t,d/b", args[0])}; } const auto PWINDOW = Desktop::focusState()->window(); @@ -3002,35 +2826,35 @@ SDispatchResult CKeybindManager::moveWindowOrGroup(std::string args) { return {}; if (!*PIGNOREGROUPLOCK && g_pKeybindManager->m_groupsLocked) { - g_pLayoutManager->getCurrentLayout()->moveWindowTo(PWINDOW, args); + g_layoutManager->moveInDirection(PWINDOW->layoutTarget(), args); return {}; } - const auto PWINDOWINDIR = g_pCompositor->getWindowInDirection(PWINDOW, arg); + const auto PWINDOWINDIR = g_pCompositor->getWindowInDirection(PWINDOW, dir); - const bool ISWINDOWGROUP = PWINDOW->m_groupData.pNextWindow; - const bool ISWINDOWGROUPLOCKED = ISWINDOWGROUP && PWINDOW->getGroupHead()->m_groupData.locked; - const bool ISWINDOWGROUPSINGLE = ISWINDOWGROUP && PWINDOW->m_groupData.pNextWindow.lock() == PWINDOW; + const bool ISWINDOWGROUP = PWINDOW->m_group; + const bool ISWINDOWGROUPLOCKED = ISWINDOWGROUP && PWINDOW->m_group->locked(); + const bool ISWINDOWGROUPSINGLE = ISWINDOWGROUP && PWINDOW->m_group->size() == 1; updateRelativeCursorCoords(); // note: PWINDOWINDIR is not null implies !PWINDOW->m_isFloating - if (PWINDOWINDIR && PWINDOWINDIR->m_groupData.pNextWindow) { // target is group - if (!*PIGNOREGROUPLOCK && (PWINDOWINDIR->getGroupHead()->m_groupData.locked || ISWINDOWGROUPLOCKED || PWINDOW->m_groupData.deny)) { - g_pLayoutManager->getCurrentLayout()->moveWindowTo(PWINDOW, args); + if (PWINDOWINDIR && PWINDOWINDIR->m_group) { // target is group + if (!*PIGNOREGROUPLOCK && (PWINDOWINDIR->m_group->locked() || ISWINDOWGROUPLOCKED || PWINDOW->m_group->denied())) { + g_layoutManager->moveInDirection(PWINDOW->layoutTarget(), args); PWINDOW->warpCursor(); } else moveWindowIntoGroup(PWINDOW, PWINDOWINDIR); } else if (PWINDOWINDIR) { // target is regular window if ((!*PIGNOREGROUPLOCK && ISWINDOWGROUPLOCKED) || !ISWINDOWGROUP || (ISWINDOWGROUPSINGLE && PWINDOW->m_groupRules & Desktop::View::GROUP_SET_ALWAYS)) { - g_pLayoutManager->getCurrentLayout()->moveWindowTo(PWINDOW, args); + g_layoutManager->moveInDirection(PWINDOW->layoutTarget(), args); PWINDOW->warpCursor(); } else moveWindowOutOfGroup(PWINDOW, args); } else if ((*PIGNOREGROUPLOCK || !ISWINDOWGROUPLOCKED) && ISWINDOWGROUP) { // no target window moveWindowOutOfGroup(PWINDOW, args); } else if (!PWINDOWINDIR && !ISWINDOWGROUP) { // no target in dir and not in group - g_pLayoutManager->getCurrentLayout()->moveWindowTo(PWINDOW, args); + g_layoutManager->moveInDirection(PWINDOW->layoutTarget(), args); PWINDOW->warpCursor(); } @@ -3054,13 +2878,13 @@ SDispatchResult CKeybindManager::setIgnoreGroupLock(std::string args) { SDispatchResult CKeybindManager::denyWindowFromGroup(std::string args) { const auto PWINDOW = Desktop::focusState()->window(); - if (!PWINDOW || (PWINDOW && PWINDOW->m_groupData.pNextWindow.lock())) + if (!PWINDOW || (PWINDOW && PWINDOW->m_group)) return {}; if (args == "toggle") - PWINDOW->m_groupData.deny = !PWINDOW->m_groupData.deny; + PWINDOW->m_group->setDenied(!PWINDOW->m_group->denied()); else - PWINDOW->m_groupData.deny = args == "on"; + PWINDOW->m_group->setDenied(args == "on"); PWINDOW->updateDecorationValues(); @@ -3090,16 +2914,15 @@ SDispatchResult CKeybindManager::moveGroupWindow(std::string args) { if (!PLASTWINDOW) return {.success = false, .error = "No window found"}; - if (!PLASTWINDOW->m_groupData.pNextWindow.lock()) + if (!PLASTWINDOW->m_group) return {.success = false, .error = "Window not in a group"}; - if ((!BACK && PLASTWINDOW->m_groupData.pNextWindow->m_groupData.head) || (BACK && PLASTWINDOW->m_groupData.head)) { - std::swap(PLASTWINDOW->m_groupData.head, PLASTWINDOW->m_groupData.pNextWindow->m_groupData.head); - std::swap(PLASTWINDOW->m_groupData.locked, PLASTWINDOW->m_groupData.pNextWindow->m_groupData.locked); - } else - PLASTWINDOW->switchWithWindowInGroup(BACK ? PLASTWINDOW->getGroupPrevious() : PLASTWINDOW->m_groupData.pNextWindow.lock()); + const auto GROUP = PLASTWINDOW->m_group; - PLASTWINDOW->updateWindowDecos(); + if (BACK) + GROUP->swapWithLast(); + else + GROUP->swapWithNext(); return {}; } @@ -3298,16 +3121,18 @@ SDispatchResult CKeybindManager::setProp(std::string args) { if (PWINDOW->m_ruleApplicator->noFocus().valueOrDefault() != noFocus) { // FIXME: what the fuck is going on here? -vax - Desktop::focusState()->rawWindowFocus(nullptr); - Desktop::focusState()->fullWindowFocus(PWINDOW); - Desktop::focusState()->fullWindowFocus(PLASTWINDOW); + Desktop::focusState()->rawWindowFocus(nullptr, Desktop::FOCUS_REASON_KEYBIND); + Desktop::focusState()->fullWindowFocus(PWINDOW, Desktop::FOCUS_REASON_KEYBIND); + Desktop::focusState()->fullWindowFocus(PLASTWINDOW, Desktop::FOCUS_REASON_KEYBIND); } if (PROP == "no_vrr") g_pConfigManager->ensureVRR(PWINDOW->m_monitor.lock()); - for (auto const& m : g_pCompositor->m_monitors) - g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->m_id); + for (auto const& m : g_pCompositor->m_monitors) { + if (m->m_activeWorkspace) + m->m_activeWorkspace->m_space->recalculate(); + } return {}; } -- cgit v1.2.3