Skip to content

Commit

Permalink
HYP-6678 | feat: circle visible
Browse files Browse the repository at this point in the history
  • Loading branch information
Крылов Александр committed Jul 13, 2024
1 parent ba5cdb2 commit 40a9e07
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 65 deletions.
98 changes: 65 additions & 33 deletions src/Compositor.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#include "Compositor.hpp"
#include "desktop/DesktopTypes.hpp"
#include "helpers/Splashes.hpp"
#include "config/ConfigValue.hpp"
#include "managers/CursorManager.hpp"
#include "managers/TokenManager.hpp"
#include "managers/PointerManager.hpp"
#include "managers/SeatManager.hpp"
#include "managers/eventLoop/EventLoopManager.hpp"
#include <cstdint>
#include <random>
#include <unordered_set>
#include "debug/HyprCtl.hpp"
Expand Down Expand Up @@ -671,6 +673,30 @@ CMonitor* CCompositor::getMonitorFromVector(const Vector2D& point) {
return mon.get();
}

SP<CMonitor> CCompositor::getNextMonitor(uint64_t curID, bool reverse) {
const auto LN = m_vMonitors.size();
if (LN == 1) {
return m_vMonitors[0];
}

size_t curPos = LN + 1;
for (size_t i = 0; i < LN; i++) {
if (m_vMonitors[i]->ID == curID) {
curPos = i;
}
}

if (curPos == LN && !reverse) {
return m_vMonitors[0];
}

if (curPos == 0 && reverse) {
return m_vMonitors[LN - 1];
}

return reverse ? m_vMonitors[curPos - 1] : m_vMonitors[curPos + 1];
}

void CCompositor::removeWindowFromVectorSafe(PHLWINDOW pWindow) {
if (!pWindow->m_bFadingOut) {
EMIT_HOOK_EVENT("destroyWindow", pWindow);
Expand Down Expand Up @@ -1565,59 +1591,65 @@ PHLWINDOW CCompositor::getWindowInDirection(PHLWINDOW pWindow, char dir) {
return nullptr;
}

PHLWINDOW CCompositor::getNextWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional<bool> floating) {
bool gotToWindow = false;
for (auto& w : m_vWindows) {
if (w != pWindow && !gotToWindow)
continue;

if (w == pWindow) {
gotToWindow = true;
continue;
}

if (floating.has_value() && w->m_bIsFloating != floating.value())
continue;
bool isWindowMatch(PHLWINDOW pWindow, bool focusableOnly, std::optional<bool> floating, const PHLWINDOW& w) {
return (!floating.has_value() || w->m_bIsFloating == floating.value()) && w != pWindow && w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() &&
(!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault());
}

if (w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault()))
PHLWINDOW CCompositor::getNextWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional<bool> floating) {
for (const auto& w : m_vWindows) {
if (isWindowMatch(pWindow, focusableOnly, floating, w))
return w;
}

for (auto& w : m_vWindows) {
if (floating.has_value() && w->m_bIsFloating != floating.value())
continue;
return nullptr;
}

if (w != pWindow && w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault()))
PHLWINDOW CCompositor::getPrevWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional<bool> floating) {
for (const auto& w : m_vWindows | std::views::reverse) {
if (isWindowMatch(pWindow, focusableOnly, floating, w))
return w;
}

return nullptr;
}

