Skip to content

Commit 4387c2e

Browse files
author
Крылов Александр
committed
HYP-6678 | feat: circle visible
1 parent b7f42a1 commit 4387c2e

File tree

4 files changed

+123
-65
lines changed

4 files changed

+123
-65
lines changed

src/Compositor.cpp

Lines changed: 65 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
#include "Compositor.hpp"
2+
#include "desktop/DesktopTypes.hpp"
23
#include "helpers/Splashes.hpp"
34
#include "config/ConfigValue.hpp"
45
#include "managers/CursorManager.hpp"
56
#include "managers/TokenManager.hpp"
67
#include "managers/PointerManager.hpp"
78
#include "managers/SeatManager.hpp"
89
#include "managers/eventLoop/EventLoopManager.hpp"
10+
#include <cstdint>
911
#include <random>
1012
#include <unordered_set>
1113
#include "debug/HyprCtl.hpp"
@@ -671,6 +673,30 @@ CMonitor* CCompositor::getMonitorFromVector(const Vector2D& point) {
671673
return mon.get();
672674
}
673675

676+
SP<CMonitor> CCompositor::getNextMonitor(uint64_t curID, bool reverse) {
677+
const auto LN = m_vMonitors.size();
678+
if (LN == 1) {
679+
return m_vMonitors[0];
680+
}
681+
682+
size_t curPos = LN + 1;
683+
for (size_t i = 0; i < LN; i++) {
684+
if (m_vMonitors[i]->ID == curID) {
685+
curPos = i;
686+
}
687+
}
688+
689+
if (curPos == LN && !reverse) {
690+
return m_vMonitors[0];
691+
}
692+
693+
if (curPos == 0 && reverse) {
694+
return m_vMonitors[LN - 1];
695+
}
696+
697+
return reverse ? m_vMonitors[curPos - 1] : m_vMonitors[curPos + 1];
698+
}
699+
674700
void CCompositor::removeWindowFromVectorSafe(PHLWINDOW pWindow) {
675701
if (!pWindow->m_bFadingOut) {
676702
EMIT_HOOK_EVENT("destroyWindow", pWindow);
@@ -1565,59 +1591,65 @@ PHLWINDOW CCompositor::getWindowInDirection(PHLWINDOW pWindow, char dir) {
15651591
return nullptr;
15661592
}
15671593

1568-
PHLWINDOW CCompositor::getNextWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional<bool> floating) {
1569-
bool gotToWindow = false;
1570-
for (auto& w : m_vWindows) {
1571-
if (w != pWindow && !gotToWindow)
1572-
continue;
1573-
1574-
if (w == pWindow) {
1575-
gotToWindow = true;
1576-
continue;
1577-
}
1578-
1579-
if (floating.has_value() && w->m_bIsFloating != floating.value())
1580-
continue;
1594+
bool isWindowMatch(PHLWINDOW pWindow, bool focusableOnly, std::optional<bool> floating, const PHLWINDOW& w) {
1595+
return (!floating.has_value() || w->m_bIsFloating == floating.value()) && w != pWindow && w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() &&
1596+
(!focusableOnly || !w->m_sAdditionalConfigData.noFocus);
1597+
}
15811598

1582-
if (w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sAdditionalConfigData.noFocus))
1599+
PHLWINDOW CCompositor::getNextWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional<bool> floating) {
1600+
for (const auto& w : m_vWindows) {
1601+
if (isWindowMatch(pWindow, focusableOnly, floating, w))
15831602
return w;
15841603
}
15851604

1586-
for (auto& w : m_vWindows) {
1587-
if (floating.has_value() && w->m_bIsFloating != floating.value())
1588-
continue;
1605+
return nullptr;
1606+
}
15891607

1590-
if (w != pWindow && w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sAdditionalConfigData.noFocus))
1608+
PHLWINDOW CCompositor::getPrevWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional<bool> floating) {
1609+
for (const auto& w : m_vWindows | std::views::reverse) {
1610+
if (isWindowMatch(pWindow, focusableOnly, floating, w))
15911611
return w;
15921612
}
15931613

15941614
return nullptr;
15951615
}
15961616

