diff options
| author | Alexander <51529891+Truenya@users.noreply.github.com> | 2025-02-03 04:34:30 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-03 02:34:30 +0100 |
| commit | 708d16636047c6a311c4e44424cf7d2090219a47 (patch) | |
| tree | ac363d6ab464b90afdff3b44a2a85d6c8b00f420 /src/Compositor.cpp | |
| parent | 44004abc0189b9ba49444431e2a39d2df7e930bb (diff) | |
dispatchers: add cyclenext hist option (#9055)
Diffstat (limited to 'src/Compositor.cpp')
| -rw-r--r-- | src/Compositor.cpp | 79 |
1 files changed, 47 insertions, 32 deletions
diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 0aa0f13d..95a57e03 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1058,7 +1058,7 @@ PHLMONITOR CCompositor::getRealMonitorFromOutput(SP<Aquamarine::IOutput> out) { return nullptr; } -void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface) { +void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface, bool preserveFocusHistory) { static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse"); static auto PSPECIALFALLTHROUGH = CConfigValue<Hyprlang::INT>("input:special_fallthrough"); @@ -1178,12 +1178,13 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> 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) @@ -1396,7 +1397,6 @@ void CCompositor::changeWindowZOrder(PHLWINDOW pWindow, bool top) { }; x11Stack(pWindow, top, x11Stack); - for (const auto& it : toMove) { moveToZ(it, top); } @@ -1647,37 +1647,52 @@ PHLWINDOW CCompositor::getWindowInDirection(const CBox& box, PHLWORKSPACE pWorks return nullptr; } -PHLWINDOW CCompositor::getNextWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional<bool> 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 <typename WINDOWPTR> +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<bool> 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 <typename WINDOWPTR> +static bool isFloatingMatches(WINDOWPTR w, std::optional<bool> 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 <typename WINDOWPTR> +static bool isWindowAvailableForCycle(WINDOWPTR pWindow, WINDOWPTR w, bool focusableOnly, std::optional<bool> 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<bool> floating) { - return !floating.has_value() || w->m_bIsFloating == floating.value(); -}; +template <typename Iterator> +static PHLWINDOW getWindowPred(Iterator cur, Iterator end, Iterator begin, const std::function<bool(const PHLWINDOW&)> 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; +} + +template <typename Iterator> +static PHLWINDOW getWeakWindowPred(Iterator cur, Iterator end, Iterator begin, const std::function<bool(const PHLWINDOWREF&)> 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<bool> 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); +} -bool CCompositor::isWindowAvailableForCycle(PHLWINDOW pWindow, const PHLWINDOW w, bool focusableOnly, std::optional<bool> floating, bool anyWorkspace) { - return isFloatingMatches(w, floating) && w != pWindow && isWorkspaceMatches(pWindow, w, anyWorkspace) && w->m_bIsMapped && !w->isHidden() && - (!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault()); +PHLWINDOW CCompositor::getWindowCycle(PHLWINDOW cur, bool focusableOnly, std::optional<bool> 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() { |