PHLWINDOW CCompositor::getPrevWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional<bool> floating) {
bool gotToWindow = false;
for (auto& w : m_vWindows | std::views::reverse) {
if (w != pWindow && !gotToWindow)
continue;
PHLWINDOW CCompositor::getNextVisibleWindow(PHLWINDOW pWindow, bool focusableOnly, std::optional<bool> floating) {
if (pWindow == getTopLeftWindowOnWorkspace(pWindow->workspaceID()))
if (const auto& w = getWindowOnAnotherMonitor(pWindow->m_iMonitorID, floating, true); w && m_pLastWindow->m_iMonitorID == w->m_iMonitorID)
return w;

if (w == pWindow) {
gotToWindow = true;
continue;
}
for (const auto& w : m_vWindows) {
if (isWindowMatch(pWindow, focusableOnly, floating, w))
return w;
}

if (floating.has_value() && w->m_bIsFloating != floating.value())
continue;
return nullptr;
}

PHLWINDOW CCompositor::getPrevVisibleWindow(PHLWINDOW pWindow, bool focusableOnly, std::optional<bool> floating) {
if (pWindow == getTopLeftWindowOnWorkspace(pWindow->workspaceID()))
if (const auto& w = getWindowOnAnotherMonitor(pWindow->m_iMonitorID, floating, true); w && m_pLastWindow->m_iMonitorID == w->m_iMonitorID)
return w;

if (w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault()))
for (const auto& w : m_vWindows | std::views::reverse) {
if (isWindowMatch(pWindow, focusableOnly, floating, w))
return w;
}

for (auto& w : m_vWindows | std::views::reverse) {
if (floating.has_value() && w->m_bIsFloating != floating.value())
return nullptr;
}

PHLWINDOW CCompositor::getWindowOnAnotherMonitor(uint64_t curMonID, std::optional<bool> floating, bool reverse) {
for (auto mon = getNextMonitor(curMonID, reverse); mon->ID != curMonID; mon = getNextMonitor(curMonID, reverse)) {
if (mon->activeWorkspace == nullptr) {
curMonID = mon->ID;
continue;
}

if (w != pWindow && w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault()))
if (const auto w = mon->activeWorkspace->getLastFocusedWindow(); w && (!floating.has_value() || floating.value() == w->m_bIsFloating)) {
return w;
}
}

return nullptr;
Expand Down
4 changes: 4 additions & 0 deletions src/Compositor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ class CCompositor {
CMonitor* getMonitorFromDesc(const std::string&);
CMonitor* getMonitorFromCursor();
CMonitor* getMonitorFromVector(const Vector2D&);
SP<CMonitor> getNextMonitor(uint64_t cur, bool reverse = false);
void removeWindowFromVectorSafe(PHLWINDOW);
void focusWindow(PHLWINDOW, SP<CWLSurfaceResource> pSurface = nullptr);
void focusSurface(SP<CWLSurfaceResource>, PHLWINDOW pWindowOwner = nullptr);
Expand Down Expand Up @@ -139,8 +140,11 @@ class CCompositor {
void changeWindowZOrder(PHLWINDOW, bool);
void cleanupFadingOut(const int& monid);
PHLWINDOW getWindowInDirection(PHLWINDOW, char);
PHLWINDOW getNextVisibleWindow(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {});
PHLWINDOW getPrevVisibleWindow(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {});
PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {});
PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {});
PHLWINDOW getWindowOnAnotherMonitor(uint64_t curMonID, std::optional<bool> floating = {}, bool reverse = false);
int getNextAvailableNamedWorkspace();
bool isPointOnAnyMonitor(const Vector2D&);
bool isPointOnReservedArea(const Vector2D& point, const CMonitor* monitor = nullptr);
Expand Down
85 changes: 53 additions & 32 deletions src/managers/KeybindManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "debug/Log.hpp"
#include "helpers/varlist/VarList.hpp"

#include <hyprutils/string/VarList.hpp>
#include <optional>
#include <iterator>
#include <string>
Expand Down Expand Up @@ -91,6 +92,7 @@ CKeybindManager::CKeybindManager() {
m_mDispatchers["resizeactive"] = resizeActive;
m_mDispatchers["moveactive"] = moveActive;
m_mDispatchers["cyclenext"] = circleNext;
m_mDispatchers["cyclenextvisible"] = circleNextVisible;
m_mDispatchers["focuswindowbyclass"] = focusWindow;
m_mDispatchers["focuswindow"] = focusWindow;
m_mDispatchers["tagwindow"] = tagWindow;
Expand Down Expand Up @@ -311,8 +313,10 @@ bool CKeybindManager::tryMoveFocusToMonitor(CMonitor* monitor) {
}

void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO) {
const auto PLASTWINDOW = g_pCompositor->m_pLastWindow.lock();
if (PWINDOWTOCHANGETO == nullptr)
return;

const auto PLASTWINDOW = g_pCompositor->m_pLastWindow.lock();
if (PWINDOWTOCHANGETO == PLASTWINDOW || !PWINDOWTOCHANGETO)
return;

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

if (!PWINDOWTOCHANGETO->m_bPinned)
g_pCompositor->setWindowFullscreen(PWINDOWTOCHANGETO, true, FSMODE);
} else {
updateRelativeCursorCoords();
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
PWINDOWTOCHANGETO->warpCursor();
return;
}
updateRelativeCursorCoords();
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
PWINDOWTOCHANGETO->warpCursor();

g_pInputManager->m_pForcedFocus = PWINDOWTOCHANGETO;
g_pInputManager->simulateMouseMovement();
g_pInputManager->m_pForcedFocus.reset();
g_pInputManager->m_pForcedFocus = PWINDOWTOCHANGETO;
g_pInputManager->simulateMouseMovement();
g_pInputManager->m_pForcedFocus.reset();

if (PLASTWINDOW && PLASTWINDOW->m_iMonitorID != PWINDOWTOCHANGETO->m_iMonitorID) {
// event
const auto PNEWMON = g_pCompositor->getMonitorFromID(PWINDOWTOCHANGETO->m_iMonitorID);
if (!PLASTWINDOW || PLASTWINDOW->m_iMonitorID == PWINDOWTOCHANGETO->m_iMonitorID)
return;

g_pCompositor->setActiveMonitor(PNEWMON);
}
}
};
// event
const auto PNEWMON = g_pCompositor->getMonitorFromID(PWINDOWTOCHANGETO->m_iMonitorID);
g_pCompositor->setActiveMonitor(PNEWMON);
}