1597-
PHLWINDOW CCompositor::getPrevWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional<bool> floating) {
1598-
bool gotToWindow = false;
1599-
for (auto& w : m_vWindows | std::views::reverse) {
1600-
if (w != pWindow && !gotToWindow)
1601-
continue;
1617+
PHLWINDOW CCompositor::getNextVisibleWindow(PHLWINDOW pWindow, bool focusableOnly, std::optional<bool> floating) {
1618+
if (pWindow == getTopLeftWindowOnWorkspace(pWindow->workspaceID()))
1619+
if (const auto& w = getWindowOnAnotherMonitor(pWindow->m_iMonitorID, floating, true); w && m_pLastWindow->m_iMonitorID == w->m_iMonitorID)
1620+
return w;
16021621

1603-
if (w == pWindow) {
1604-
gotToWindow = true;
1605-
continue;
1606-
}
1622+
for (const auto& w : m_vWindows) {
1623+
if (isWindowMatch(pWindow, focusableOnly, floating, w))
1624+
return w;
1625+
}
16071626

1608-
if (floating.has_value() && w->m_bIsFloating != floating.value())
1609-
continue;
1627+
return nullptr;
1628+
}
1629+
1630+
PHLWINDOW CCompositor::getPrevVisibleWindow(PHLWINDOW pWindow, bool focusableOnly, std::optional<bool> floating) {
1631+
if (pWindow == getTopLeftWindowOnWorkspace(pWindow->workspaceID()))
1632+
if (const auto& w = getWindowOnAnotherMonitor(pWindow->m_iMonitorID, floating, true); w && m_pLastWindow->m_iMonitorID == w->m_iMonitorID)
1633+
return w;
16101634

1611-
if (w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sAdditionalConfigData.noFocus))
1635+
for (const auto& w : m_vWindows | std::views::reverse) {
1636+
if (isWindowMatch(pWindow, focusableOnly, floating, w))
16121637
return w;
16131638
}
16141639

1615-
for (auto& w : m_vWindows | std::views::reverse) {
1616-
if (floating.has_value() && w->m_bIsFloating != floating.value())
1640+
return nullptr;
1641+
}
1642+
1643+
PHLWINDOW CCompositor::getWindowOnAnotherMonitor(uint64_t curMonID, std::optional<bool> floating, bool reverse) {
1644+
for (auto mon = getNextMonitor(curMonID, reverse); mon->ID != curMonID; mon = getNextMonitor(curMonID, reverse)) {
1645+
if (mon->activeWorkspace == nullptr) {
1646+
curMonID = mon->ID;
16171647
continue;
1648+
}
16181649

1619-
if (w != pWindow && w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sAdditionalConfigData.noFocus))
1650+
if (const auto w = mon->activeWorkspace->getLastFocusedWindow(); w && (!floating.has_value() || floating.value() == w->m_bIsFloating)) {
16201651
return w;
1652+
}
16211653
}
16221654

16231655
return nullptr;

src/Compositor.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ class CCompositor {
107107
CMonitor* getMonitorFromDesc(const std::string&);
108108
CMonitor* getMonitorFromCursor();
109109
CMonitor* getMonitorFromVector(const Vector2D&);
110+
SP<CMonitor> getNextMonitor(uint64_t cur, bool reverse = false);
110111
void removeWindowFromVectorSafe(PHLWINDOW);
111112
void focusWindow(PHLWINDOW, SP<CWLSurfaceResource> pSurface = nullptr);
112113
void focusSurface(SP<CWLSurfaceResource>, PHLWINDOW pWindowOwner = nullptr);
@@ -139,8 +140,11 @@ class CCompositor {
139140
void changeWindowZOrder(PHLWINDOW, bool);
140141
void cleanupFadingOut(const int& monid);
141142
PHLWINDOW getWindowInDirection(PHLWINDOW, char);
143+
PHLWINDOW getNextVisibleWindow(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {});
144+
PHLWINDOW getPrevVisibleWindow(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {});
142145
PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {});
143146
PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {});
147+
PHLWINDOW getWindowOnAnotherMonitor(uint64_t curMonID, std::optional<bool> floating = {}, bool reverse = false);
144148
int getNextAvailableNamedWorkspace();
145149
bool isPointOnAnyMonitor(const Vector2D&);
146150
bool isPointOnReservedArea(const Vector2D& point, const CMonitor* monitor = nullptr);

src/managers/KeybindManager.cpp

Lines changed: 53 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "debug/Log.hpp"
1212
#include "helpers/varlist/VarList.hpp"
1313

14+
#include <hyprutils/string/VarList.hpp>
1415
#include <optional>
1516
#include <iterator>
1617
#include <string>
@@ -91,6 +92,7 @@ CKeybindManager::CKeybindManager() {
9192
m_mDispatchers["resizeactive"] = resizeActive;
9293
m_mDispatchers["moveactive"] = moveActive;
9394
m_mDispatchers["cyclenext"] = circleNext;
95+
m_mDispatchers["cyclenextvisible"] = circleNextVisible;
9496
m_mDispatchers["focuswindowbyclass"] = focusWindow;
9597
m_mDispatchers["focuswindow"] = focusWindow;
9698
m_mDispatchers["tagwindow"] = tagWindow;
@@ -311,8 +313,10 @@ bool CKeybindManager::tryMoveFocusToMonitor(CMonitor* monitor) {
311313
}
312314

313315
void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO) {
314-
const auto PLASTWINDOW = g_pCompositor->m_pLastWindow.lock();
316+
if (PWINDOWTOCHANGETO == nullptr)
317+
return;
315318

319+
const auto PLASTWINDOW = g_pCompositor->m_pLastWindow.lock();
316320
if (PWINDOWTOCHANGETO == PLASTWINDOW || !PWINDOWTOCHANGETO)
317321
return;
318322

@@ -330,23 +334,23 @@ void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO) {
330334

331335
if (!PWINDOWTOCHANGETO->m_bPinned)
332336
g_pCompositor->setWindowFullscreen(PWINDOWTOCHANGETO, true, FSMODE);
333-
} else {
334-
updateRelativeCursorCoords();
335-
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
336-
PWINDOWTOCHANGETO->warpCursor();
337+
return;
338+
}
339+
updateRelativeCursorCoords();
340+
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
341+
PWINDOWTOCHANGETO->warpCursor();
337342

338-
g_pInputManager->m_pForcedFocus = PWINDOWTOCHANGETO;
339-
g_pInputManager->simulateMouseMovement();
340-
g_pInputManager->m_pForcedFocus.reset();
343+
g_pInputManager->m_pForcedFocus = PWINDOWTOCHANGETO;
344+
g_pInputManager->simulateMouseMovement();
345+
g_pInputManager->m_pForcedFocus.reset();
341346

342-
if (PLASTWINDOW && PLASTWINDOW->m_iMonitorID != PWINDOWTOCHANGETO->m_iMonitorID) {
343-
// event
344-
const auto PNEWMON = g_pCompositor->getMonitorFromID(PWINDOWTOCHANGETO->m_iMonitorID);
347+
if (!PLASTWINDOW || PLASTWINDOW->m_iMonitorID == PWINDOWTOCHANGETO->m_iMonitorID)
348+
return;
345349

346-
g_pCompositor->setActiveMonitor(PNEWMON);
347-
}
348-
}
349-
};
350+
// event
351+
const auto PNEWMON = g_pCompositor->getMonitorFromID(PWINDOWTOCHANGETO->m_iMonitorID);
352+
g_pCompositor->setActiveMonitor(PNEWMON);
353+
}
350354

