From 2558af6c41df8d7cc1da1302b99312d4e07b6189 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D1=80=D1=8B=D0=BB=D0=BE=D0=B2=20=D0=90=D0=BB=D0=B5?= =?UTF-8?q?=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80?= Date: Wed, 22 Jan 2025 10:16:11 +0300 Subject: [PATCH] feat: cyclenext hist option --- src/Compositor.cpp | 170 ++++++++++++++++---------------- src/Compositor.hpp | 12 +-- src/macros.hpp | 3 +- src/managers/KeybindManager.cpp | 34 +++---- src/managers/KeybindManager.hpp | 2 +- 5 files changed, 106 insertions(+), 115 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 3421c314620..d495783f64f 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -22,14 +22,12 @@ #include #include #include -#include #include #include "debug/HyprCtl.hpp" #include "debug/CrashReporter.hpp" #ifdef USES_SYSTEMD #include // for SdNotify #endif -#include "helpers/varlist/VarList.hpp" #include "helpers/fs/FsUtils.hpp" #include "protocols/FractionalScale.hpp" #include "protocols/PointerConstraints.hpp" @@ -166,9 +164,7 @@ void CCompositor::restoreNofile() { CCompositor::CCompositor(bool onlyConfig) : m_bOnlyConfigVerification(onlyConfig), m_iHyprlandPID(getpid()) { if (onlyConfig) return; - m_szHyprTempDataRoot = std::string{getenv("XDG_RUNTIME_DIR")} + "/hypr"; - if (m_szHyprTempDataRoot.starts_with("/hypr")) { std::println("Bailing out, $XDG_RUNTIME_DIR is invalid"); throw std::runtime_error("CCompositor() failed"); @@ -265,7 +261,6 @@ static bool filterGlobals(const wl_client* client, const wl_global* global, void // void CCompositor::initServer(std::string socketName, int socketFd) { - if (m_bOnlyConfigVerification) { g_pHookSystem = makeUnique(); g_pKeybindManager = makeUnique(); @@ -501,7 +496,7 @@ void CCompositor::cleanEnvironment() { "dbus-update-activation-environment 2>/dev/null && " #endif "dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP HYPRLAND_INSTANCE_SIGNATURE QT_QPA_PLATFORMTHEME PATH XDG_DATA_DIRS"; - g_pKeybindManager->spawn(CMD); + CKeybindManager::spawn(CMD); } } @@ -739,7 +734,7 @@ void CCompositor::startCompositor() { "dbus-update-activation-environment 2>/dev/null && " #endif "dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP HYPRLAND_INSTANCE_SIGNATURE QT_QPA_PLATFORMTHEME PATH XDG_DATA_DIRS"; - g_pKeybindManager->spawn(CMD); + CKeybindManager::spawn(CMD); } Debug::log(LOG, "Running on WAYLAND_DISPLAY: {}", m_szWLDisplaySocket); @@ -840,12 +835,7 @@ void CCompositor::removeWindowFromVectorSafe(PHLWINDOW pWindow) { } bool CCompositor::monitorExists(PHLMONITOR pMonitor) { - for (auto const& m : m_vRealMonitors) { - if (m == pMonitor) - return true; - } - - return false; + return std::ranges::any_of(m_vRealMonitors, [&](const PHLMONITOR& m) { return m == pMonitor; }); } PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t properties, PHLWINDOW pIgnoreWindow) { @@ -1065,7 +1055,7 @@ PHLMONITOR CCompositor::getRealMonitorFromOutput(SP out) { return nullptr; } -void CCompositor::focusWindow(PHLWINDOW pWindow, SP pSurface) { +void CCompositor::focusWindow(PHLWINDOW pWindow, SP pSurface, bool preserveFocusHistory) { static auto PFOLLOWMOUSE = CConfigValue("input:follow_mouse"); static auto PSPECIALFALLTHROUGH = CConfigValue("input:special_fallthrough"); @@ -1101,8 +1091,8 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP pSurface g_pSeatManager->setKeyboardFocus(nullptr); - g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","}); - g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", ""}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindow", .data = ","}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindowv2", .data = ""}); EMIT_HOOK_EVENT("activeWindow", (PHLWINDOW) nullptr); @@ -1176,8 +1166,8 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP pSurface pWindow->m_bIsUrgent = false; // Send an event - g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", pWindow->m_szClass + "," + pWindow->m_szTitle}); - g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", std::format("{:x}", (uintptr_t)pWindow.get())}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindow", .data = pWindow->m_szClass + "," + pWindow->m_szTitle}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindowv2", .data = std::format("{:x}", (uintptr_t)pWindow.get())}); EMIT_HOOK_EVENT("activeWindow", pWindow); @@ -1185,12 +1175,14 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP pSurface g_pInputManager->recheckIdleInhibitorStatus(); - // move to front of the window history - const auto HISTORYPIVOT = std::find_if(m_vWindowFocusHistory.begin(), m_vWindowFocusHistory.end(), [&](const auto& other) { return other.lock() == pWindow; }); - if (HISTORYPIVOT == m_vWindowFocusHistory.end()) { - Debug::log(ERR, "BUG THIS: {} has no pivot in history", pWindow); - } else { - std::rotate(m_vWindowFocusHistory.begin(), HISTORYPIVOT, HISTORYPIVOT + 1); + if (!preserveFocusHistory) { + // move to front of the window history + const auto HISTORYPIVOT = std::ranges::find_if(m_vWindowFocusHistory, [&](const auto& other) { return other.lock() == pWindow; }); + if (HISTORYPIVOT == m_vWindowFocusHistory.end()) { + Debug::log(ERR, "BUG THIS: {} has no pivot in history", pWindow); + } else { + std::rotate(m_vWindowFocusHistory.begin(), HISTORYPIVOT, HISTORYPIVOT + 1); + } } if (*PFOLLOWMOUSE == 0) @@ -1218,8 +1210,8 @@ void CCompositor::focusSurface(SP pSurface, PHLWINDOW pWindo if (!pSurface) { g_pSeatManager->setKeyboardFocus(nullptr); - g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","}); // unfocused - g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", ""}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindow", .data = ","}); // unfocused + g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindowv2", .data = ""}); EMIT_HOOK_EVENT("keyboardFocus", (SP)nullptr); m_pLastFocus.reset(); return; @@ -1396,7 +1388,7 @@ void CCompositor::changeWindowZOrder(PHLWINDOW pWindow, bool top) { toMove.insert(toMove.begin(), pw); for (auto const& w : m_vWindows) { - if (w->m_bIsMapped && !w->isHidden() && w->m_bIsX11 && w->x11TransientFor() == pw && w != pw && std::find(toMove.begin(), toMove.end(), w) == toMove.end()) { + if (w->m_bIsMapped && !w->isHidden() && w->m_bIsX11 && w->x11TransientFor() == pw && w != pw && std::ranges::find(toMove, w) == toMove.end()) { x11Stack(w, top, x11Stack); } } @@ -1455,7 +1447,7 @@ void CCompositor::cleanupFadingOut(const MONITORID& monid) { if (ls->fadingOut && ls->readyToDelete && ls->isFadedOut()) { for (auto const& m : m_vMonitors) { for (auto& lsl : m->m_aLayerSurfaceLayers) { - if (!lsl.empty() && std::find_if(lsl.begin(), lsl.end(), [&](auto& other) { return other == ls; }) != lsl.end()) { + if (!lsl.empty() && std::ranges::find_if(lsl, [&](auto& other) { return other == ls; }) != lsl.end()) { std::erase_if(lsl, [&](auto& other) { return other == ls || !other; }); } } @@ -1478,7 +1470,7 @@ void CCompositor::cleanupFadingOut(const MONITORID& monid) { } void CCompositor::addToFadingOutSafe(PHLLS pLS) { - const auto FOUND = std::find_if(m_vSurfacesFadingOut.begin(), m_vSurfacesFadingOut.end(), [&](auto& other) { return other.lock() == pLS; }); + const auto FOUND = std::ranges::find_if(m_vSurfacesFadingOut, [&](auto& other) { return other.lock() == pLS; }); if (FOUND != m_vSurfacesFadingOut.end()) return; // if it's already added, don't add it. @@ -1491,7 +1483,7 @@ void CCompositor::removeFromFadingOutSafe(PHLLS ls) { } void CCompositor::addToFadingOutSafe(PHLWINDOW pWindow) { - const auto FOUND = std::find_if(m_vWindowsFadingOut.begin(), m_vWindowsFadingOut.end(), [&](PHLWINDOWREF& other) { return other.lock() == pWindow; }); + const auto FOUND = std::ranges::find_if(m_vWindowsFadingOut, [&](PHLWINDOWREF& other) { return other.lock() == pWindow; }); if (FOUND != m_vWindowsFadingOut.end()) return; // if it's already added, don't add it. @@ -1610,7 +1602,7 @@ PHLWINDOW CCompositor::getWindowInDirection(const CBox& box, PHLWORKSPACE pWorks // auto vectorAngles = [](const Vector2D& a, const Vector2D& b) -> double { - double dot = a.x * b.x + a.y * b.y; + double dot = (a.x * b.x) + (a.y * b.y); double ang = std::acos(dot / (a.size() * b.size())); return ang; }; @@ -1654,37 +1646,52 @@ PHLWINDOW CCompositor::getWindowInDirection(const CBox& box, PHLWORKSPACE pWorks return nullptr; } -PHLWINDOW CCompositor::getNextWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional floating, bool visible) { - auto it = std::ranges::find(m_vWindows, pWindow); - const auto FINDER = [&](const PHLWINDOW& w) { return isWindowAvailableForCycle(pWindow, w, focusableOnly, floating, visible); }; - const auto IN_RIGHT = std::find_if(it, m_vWindows.end(), FINDER); - if (IN_RIGHT != m_vWindows.end()) - return *IN_RIGHT; - const auto IN_LEFT = std::find_if(m_vWindows.begin(), it, FINDER); - return *IN_LEFT; +template +static bool isWorkspaceMatches(WINDOWPTR pWindow, const WINDOWPTR w, bool anyWorkspace) { + return anyWorkspace ? w->m_pWorkspace && w->m_pWorkspace->isVisible() : w->m_pWorkspace == pWindow->m_pWorkspace; } -PHLWINDOW CCompositor::getPrevWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional floating, bool visible) { - auto it = std::ranges::find(std::ranges::reverse_view(m_vWindows), pWindow); - const auto FINDER = [&](const PHLWINDOW& w) { return isWindowAvailableForCycle(pWindow, w, focusableOnly, floating, visible); }; - const auto IN_LEFT = std::find_if(it, m_vWindows.rend(), FINDER); - if (IN_LEFT != m_vWindows.rend()) - return *IN_LEFT; - const auto IN_RIGHT = std::find_if(m_vWindows.rbegin(), it, FINDER); - return *IN_RIGHT; +template +static bool isFloatingMatches(WINDOWPTR w, std::optional floating) { + return !floating.has_value() || w->m_bIsFloating == floating.value(); } -inline static bool isWorkspaceMatches(PHLWINDOW pWindow, const PHLWINDOW w, bool anyWorkspace) { - return anyWorkspace ? w->m_pWorkspace && w->m_pWorkspace->isVisible() : w->m_pWorkspace == pWindow->m_pWorkspace; +template +static bool isWindowAvailableForCycle(WINDOWPTR pWindow, WINDOWPTR w, bool focusableOnly, std::optional floating, bool anyWorkspace = false) { + return isFloatingMatches(w, floating) && + (w != pWindow && isWorkspaceMatches(pWindow, w, anyWorkspace) && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault())); } -inline static bool isFloatingMatches(PHLWINDOW w, std::optional floating) { - return !floating.has_value() || w->m_bIsFloating == floating.value(); -}; +template +static PHLWINDOW getWindowPred(Iterator cur, Iterator end, Iterator begin, const std::function PRED) { + const auto IN_ONE_SIDE = std::find_if(cur, end, PRED); + if (IN_ONE_SIDE != end) + return *IN_ONE_SIDE; + const auto IN_OTHER_SIDE = std::find_if(begin, cur, PRED); + return *IN_OTHER_SIDE; +} -bool CCompositor::isWindowAvailableForCycle(PHLWINDOW pWindow, const PHLWINDOW w, bool focusableOnly, std::optional floating, bool anyWorkspace) { - return isFloatingMatches(w, floating) && w != pWindow && isWorkspaceMatches(pWindow, w, anyWorkspace) && w->m_bIsMapped && !w->isHidden() && - (!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault()); +template +static PHLWINDOW getWeakWindowPred(Iterator cur, Iterator end, Iterator begin, const std::function PRED) { + const auto IN_ONE_SIDE = std::find_if(cur, end, PRED); + if (IN_ONE_SIDE != end) + return IN_ONE_SIDE->lock(); + const auto IN_OTHER_SIDE = std::find_if(begin, cur, PRED); + return IN_OTHER_SIDE->lock(); +} + +PHLWINDOW CCompositor::getWindowCycleHist(PHLWINDOWREF cur, bool focusableOnly, std::optional floating, bool visible, bool next) { + const auto FINDER = [&](const PHLWINDOWREF& w) { return isWindowAvailableForCycle(cur, w, focusableOnly, floating, visible); }; + // also m_vWindowFocusHistory has reverse order, so when it is next - we need to reverse again + return next ? + getWeakWindowPred(std::ranges::find(std::ranges::reverse_view(m_vWindowFocusHistory), cur), m_vWindowFocusHistory.rend(), m_vWindowFocusHistory.rbegin(), FINDER) : + getWeakWindowPred(std::ranges::find(m_vWindowFocusHistory, cur), m_vWindowFocusHistory.end(), m_vWindowFocusHistory.begin(), FINDER); +} + +PHLWINDOW CCompositor::getWindowCycle(PHLWINDOW cur, bool focusableOnly, std::optional floating, bool visible, bool prev) { + const auto FINDER = [&](const PHLWINDOW& w) { return isWindowAvailableForCycle(cur, w, focusableOnly, floating, visible); }; + return prev ? getWindowPred(std::ranges::find(std::ranges::reverse_view(m_vWindows), cur), m_vWindows.rend(), m_vWindows.rbegin(), FINDER) : + getWindowPred(std::ranges::find(m_vWindows, cur), m_vWindows.end(), m_vWindows.begin(), FINDER); } WORKSPACEID CCompositor::getNextAvailableNamedWorkspace() { @@ -1729,7 +1736,7 @@ bool CCompositor::isPointOnReservedArea(const Vector2D& point, const PHLMONITOR const auto XY1 = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft; const auto XY2 = PMONITOR->vecPosition + PMONITOR->vecSize - PMONITOR->vecReservedBottomRight; - return !VECINRECT(point, XY1.x, XY1.y, XY2.x, XY2.y); + return VECNOTINRECT(point, XY1.x, XY1.y, XY2.x, XY2.y); } PHLMONITOR CCompositor::getMonitorInDirection(const char& dir) { @@ -1903,7 +1910,7 @@ void CCompositor::updateWindowAnimatedDecorationValues(PHLWINDOW pWindow) { MONITORID CCompositor::getNextAvailableMonitorID(std::string const& name) { // reuse ID if it's already in the map, and the monitor with that ID is not being used by another monitor - if (m_mMonitorIDMap.contains(name) && !std::any_of(m_vRealMonitors.begin(), m_vRealMonitors.end(), [&](auto m) { return m->ID == m_mMonitorIDMap[name]; })) + if (m_mMonitorIDMap.contains(name) && !std::ranges::any_of(m_vRealMonitors, [&](auto m) { return m->ID == m_mMonitorIDMap[name]; })) return m_mMonitorIDMap[name]; // otherwise, find minimum available ID that is not in the map @@ -1913,7 +1920,7 @@ MONITORID CCompositor::getNextAvailableMonitorID(std::string const& name) { } MONITORID nextID = 0; - while (usedIDs.count(nextID) > 0) { + while (usedIDs.contains(nextID)) { nextID++; } m_mMonitorIDMap[name] = nextID; @@ -1993,17 +2000,17 @@ void CCompositor::swapActiveWorkspaces(PHLMONITOR pMonitorA, PHLMONITOR pMonitor (g_pCompositor->vectorToWindowUnified(g_pInputManager->getMouseCoordsInternal(), RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING))); const auto PNEWWORKSPACE = pMonitorA->ID == g_pCompositor->m_pLastMonitor->ID ? PWORKSPACEB : PWORKSPACEA; - g_pEventManager->postEvent(SHyprIPCEvent{"workspace", PNEWWORKSPACE->m_szName}); - g_pEventManager->postEvent(SHyprIPCEvent{"workspacev2", std::format("{},{}", PNEWWORKSPACE->m_iID, PNEWWORKSPACE->m_szName)}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "workspace", .data = PNEWWORKSPACE->m_szName}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "workspacev2", .data = std::format("{},{}", PNEWWORKSPACE->m_iID, PNEWWORKSPACE->m_szName)}); EMIT_HOOK_EVENT("workspace", PNEWWORKSPACE); } // event - g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspace", PWORKSPACEA->m_szName + "," + pMonitorB->szName}); - g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspacev2", std::format("{},{},{}", PWORKSPACEA->m_iID, PWORKSPACEA->m_szName, pMonitorB->szName)}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "moveworkspace", .data = PWORKSPACEA->m_szName + "," + pMonitorB->szName}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "moveworkspacev2", .data = std::format("{},{},{}", PWORKSPACEA->m_iID, PWORKSPACEA->m_szName, pMonitorB->szName)}); EMIT_HOOK_EVENT("moveWorkspace", (std::vector{PWORKSPACEA, pMonitorB})); - g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspace", PWORKSPACEB->m_szName + "," + pMonitorA->szName}); - g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspacev2", std::format("{},{},{}", PWORKSPACEB->m_iID, PWORKSPACEB->m_szName, pMonitorA->szName)}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "moveworkspace", .data = PWORKSPACEB->m_szName + "," + pMonitorA->szName}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "moveworkspacev2", .data = std::format("{},{},{}", PWORKSPACEB->m_iID, PWORKSPACEB->m_szName, pMonitorA->szName)}); EMIT_HOOK_EVENT("moveWorkspace", (std::vector{PWORKSPACEB, pMonitorA})); } @@ -2189,8 +2196,8 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, PHLMONITOR pMo updateSuspendedStates(); // event - g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspace", pWorkspace->m_szName + "," + pMonitor->szName}); - g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspacev2", std::format("{},{},{}", pWorkspace->m_iID, pWorkspace->m_szName, pMonitor->szName)}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "moveworkspace", .data = pWorkspace->m_szName + "," + pMonitor->szName}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "moveworkspacev2", .data = std::format("{},{},{}", pWorkspace->m_iID, pWorkspace->m_szName, pMonitor->szName)}); EMIT_HOOK_EVENT("moveWorkspace", (std::vector{pWorkspace, pMonitor})); } @@ -2202,11 +2209,8 @@ bool CCompositor::workspaceIDOutOfBounds(const WORKSPACEID& id) { if (w->m_bIsSpecialWorkspace) continue; - if (w->m_iID < lowestID) - lowestID = w->m_iID; - - if (w->m_iID > highestID) - highestID = w->m_iID; + lowestID = std::min(w->m_iID, lowestID); + highestID = std::max(w->m_iID, highestID); } return std::clamp(id, lowestID, highestID) != id; @@ -2282,7 +2286,7 @@ void CCompositor::setWindowFullscreenState(const PHLWINDOW PWINDOW, SFullscreenS if (PWORKSPACE->m_bHasFullscreenWindow && !PWINDOW->isFullscreen()) setWindowFullscreenInternal(PWORKSPACE->getFullscreenWindow(), FSMODE_NONE); - const bool CHANGEINTERNAL = !(PWINDOW->m_bPinned || CURRENT_EFFECTIVE_MODE == EFFECTIVE_MODE); + const bool CHANGEINTERNAL = !PWINDOW->m_bPinned && CURRENT_EFFECTIVE_MODE != EFFECTIVE_MODE; if (*PALLOWPINFULLSCREEN && PWINDOW->m_bPinFullscreened && PWINDOW->isFullscreen() && !PWINDOW->m_bPinned && state.internal == FSMODE_NONE) { PWINDOW->m_bPinned = true; @@ -2309,7 +2313,7 @@ void CCompositor::setWindowFullscreenState(const PHLWINDOW PWINDOW, SFullscreenS PWORKSPACE->m_efFullscreenMode = EFFECTIVE_MODE; PWORKSPACE->m_bHasFullscreenWindow = EFFECTIVE_MODE != FSMODE_NONE; - g_pEventManager->postEvent(SHyprIPCEvent{"fullscreen", std::to_string((int)EFFECTIVE_MODE != FSMODE_NONE)}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "fullscreen", .data = std::to_string((int)EFFECTIVE_MODE != FSMODE_NONE)}); EMIT_HOOK_EVENT("fullscreen", PWINDOW); PWINDOW->updateDynamicRules(); @@ -2576,8 +2580,8 @@ Vector2D CCompositor::parseWindowVectorArgsRelative(const std::string& args, con X = xIsPercent ? std::stof(x) * 0.01 * PMONITOR->vecSize.x : std::stoi(x); Y = yIsPercent ? std::stof(y) * 0.01 * PMONITOR->vecSize.y : std::stoi(y); } else { - X = xIsPercent ? std::stof(x) * 0.01 * relativeTo.x + relativeTo.x : std::stoi(x) + relativeTo.x; - Y = yIsPercent ? std::stof(y) * 0.01 * relativeTo.y + relativeTo.y : std::stoi(y) + relativeTo.y; + X = xIsPercent ? (std::stof(x) * 0.01 * relativeTo.x) + relativeTo.x : std::stoi(x) + relativeTo.x; + Y = yIsPercent ? (std::stof(y) * 0.01 * relativeTo.y) + relativeTo.y : std::stoi(y) + relativeTo.y; } return Vector2D(X, Y); @@ -2614,8 +2618,8 @@ void CCompositor::setActiveMonitor(PHLMONITOR pMonitor) { const auto WORKSPACE_ID = PWORKSPACE ? std::to_string(PWORKSPACE->m_iID) : std::to_string(WORKSPACE_INVALID); const auto WORKSPACE_NAME = PWORKSPACE ? PWORKSPACE->m_szName : "?"; - g_pEventManager->postEvent(SHyprIPCEvent{"focusedmon", pMonitor->szName + "," + WORKSPACE_NAME}); - g_pEventManager->postEvent(SHyprIPCEvent{"focusedmonv2", pMonitor->szName + "," + WORKSPACE_ID}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "focusedmon", .data = pMonitor->szName + "," + WORKSPACE_NAME}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "focusedmonv2", .data = pMonitor->szName + "," + WORKSPACE_ID}); EMIT_HOOK_EVENT("focusedMon", pMonitor); m_pLastMonitor = pMonitor->self; @@ -2805,14 +2809,10 @@ void CCompositor::arrangeMonitors() { // Finds the max and min values of explicitely placed monitors. for (auto const& m : arranged) { - if (m->vecPosition.x + m->vecSize.x > maxXOffsetRight) - maxXOffsetRight = m->vecPosition.x + m->vecSize.x; - if (m->vecPosition.x < maxXOffsetLeft) - maxXOffsetLeft = m->vecPosition.x; - if (m->vecPosition.y + m->vecSize.y > maxYOffsetDown) - maxYOffsetDown = m->vecPosition.y + m->vecSize.y; - if (m->vecPosition.y < maxYOffsetUp) - maxYOffsetUp = m->vecPosition.y; + maxXOffsetRight = std::max(m->vecPosition.x + m->vecSize.x, maxXOffsetRight); + maxXOffsetLeft = std::min(m->vecPosition.x, maxXOffsetLeft); + maxYOffsetDown = std::max(m->vecPosition.y + m->vecSize.y, maxYOffsetDown); + maxYOffsetUp = std::min(m->vecPosition.y, maxYOffsetUp); } }; diff --git a/src/Compositor.hpp b/src/Compositor.hpp index e55d7e1e6cf..50fc190be58 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -1,15 +1,12 @@ #pragma once -#include #include -#include "defines.hpp" #include "managers/XWaylandManager.hpp" #include "managers/KeybindManager.hpp" #include "managers/SessionLockManager.hpp" #include "desktop/Window.hpp" #include "protocols/types/ColorManagement.hpp" -#include "helpers/memory/Memory.hpp" #include #include @@ -86,7 +83,7 @@ class CCompositor { PHLMONITOR getMonitorFromCursor(); PHLMONITOR getMonitorFromVector(const Vector2D&); void removeWindowFromVectorSafe(PHLWINDOW); - void focusWindow(PHLWINDOW, SP pSurface = nullptr); + void focusWindow(PHLWINDOW, SP pSurface = nullptr, bool preserveFocusHistory = false); void focusSurface(SP, PHLWINDOW pWindowOwner = nullptr); bool monitorExists(PHLMONITOR); PHLWINDOW vectorToWindowUnified(const Vector2D&, uint8_t properties, PHLWINDOW pIgnoreWindow = nullptr); @@ -108,8 +105,8 @@ class CCompositor { void cleanupFadingOut(const MONITORID& monid); PHLWINDOW getWindowInDirection(PHLWINDOW, char); PHLWINDOW getWindowInDirection(const CBox& box, PHLWORKSPACE pWorkspace, char dir, PHLWINDOW ignoreWindow = nullptr, bool useVectorAngles = false); - PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {}, bool visible = false); - PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {}, bool visible = false); + PHLWINDOW getWindowCycle(PHLWINDOW cur, bool focusableOnly = false, std::optional floating = std::nullopt, bool visible = false, bool prev = false); + PHLWINDOW getWindowCycleHist(PHLWINDOWREF cur, bool focusableOnly = false, std::optional floating = std::nullopt, bool visible = false, bool next = false); WORKSPACEID getNextAvailableNamedWorkspace(); bool isPointOnAnyMonitor(const Vector2D&); bool isPointOnReservedArea(const Vector2D& point, const PHLMONITOR monitor = nullptr); @@ -166,11 +163,10 @@ class CCompositor { void setRandomSplash(); void initManagers(eManagersInitStage stage); void prepareFallbackOutput(); - bool isWindowAvailableForCycle(PHLWINDOW pWindow, PHLWINDOW w, bool focusableOnly, std::optional floating, bool anyWorkspace = false); uint64_t m_iHyprlandPID = 0; wl_event_source* m_critSigSource = nullptr; - rlimit m_sOriginalNofile = {0}; + rlimit m_sOriginalNofile = {.rlim_cur = 0}; }; inline UP g_pCompositor; diff --git a/src/macros.hpp b/src/macros.hpp index 0a3be8bcc5e..a5176675a93 100644 --- a/src/macros.hpp +++ b/src/macros.hpp @@ -38,7 +38,8 @@ #define DYNLISTENER(name) CHyprWLListener hyprListener_##name #define DYNMULTILISTENER(name) wl_listener listen_##name -#define VECINRECT(vec, x1, y1, x2, y2) ((vec).x >= (x1) && (vec).x < (x2) && (vec).y >= (y1) && (vec).y < (y2)) +#define VECINRECT(vec, x1, y1, x2, y2) ((vec).x >= (x1) && (vec).x < (x2) && (vec).y >= (y1) && (vec).y < (y2)) +#define VECNOTINRECT(vec, x1, y1, x2, y2) ((vec).x < (x1) || (vec).x >= (x2) || (vec).y < (y1) || (vec).y >= (y2)) #define DELTALESSTHAN(a, b, delta) (abs((a) - (b)) < (delta)) diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 2cb77d217c3..36a88ec1e29 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -12,8 +12,6 @@ #include "TokenManager.hpp" #include "eventLoop/EventLoopManager.hpp" #include "debug/Log.hpp" -#include "helpers/varlist/VarList.hpp" -#include "../helpers/signal/Signal.hpp" #include "../managers/HookSystemManager.hpp" #include "../managers/input/InputManager.hpp" #include "../managers/LayoutManager.hpp" @@ -367,7 +365,7 @@ bool CKeybindManager::tryMoveFocusToMonitor(PHLMONITOR monitor) { return true; } -void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO) { +void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO, bool preserveFocusHistory) { static auto PFOLLOWMOUSE = CConfigValue("input:follow_mouse"); static auto PNOWARPS = CConfigValue("cursor:no_warps"); @@ -386,7 +384,7 @@ void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO) { if (!PWINDOWTOCHANGETO->m_bPinned) g_pCompositor->setWindowFullscreenInternal(PLASTWINDOW, FSMODE_NONE); - g_pCompositor->focusWindow(PWINDOWTOCHANGETO); + g_pCompositor->focusWindow(PWINDOWTOCHANGETO, nullptr, preserveFocusHistory); if (!PWINDOWTOCHANGETO->m_bPinned) g_pCompositor->setWindowFullscreenInternal(PWINDOWTOCHANGETO, MODE); @@ -396,7 +394,7 @@ void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO) { PWINDOWTOCHANGETO->m_vRealSize->warp(); } else { updateRelativeCursorCoords(); - g_pCompositor->focusWindow(PWINDOWTOCHANGETO); + g_pCompositor->focusWindow(PWINDOWTOCHANGETO, nullptr, preserveFocusHistory); PWINDOWTOCHANGETO->warpCursor(); // Move mouse focus to the new window if required by current follow_mouse and warp modes @@ -1480,7 +1478,7 @@ SDispatchResult CKeybindManager::moveFocusTo(std::string args) { } const auto PWINDOWTOCHANGETO = *PFULLCYCLE && PLASTWINDOW->isFullscreen() ? - (arg == 'd' || arg == 'b' || arg == 'r' ? g_pCompositor->getNextWindowOnWorkspace(PLASTWINDOW, true) : g_pCompositor->getPrevWindowOnWorkspace(PLASTWINDOW, true)) : + g_pCompositor->getWindowCycle(PLASTWINDOW, true, {}, false, arg != 'd' && arg != 'b' && arg != 'r') : g_pCompositor->getWindowInDirection(PLASTWINDOW, arg); // Prioritize focus change within groups if the window is a part of it. @@ -2228,11 +2226,13 @@ SDispatchResult CKeybindManager::circleNext(std::string arg) { floatStatus = true; const auto VISIBLE = args.contains("visible") || args.contains("v"); - const auto& w = (args.contains("prev") || args.contains("p") || args.contains("last") || args.contains("l")) ? - g_pCompositor->getPrevWindowOnWorkspace(g_pCompositor->m_pLastWindow.lock(), true, floatStatus, VISIBLE) : - g_pCompositor->getNextWindowOnWorkspace(g_pCompositor->m_pLastWindow.lock(), true, floatStatus, VISIBLE); + 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(g_pCompositor->m_pLastWindow, true, floatStatus, VISIBLE, NEXT) : + g_pCompositor->getWindowCycle(g_pCompositor->m_pLastWindow.lock(), true, floatStatus, VISIBLE, PREV); - switchToWindow(w); + switchToWindow(w, HIST); return {}; } @@ -2627,18 +2627,12 @@ SDispatchResult CKeybindManager::swapnext(std::string arg) { g_pCompositor->m_pLastWindow->m_pLastCycledWindow.lock() : nullptr; - if (arg == "last" || arg == "l" || arg == "prev" || arg == "p") - toSwap = g_pCompositor->getPrevWindowOnWorkspace(PLASTCYCLED ? PLASTCYCLED : PLASTWINDOW, true); - else - toSwap = g_pCompositor->getNextWindowOnWorkspace(PLASTCYCLED ? PLASTCYCLED : PLASTWINDOW, true); + const bool NEED_PREV = arg == "last" || arg == "l" || arg == "prev" || arg == "p"; + toSwap = g_pCompositor->getWindowCycle(PLASTCYCLED ? PLASTCYCLED : PLASTWINDOW, true, std::nullopt, false, NEED_PREV); // sometimes we may come back to ourselves. - if (toSwap == PLASTWINDOW) { - if (arg == "last" || arg == "l" || arg == "prev" || arg == "p") - toSwap = g_pCompositor->getPrevWindowOnWorkspace(PLASTWINDOW, true); - else - toSwap = g_pCompositor->getNextWindowOnWorkspace(PLASTWINDOW, true); - } + if (toSwap == PLASTWINDOW) + toSwap = g_pCompositor->getWindowCycle(PLASTWINDOW, true, std::nullopt, false, NEED_PREV); g_pLayoutManager->getCurrentLayout()->switchWindows(PLASTWINDOW, toSwap); diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp index 1848ca789f4..cea3e3cf783 100644 --- a/src/managers/KeybindManager.hpp +++ b/src/managers/KeybindManager.hpp @@ -148,7 +148,7 @@ class CKeybindManager { static bool tryMoveFocusToMonitor(PHLMONITOR monitor); static void moveWindowOutOfGroup(PHLWINDOW pWindow, const std::string& dir = ""); static void moveWindowIntoGroup(PHLWINDOW pWindow, PHLWINDOW pWindowInDirection); - static void switchToWindow(PHLWINDOW PWINDOWTOCHANGETO); + static void switchToWindow(PHLWINDOW PWINDOWTOCHANGETO, bool preserveFocusHistory = false); static uint64_t spawnRawProc(std::string, PHLWORKSPACE pInitialWorkspace); static uint64_t spawnWithRules(std::string, PHLWORKSPACE pInitialWorkspace);