diff --git a/src/Compositor.cpp b/src/Compositor.cpp index f5f1d1f9574..e022f71870a 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -13,7 +13,6 @@ #include "managers/VersionKeeperManager.hpp" #include "managers/DonationNagManager.hpp" #include "managers/eventLoop/EventLoopManager.hpp" -#include #include #include #include @@ -21,13 +20,13 @@ #include #include #include -#include #include #include "debug/HyprCtl.hpp" #include "debug/CrashReporter.hpp" #ifdef USES_SYSTEMD #include // for SdNotify #endif +#include #include "helpers/varlist/VarList.hpp" #include "helpers/fs/FsUtils.hpp" #include "protocols/FractionalScale.hpp" @@ -44,7 +43,6 @@ #include "xwayland/XWayland.hpp" #include "helpers/ByteOperations.hpp" #include "render/decorations/CHyprGroupBarDecoration.hpp" - #include "managers/KeybindManager.hpp" #include "managers/SessionLockManager.hpp" #include "managers/XWaylandManager.hpp" @@ -1640,32 +1638,26 @@ 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; -} - -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; -} - -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; -} +PHLWINDOW CCompositor::getWindowCycleHist(PHLWINDOWREF cur, bool focusableOnly, std::optional floating, bool visible, bool prev) { + if (prev) { + auto it = std::ranges::find(std::ranges::reverse_view(m_vWindowFocusHistory), cur); + const auto FINDER = [&](const PHLWINDOWREF& w) { return isWindowAvailableForCycle(cur, w, focusableOnly, floating, visible); }; + return getWindowPred(it, m_vWindowFocusHistory.rend(), m_vWindowFocusHistory.rbegin(), FINDER); + } + auto it = std::ranges::find(m_vWindowFocusHistory, cur); + const auto FINDER = [&](const PHLWINDOWREF& w) { return isWindowAvailableForCycle(cur, w, focusableOnly, floating, visible); }; + return getWindowPred(it, m_vWindowFocusHistory.end(), m_vWindowFocusHistory.begin(), FINDER); +}; -inline static bool isFloatingMatches(PHLWINDOW w, std::optional floating) { - return !floating.has_value() || w->m_bIsFloating == floating.value(); +PHLWINDOW CCompositor::getWindowCycle(PHLWINDOW cur, bool focusableOnly, std::optional floating, bool visible, bool prev) { + if (prev) { + auto it = std::ranges::find(std::ranges::reverse_view(m_vWindows), cur); + const auto FINDER = [&](const PHLWINDOW& w) { return isWindowAvailableForCycle(cur, w, focusableOnly, floating, visible); }; + return getWindowPred(it, m_vWindows.rend(), m_vWindows.rbegin(), FINDER); + } + auto it = std::ranges::find(m_vWindows, cur); + const auto FINDER = [&](const PHLWINDOW& w) { return isWindowAvailableForCycle(cur, w, focusableOnly, floating, visible); }; + return getWindowPred(it, m_vWindows.end(), m_vWindows.begin(), FINDER); }; bool CCompositor::isWindowAvailableForCycle(PHLWINDOW pWindow, const PHLWINDOW w, bool focusableOnly, std::optional floating, bool anyWorkspace) { @@ -2757,6 +2749,7 @@ void CCompositor::arrangeMonitors() { std::vector toArrange(m_vMonitors.begin(), m_vMonitors.end()); std::vector arranged; + arranged.reserve(toArrange.size()); Debug::log(LOG, "arrangeMonitors: {} to arrange", toArrange.size()); diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 0a87ec3345f..3e75683bfc5 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -1,7 +1,9 @@ #pragma once +#include #include #include +#include #include #include "defines.hpp" @@ -106,8 +108,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 prev = false); WORKSPACEID getNextAvailableNamedWorkspace(); bool isPointOnAnyMonitor(const Vector2D&); bool isPointOnReservedArea(const Vector2D& point, const PHLMONITOR monitor = nullptr); @@ -150,20 +152,42 @@ class CCompositor { void setPreferredTransformForSurface(SP pSurface, wl_output_transform transform); void updateSuspendedStates(); void onNewMonitor(SP output); - SImageDescription getPreferredImageDescription(); bool shouldChangePreferredImageDescription(); - std::string explicitConfigPath; + template + 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; + }; + private: - void initAllSignals(); - void removeAllSignals(); - void cleanEnvironment(); - void setRandomSplash(); - void initManagers(eManagersInitStage stage); - void prepareFallbackOutput(); - bool isWindowAvailableForCycle(PHLWINDOW pWindow, PHLWINDOW w, bool focusableOnly, std::optional floating, bool anyWorkspace = false); + void initAllSignals(); + void removeAllSignals(); + void cleanEnvironment(); + void setRandomSplash(); + void initManagers(eManagersInitStage stage); + void prepareFallbackOutput(); + + 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; + }; + + template + static bool isFloatingMatches(WINDOWPTR w, std::optional floating) { + return !floating.has_value() || w->m_bIsFloating == floating.value(); + }; + + template + 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())); + }; uint64_t m_iHyprlandPID = 0; wl_event_source* m_critSigSource = nullptr;