From f83d3ccea72ba0f064b0f767196d5b494d9a41fb Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Sun, 5 Dec 2021 12:05:44 +0100 Subject: [PATCH] added moving focus and no hover focus --- example/hypr.conf | 6 ++++++ src/KeybindManager.cpp | 4 ++++ src/KeybindManager.hpp | 1 + src/config/ConfigManager.cpp | 3 +++ src/events/events.cpp | 17 ++++++++++++----- src/windowManager.cpp | 28 +++++++++++++++++++++++++--- src/windowManager.hpp | 1 + 7 files changed, 52 insertions(+), 8 deletions(-) diff --git a/example/hypr.conf b/example/hypr.conf index ebba2fb..91803d1 100644 --- a/example/hypr.conf +++ b/example/hypr.conf @@ -9,6 +9,7 @@ gaps_out=20 rounding=0 max_fps=60 # max fps for updates of config & animations layout=0 # 0 - dwindle (default), 1 - master +focus_when_hover=1 # 0 - do not switch the focus when hover (only for tiling) # Execs @@ -58,6 +59,11 @@ bind=SUPER,RIGHT,movewindow,r bind=SUPER,UP,movewindow,u bind=SUPER,DOWN,movewindow,d +bind=SUPER,LEFT,movefocus,l +bind=SUPER,RIGHT,movefocus,r +bind=SUPER,UP,movefocus,u +bind=SUPER,DOWN,movefocus,d + bind=SUPER,F,fullscreen, bind=SUPER,1,workspace,1 diff --git a/src/KeybindManager.cpp b/src/KeybindManager.cpp index e3443f3..da27d47 100644 --- a/src/KeybindManager.cpp +++ b/src/KeybindManager.cpp @@ -128,6 +128,10 @@ void KeybindManager::movewindow(std::string arg) { g_pWindowManager->moveActiveWindowTo(arg[0]); } +void KeybindManager::movefocus(std::string arg) { + g_pWindowManager->moveActiveFocusTo(arg[0]); +} + void KeybindManager::movetoworkspace(std::string arg) { try { g_pWindowManager->moveActiveWindowToWorkspace(stoi(arg)); diff --git a/src/KeybindManager.hpp b/src/KeybindManager.hpp index f8e1c45..b1c38ae 100644 --- a/src/KeybindManager.hpp +++ b/src/KeybindManager.hpp @@ -21,6 +21,7 @@ namespace KeybindManager { void call(std::string args); void killactive(std::string args); void movewindow(std::string args); + void movefocus(std::string args); void changeworkspace(std::string args); void toggleActiveWindowFullscreen(std::string args); void toggleActiveWindowFloating(std::string args); diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 7ba68ab..7ba6563 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -15,6 +15,8 @@ void ConfigManager::init() { configValues["gaps_out"].intValue = 20; configValues["rounding"].intValue = 5; + configValues["focus_when_hover"].intValue = 1; + configValues["layout"].intValue = LAYOUT_DWINDLE; configValues["max_fps"].intValue = 60; @@ -109,6 +111,7 @@ void handleBind(const std::string& command, const std::string& value) { if (HANDLER == "killactive") dispatcher = KeybindManager::killactive; if (HANDLER == "fullscreen") dispatcher = KeybindManager::toggleActiveWindowFullscreen; if (HANDLER == "movewindow") dispatcher = KeybindManager::movewindow; + if (HANDLER == "movefocus") dispatcher = KeybindManager::movefocus; if (HANDLER == "movetoworkspace") dispatcher = KeybindManager::movetoworkspace; if (HANDLER == "workspace") dispatcher = KeybindManager::changeworkspace; if (HANDLER == "togglefloating") dispatcher = KeybindManager::toggleActiveWindowFloating; diff --git a/src/events/events.cpp b/src/events/events.cpp index 70d3031..cf9b380 100644 --- a/src/events/events.cpp +++ b/src/events/events.cpp @@ -61,12 +61,19 @@ void Events::setThread() { void Events::eventEnter(xcb_generic_event_t* event) { const auto E = reinterpret_cast(event); - // Just focus it and update. - g_pWindowManager->setFocusedWindow(E->event); - if(const auto PENTERWINDOW = g_pWindowManager->getWindowFromDrawable(E->event)) { - PENTERWINDOW->setDirty(true); - } + const auto PENTERWINDOW = g_pWindowManager->getWindowFromDrawable(E->event); + + if (!PENTERWINDOW) + return; // wut + + // Only when focus_when_hover OR floating OR last window floating + if (ConfigManager::getInt("focus_when_hover") == 1 + || PENTERWINDOW->getIsFloating() + || (g_pWindowManager->getWindowFromDrawable(g_pWindowManager->LastWindow) && g_pWindowManager->getWindowFromDrawable(g_pWindowManager->LastWindow)->getIsFloating())) + g_pWindowManager->setFocusedWindow(E->event); + + PENTERWINDOW->setDirty(true); } void Events::eventLeave(xcb_generic_event_t* event) { diff --git a/src/windowManager.cpp b/src/windowManager.cpp index 4a898a3..646a9ff 100644 --- a/src/windowManager.cpp +++ b/src/windowManager.cpp @@ -403,8 +403,6 @@ void CWindowManager::refreshDirtyWindows() { void CWindowManager::setFocusedWindow(xcb_drawable_t window) { if (window && window != Screen->root) { - xcb_set_input_focus(DisplayConnection, XCB_INPUT_FOCUS_POINTER_ROOT, window, XCB_CURRENT_TIME); - // Fix border from the old window that was in focus. Values[0] = ConfigManager::getInt("col.inactive_border"); xcb_change_window_attributes(DisplayConnection, LastWindow, XCB_CW_BORDER_PIXEL, Values); @@ -425,6 +423,9 @@ void CWindowManager::setFocusedWindow(xcb_drawable_t window) { LastWindow = window; applyRoundedCornersToWindow(g_pWindowManager->getWindowFromDrawable(window)); + + // set focus in X11 + xcb_set_input_focus(DisplayConnection, XCB_INPUT_FOCUS_POINTER_ROOT, window, XCB_CURRENT_TIME); } } @@ -1152,10 +1153,12 @@ CWindow* CWindowManager::getNeighborInDir(char dir) { return &w; break; case 't': + case 'u': if (STICKS(POSA.y, POSB.y + SIZEB.y)) return &w; break; case 'b': + case 'd': if (STICKS(POSA.y + SIZEA.y, POSB.y)) return &w; break; @@ -1259,6 +1262,24 @@ void CWindowManager::moveActiveWindowTo(char dir) { warpCursorTo(CURRENTWINDOW->getPosition() + CURRENTWINDOW->getSize() / 2.f); } +void CWindowManager::moveActiveFocusTo(char dir) { + const auto CURRENTWINDOW = getWindowFromDrawable(LastWindow); + + if (!CURRENTWINDOW) + return; + + const auto neighbor = getNeighborInDir(dir); + + if (!neighbor) + return; + + // move the focus + setFocusedWindow(neighbor->getDrawable()); + + // finish by moving the cursor to the current window + warpCursorTo(CURRENTWINDOW->getPosition() + CURRENTWINDOW->getSize() / 2.f); +} + void CWindowManager::changeWorkspaceByID(int ID) { const auto MONITOR = getMonitorFromCursor(); @@ -1606,7 +1627,8 @@ void CWindowManager::getICCCMWMProtocols(CWindow* pWindow) { void CWindowManager::refocusWindowOnClosed() { const auto PWINDOW = findWindowAtCursor(); - if (!PWINDOW) + // No window or last window valid + if (!PWINDOW || getWindowFromDrawable(LastWindow)) return; LastWindow = PWINDOW->getDrawable(); diff --git a/src/windowManager.hpp b/src/windowManager.hpp index 8973523..26a6fdd 100644 --- a/src/windowManager.hpp +++ b/src/windowManager.hpp @@ -74,6 +74,7 @@ public: void closeWindowAllChecks(int64_t); void moveActiveWindowTo(char); + void moveActiveFocusTo(char); void moveActiveWindowToWorkspace(int); void warpCursorTo(Vector2D);