351355
bool CKeybindManager::onKeyEvent(std::any event, SP<IKeyboard> pKeyboard) {
352356
if (!g_pCompositor->m_bSessionActive || g_pCompositor->m_bUnsafeState) {
@@ -1904,31 +1908,48 @@ void CKeybindManager::resizeWindow(std::string args) {
19041908
PWINDOW->setHidden(false);
19051909
}
19061910

1907-
void CKeybindManager::circleNext(std::string arg) {
1911+
std::optional<bool> getFloatStatus(CVarList args) {
1912+
if (args.contains("tile") || args.contains("tiled"))
1913+
return false;
1914+
if (args.contains("float") || args.contains("floating"))
1915+
return true;
19081916

1909-
if (g_pCompositor->m_pLastWindow.expired()) {
1910-
// if we have a clear focus, find the first window and get the next focusable.
1911-
if (g_pCompositor->getWindowsOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspaceID()) > 0) {
1912-
const auto PWINDOW = g_pCompositor->getFirstWindowOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspaceID());
1917+
return std::nullopt;
1918+
}
19131919

1914-
switchToWindow(PWINDOW);
1915-
}
1920+
bool argsIsPrevious(CVarList args) {
1921+
return args.contains("prev") || args.contains("p") || args.contains("last") || args.contains("l");
1922+
}
19161923

1917-
return;
1924+
void CKeybindManager::circleNext(std::string arg) {
1925+
if (g_pCompositor->m_pLastWindow.expired()) {
1926+
if (g_pCompositor->getWindowsOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspaceID()) <= 0)
1927+
return; // if we have a clear focus, find the first window and get the next focusable.
1928+
1929+
const auto PWINDOW = g_pCompositor->getFirstWindowOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspaceID());
1930+
switchToWindow(PWINDOW);
19181931
}
19191932

1920-
CVarList args{arg, 0, 's', true};
1933+
CVarList args{arg, 0, 's', true};
1934+
if (argsIsPrevious(arg))
1935+
switchToWindow(g_pCompositor->getPrevWindowOnWorkspace(g_pCompositor->m_pLastWindow.lock(), true, getFloatStatus(arg)));
1936+
else
1937+
switchToWindow(g_pCompositor->getNextWindowOnWorkspace(g_pCompositor->m_pLastWindow.lock(), true, getFloatStatus(arg)));
1938+
}
19211939