bool CKeybindManager::onKeyEvent(std::any event, SP<IKeyboard> pKeyboard) {
if (!g_pCompositor->m_bSessionActive || g_pCompositor->m_bUnsafeState) {
Expand Down Expand Up @@ -1894,31 +1898,48 @@ void CKeybindManager::resizeWindow(std::string args) {
PWINDOW->setHidden(false);
}

void CKeybindManager::circleNext(std::string arg) {
std::optional<bool> getFloatStatus(CVarList args) {
if (args.contains("tile") || args.contains("tiled"))
return false;
if (args.contains("float") || args.contains("floating"))
return true;

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

switchToWindow(PWINDOW);
}
bool argsIsPrevious(CVarList args) {
return args.contains("prev") || args.contains("p") || args.contains("last") || args.contains("l");
}

return;
void CKeybindManager::circleNext(std::string arg) {
if (g_pCompositor->m_pLastWindow.expired()) {
if (g_pCompositor->getWindowsOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspaceID()) <= 0)
return; // if we have a clear focus, find the first window and get the next focusable.

const auto PWINDOW = g_pCompositor->getFirstWindowOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspaceID());
switchToWindow(PWINDOW);
}

CVarList args{arg, 0, 's', true};
CVarList args{arg, 0, 's', true};
if (argsIsPrevious(arg))
switchToWindow(g_pCompositor->getPrevWindowOnWorkspace(g_pCompositor->m_pLastWindow.lock(), true, getFloatStatus(arg)));
else
switchToWindow(g_pCompositor->getNextWindowOnWorkspace(g_pCompositor->m_pLastWindow.lock(), true, getFloatStatus(arg)));
}

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

if (args.contains("prev") || args.contains("p") || args.contains("last") || args.contains("l"))
switchToWindow(g_pCompositor->getPrevWindowOnWorkspace(g_pCompositor->m_pLastWindow.lock(), true, floatStatus));
CVarList args{arg, 0, 's', true};
if (argsIsPrevious(args))
switchToWindow(g_pCompositor->getPrevVisibleWindow(g_pCompositor->m_pLastWindow.lock(), true, getFloatStatus(args)));
else
switchToWindow(g_pCompositor->getNextWindowOnWorkspace(g_pCompositor->m_pLastWindow.lock(), true, floatStatus));
switchToWindow(g_pCompositor->getNextVisibleWindow(g_pCompositor->m_pLastWindow.lock(), true, getFloatStatus(args)));
}

void CKeybindManager::focusWindow(std::string regexp) {
Expand Down
1 change: 1 addition & 0 deletions src/managers/KeybindManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ class CKeybindManager {
static void moveWindow(std::string);
static void resizeWindow(std::string);
static void circleNext(std::string);
static void circleNextVisible(std::string);
static void focusWindow(std::string);
static void tagWindow(std::string);
static void setSubmap(std::string);
Expand Down

0 comments on commit 40a9e07

Please sign in to comment.