diff --git a/src/Compositor.cpp b/src/Compositor.cpp index cd0c7c61..f5f1d1f9 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -2,6 +2,7 @@ #include "Compositor.hpp" #include "debug/Log.hpp" +#include "desktop/DesktopTypes.hpp" #include "helpers/Splashes.hpp" #include "config/ConfigValue.hpp" #include "config/ConfigWatcher.hpp" @@ -12,6 +13,7 @@ #include "managers/VersionKeeperManager.hpp" #include "managers/DonationNagManager.hpp" #include "managers/eventLoop/EventLoopManager.hpp" +#include #include #include #include @@ -19,13 +21,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" @@ -1638,62 +1640,37 @@ PHLWINDOW CCompositor::getWindowInDirection(const CBox& box, PHLWORKSPACE pWorks return nullptr; } -PHLWINDOW CCompositor::getNextWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional floating) { - bool gotToWindow = false; - for (auto const& w : m_vWindows) { - if (w != pWindow && !gotToWindow) - continue; - - if (w == pWindow) { - gotToWindow = true; - continue; - } - - if (floating.has_value() && w->m_bIsFloating != floating.value()) - continue; - - if (w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault())) - return w; - } - - for (auto const& w : m_vWindows) { - if (floating.has_value() && w->m_bIsFloating != floating.value()) - continue; - - if (w != pWindow && w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault())) - return w; - } - - 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 gotToWindow = false; - for (auto const& w : m_vWindows | std::views::reverse) { - if (w != pWindow && !gotToWindow) - continue; +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; +} - if (w == pWindow) { - gotToWindow = true; - continue; - } +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; +} - if (floating.has_value() && w->m_bIsFloating != floating.value()) - continue; +inline static bool isFloatingMatches(PHLWINDOW w, std::optional floating) { + return !floating.has_value() || w->m_bIsFloating == floating.value(); +}; - if (w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault())) - return w; - } - - for (auto const& w : m_vWindows | std::views::reverse) { - if (floating.has_value() && w->m_bIsFloating != floating.value()) - continue; - - if (w != pWindow && w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault())) - return w; - } - - return nullptr; +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()); } WORKSPACEID CCompositor::getNextAvailableNamedWorkspace() { @@ -1728,12 +1705,8 @@ PHLWORKSPACE CCompositor::getWorkspaceByString(const std::string& str) { } bool CCompositor::isPointOnAnyMonitor(const Vector2D& point) { - for (auto const& m : m_vMonitors) { - if (VECINRECT(point, m->vecPosition.x, m->vecPosition.y, m->vecSize.x + m->vecPosition.x, m->vecSize.y + m->vecPosition.y)) - return true; - } - - return false; + return std::ranges::any_of( + m_vMonitors, [&](const PHLMONITOR& m) { return VECINRECT(point, m->vecPosition.x, m->vecPosition.y, m->vecSize.x + m->vecPosition.x, m->vecSize.y + m->vecPosition.y); }); } bool CCompositor::isPointOnReservedArea(const Vector2D& point, const PHLMONITOR pMonitor) { diff --git a/src/Compositor.hpp b/src/Compositor.hpp index ebcca5d0..0a87ec33 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -106,8 +106,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 = {}); - PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {}); + PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {}, bool visible = false); + PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {}, bool visible = false); WORKSPACEID getNextAvailableNamedWorkspace(); bool isPointOnAnyMonitor(const Vector2D&); bool isPointOnReservedArea(const Vector2D& point, const PHLMONITOR monitor = nullptr); @@ -163,6 +163,7 @@ 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; diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 65891840..0816de2a 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -750,7 +750,7 @@ SDispatchResult CKeybindManager::handleKeybinds(const uint32_t modmask, const SP Debug::log(ERR, "Invalid handler in a keybind! (handler {} does not exist)", k->handler); } else { // call the dispatcher - Debug::log(LOG, "Keybind triggered, calling dispatcher ({}, {}, {})", modmask, key.keyName, key.keysym); + Debug::log(LOG, "Keybind triggered, calling dispatcher ({}, {}, {}, {})", modmask, key.keyName, key.keysym, DISPATCHER->first); m_iPassPressed = (int)pressed; @@ -2201,7 +2201,6 @@ SDispatchResult CKeybindManager::resizeWindow(std::string args) { } SDispatchResult CKeybindManager::circleNext(std::string arg) { - if (g_pCompositor->m_pLastWindow.expired()) { // if we have a clear focus, find the first window and get the next focusable. const auto PWS = g_pCompositor->m_pLastMonitor->activeWorkspace; @@ -2221,10 +2220,12 @@ SDispatchResult CKeybindManager::circleNext(std::string arg) { else if (args.contains("float") || args.contains("floating")) floatStatus = true; - if (args.contains("prev") || args.contains("p") || args.contains("last") || args.contains("l")) - switchToWindow(g_pCompositor->getPrevWindowOnWorkspace(g_pCompositor->m_pLastWindow.lock(), true, floatStatus)); - else - switchToWindow(g_pCompositor->getNextWindowOnWorkspace(g_pCompositor->m_pLastWindow.lock(), true, floatStatus)); + 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); + + switchToWindow(w); return {}; }