1922-
std::optional<bool> floatStatus = {};
1923-
if (args.contains("tile") || args.contains("tiled"))
1924-
floatStatus = false;
1925-
else if (args.contains("float") || args.contains("floating"))
1926-
floatStatus = true;
1940+
void CKeybindManager::circleNextVisible(std::string arg) {
1941+
if (g_pCompositor->m_pLastWindow.expired()) {
1942+
if (g_pCompositor->getWindowsOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspaceID()) <= 0)
1943+
return; // if we have a clear focus, find the first window and get the next focusable.
1944+
const auto PWINDOW = g_pCompositor->getFirstWindowOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspaceID());
1945+
switchToWindow(PWINDOW);
1946+
}
19271947

1928-
if (args.contains("prev") || args.contains("p") || args.contains("last") || args.contains("l"))
1929-
switchToWindow(g_pCompositor->getPrevWindowOnWorkspace(g_pCompositor->m_pLastWindow.lock(), true, floatStatus));
1948+
CVarList args{arg, 0, 's', true};
1949+
if (argsIsPrevious(args))
1950+
switchToWindow(g_pCompositor->getPrevVisibleWindow(g_pCompositor->m_pLastWindow.lock(), true, getFloatStatus(args)));
19301951
else
1931-
switchToWindow(g_pCompositor->getNextWindowOnWorkspace(g_pCompositor->m_pLastWindow.lock(), true, floatStatus));
1952+
switchToWindow(g_pCompositor->getNextVisibleWindow(g_pCompositor->m_pLastWindow.lock(), true, getFloatStatus(args)));
19321953
}
19331954

19341955
void CKeybindManager::focusWindow(std::string regexp) {

src/managers/KeybindManager.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ class CKeybindManager {
182182
static void moveWindow(std::string);
183183
static void resizeWindow(std::string);
184184
static void circleNext(std::string);
185+
static void circleNextVisible(std::string);
185186
static void focusWindow(std::string);
186187
static void tagWindow(std::string);
187188
static void setSubmap(std::string);

0 commit comments

Comments
 (0)