From 3d5e2c1dc34e1099fd56bad61848f7a48268ea77 Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Sat, 9 Apr 2022 13:26:55 +0200 Subject: [PATCH] Added movefocus dispatcher --- example/hyprland.conf | 5 +++ src/Compositor.cpp | 61 +++++++++++++++++++++++++++++++++ src/Compositor.hpp | 1 + src/managers/KeybindManager.cpp | 20 +++++++++++ src/managers/KeybindManager.hpp | 1 + 5 files changed, 88 insertions(+) diff --git a/example/hyprland.conf b/example/hyprland.conf index 8503bf42..2e1425a5 100644 --- a/example/hyprland.conf +++ b/example/hyprland.conf @@ -63,6 +63,11 @@ bind=SUPER,V,togglefloating, bind=SUPER,R,exec,wofi --show drun -o DP-3 bind=SUPER,P,pseudo, +bind=SUPER,left,movefocus,l +bind=SUPER,right,movefocus,r +bind=SUPER,up,movefocus,u +bind=SUPER,down,movefocus,d + bind=SUPER,1,workspace,1 bind=SUPER,2,workspace,2 bind=SUPER,3,workspace,3 diff --git a/src/Compositor.cpp b/src/Compositor.cpp index bd843ef5..ecefbaba 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -568,4 +568,65 @@ void CCompositor::cleanupWindows() { return; } } +} + +CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) { + const auto POSA = pWindow->m_vPosition; + const auto SIZEA = pWindow->m_vSize; + + auto longestIntersect = -1; + CWindow* longestIntersectWindow = nullptr; + + for (auto& w : m_lWindows) { + if (&w == pWindow || !windowValidMapped(&w) || w.m_bIsFloating || w.m_iWorkspaceID != pWindow->m_iWorkspaceID) + continue; + + const auto POSB = w.m_vPosition; + const auto SIZEB = w.m_vSize; + switch (dir) { + case 'l': + if (STICKS(POSA.x, POSB.x + SIZEB.x)) { + const auto INTERSECTLEN = std::max((double)0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y)); + if (INTERSECTLEN > longestIntersect) { + longestIntersect = INTERSECTLEN; + longestIntersectWindow = &w; + } + } + break; + case 'r': + if (STICKS(POSA.x + SIZEA.x, POSB.x)) { + const auto INTERSECTLEN = std::max((double)0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y)); + if (INTERSECTLEN > longestIntersect) { + longestIntersect = INTERSECTLEN; + longestIntersectWindow = &w; + } + } + break; + case 't': + case 'u': + if (STICKS(POSA.y, POSB.y + SIZEB.y)) { + const auto INTERSECTLEN = std::max((double)0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x)); + if (INTERSECTLEN > longestIntersect) { + longestIntersect = INTERSECTLEN; + longestIntersectWindow = &w; + } + } + break; + case 'b': + case 'd': + if (STICKS(POSA.y + SIZEA.y, POSB.y)) { + const auto INTERSECTLEN = std::max((double)0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x)); + if (INTERSECTLEN > longestIntersect) { + longestIntersect = INTERSECTLEN; + longestIntersectWindow = &w; + } + } + break; + } + } + + if (longestIntersect != -1) + return longestIntersectWindow; + + return nullptr; } \ No newline at end of file diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 1133d38c..2eb5b2e2 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -100,6 +100,7 @@ public: bool isWindowActive(CWindow*); void moveWindowToTop(CWindow*); void cleanupWindows(); + CWindow* getWindowInDirection(CWindow*, char); private: void initAllSignals(); diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index d820e83e..8cf22892 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -54,6 +54,7 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const xkb_keysym_t else if (k.handler == "fullscreen") { fullscreenActive(k.arg); } else if (k.handler == "movetoworkspace") { moveActiveToWorkspace(k.arg); } else if (k.handler == "pseudo") { toggleActivePseudo(k.arg); } + else if (k.handler == "movefocus") { moveFocusTo(k.arg); } found = true; } @@ -244,3 +245,22 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) { PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition + g_pCompositor->getMonitorFromID(NEWWORKSPACE->monitorID)->vecPosition; } } + +void CKeybindManager::moveFocusTo(std::string args) { + char arg = args[0]; + + if (arg != 'l' && arg != 'r' && arg != 'u' && arg != 'd' && arg != 't' && arg != 'b') { + Debug::log(ERR, "Cannot move window in direction %c, unsupported direction. Supported: l,r,u/t,d/b", arg); + return; + } + + const auto PLASTWINDOW = g_pCompositor->m_pLastWindow; + + if (!g_pCompositor->windowValidMapped(PLASTWINDOW)) + return; + + const auto PWINDOWTOCHANGETO = g_pCompositor->getWindowInDirection(PLASTWINDOW, arg); + + if (PWINDOWTOCHANGETO) + g_pCompositor->focusWindow(PWINDOWTOCHANGETO); +} \ No newline at end of file diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp index f68f8314..de4e8fa3 100644 --- a/src/managers/KeybindManager.hpp +++ b/src/managers/KeybindManager.hpp @@ -31,6 +31,7 @@ private: void changeworkspace(std::string); void fullscreenActive(std::string); void moveActiveToWorkspace(std::string); + void moveFocusTo(std::string); }; inline std::unique_ptr g_pKeybindManager; \ No newline at end of file