diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 7df288fe..94a81458 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -658,6 +658,7 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v bool locked = false; bool release = false; bool repeat = false; + bool mouse = false; const auto ARGS = command.substr(4); for (auto& arg : ARGS) { @@ -667,6 +668,8 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v release = true; } else if (arg == 'e') { repeat = true; + } else if (arg == 'm') { + mouse = true; } else { parseError = "bind: invalid flag"; return; @@ -678,6 +681,11 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v return; } + if (mouse && (repeat || release || locked)) { + parseError = "flag m is exclusive"; + return; + } + auto valueCopy = value; const auto MOD = g_pKeybindManager->stringToModMask(valueCopy.substr(0, valueCopy.find_first_of(","))); @@ -687,10 +695,13 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v const auto KEY = valueCopy.substr(0, valueCopy.find_first_of(",")); valueCopy = valueCopy.substr(valueCopy.find_first_of(",") + 1); - const auto HANDLER = valueCopy.substr(0, valueCopy.find_first_of(",")); + auto HANDLER = valueCopy.substr(0, valueCopy.find_first_of(",")); valueCopy = valueCopy.substr(valueCopy.find_first_of(",") + 1); - const auto COMMAND = valueCopy; + const auto COMMAND = mouse ? HANDLER : valueCopy; + + if (mouse) + HANDLER = "mouse"; const auto DISPATCHER = g_pKeybindManager->m_mDispatchers.find(HANDLER); @@ -713,11 +724,10 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v if (KEY != "") { if (isNumber(KEY) && std::stoi(KEY) > 9) - g_pKeybindManager->addKeybind(SKeybind{"", std::stoi(KEY), MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat}); + g_pKeybindManager->addKeybind(SKeybind{"", std::stoi(KEY), MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat, mouse}); else - g_pKeybindManager->addKeybind(SKeybind{KEY, -1, MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat}); + g_pKeybindManager->addKeybind(SKeybind{KEY, -1, MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat, mouse}); } - } void CConfigManager::handleUnbind(const std::string& command, const std::string& value) { diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index 1cc7f7db..8984a107 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -137,7 +137,7 @@ void IHyprLayout::onBeginDragWindow() { DRAGGINGWINDOW->m_bDraggingTiled = false; if (!DRAGGINGWINDOW->m_bIsFloating) { - if (g_pInputManager->dragButton == BTN_LEFT) { + if (g_pInputManager->dragMode == MBIND_MOVE) { changeWindowFloatingMode(DRAGGINGWINDOW); DRAGGINGWINDOW->m_bIsFloating = true; DRAGGINGWINDOW->m_bDraggingTiled = true; @@ -192,11 +192,11 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) { g_pHyprRenderer->damageWindow(DRAGGINGWINDOW); - if (g_pInputManager->dragButton == BTN_LEFT) { + if (g_pInputManager->dragMode == MBIND_MOVE) { DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(m_vBeginDragPositionXY + DELTA); g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv()); - } else { + } else if (g_pInputManager->dragMode == MBIND_RESIZE) { if (DRAGGINGWINDOW->m_bIsFloating) { const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(DRAGGINGWINDOW); diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 9b4827c9..47f42e2b 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -43,6 +43,7 @@ CKeybindManager::CKeybindManager() { m_mDispatchers["swapnext"] = swapnext; m_mDispatchers["swapactiveworkspaces"] = swapActiveWorkspaces; m_mDispatchers["pin"] = pinActive; + m_mDispatchers["mouse"] = mouse; m_tScrollTimer.reset(); } @@ -278,7 +279,7 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string& } for (auto& k : m_lKeybinds) { - if (modmask != k.modmask || (g_pCompositor->m_sSeat.exclusiveClient && !k.locked) || k.submap != m_szCurrentSelectedSubmap || (!pressed && !k.release && k.handler != "pass") || k.shadowed) + if (modmask != k.modmask || (g_pCompositor->m_sSeat.exclusiveClient && !k.locked) || k.submap != m_szCurrentSelectedSubmap || (!pressed && !k.release && k.handler != "pass" && k.handler != "mouse") || k.shadowed) continue; if (!key.empty()) { @@ -307,7 +308,7 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string& return true; } - const auto DISPATCHER = m_mDispatchers.find(k.handler); + const auto DISPATCHER = m_mDispatchers.find(k.mouse ? "mouse" : k.handler); // Should never happen, as we check in the ConfigManager, but oh well if (DISPATCHER == m_mDispatchers.end()) { @@ -318,7 +319,10 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string& m_iPassPressed = (int)pressed; - DISPATCHER->second(k.arg); + if (k.handler == "mouse") + DISPATCHER->second((pressed ? "1" : "0") + k.arg); + else + DISPATCHER->second(k.arg); m_iPassPressed = -1; @@ -1576,3 +1580,36 @@ void CKeybindManager::pinActive(std::string args) { PWORKSPACE->m_pLastFocusedWindow = g_pCompositor->vectorToWindowTiled(g_pInputManager->getMouseCoordsInternal()); } + +void CKeybindManager::mouse(std::string args) { + const auto TRUEARG = args.substr(1); + const auto PRESSED = args[0] == '1'; + + if (TRUEARG == "movewindow") { + if (PRESSED) { + g_pInputManager->currentlyDraggedWindow = g_pCompositor->windowFromCursor(); + g_pInputManager->dragMode = MBIND_MOVE; + + g_pLayoutManager->getCurrentLayout()->onBeginDragWindow(); + } else { + if (g_pInputManager->currentlyDraggedWindow) { + g_pLayoutManager->getCurrentLayout()->onEndDragWindow(); + g_pInputManager->currentlyDraggedWindow = nullptr; + g_pInputManager->dragMode = MBIND_INVALID; + } + } + } else if (TRUEARG == "resizewindow") { + if (PRESSED) { + g_pInputManager->currentlyDraggedWindow = g_pCompositor->windowFromCursor(); + g_pInputManager->dragMode = MBIND_RESIZE; + + g_pLayoutManager->getCurrentLayout()->onBeginDragWindow(); + } else { + if (g_pInputManager->currentlyDraggedWindow) { + g_pLayoutManager->getCurrentLayout()->onEndDragWindow(); + g_pInputManager->currentlyDraggedWindow = nullptr; + g_pInputManager->dragMode = MBIND_INVALID; + } + } + } +} diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp index d7233c79..ab883c40 100644 --- a/src/managers/KeybindManager.hpp +++ b/src/managers/KeybindManager.hpp @@ -18,6 +18,7 @@ struct SKeybind { std::string submap = ""; bool release = false; bool repeat = false; + bool mouse = false; // DO NOT INITIALIZE bool shadowed = false; @@ -114,6 +115,7 @@ private: static void swapnext(std::string); static void swapActiveWorkspaces(std::string); static void pinActive(std::string); + static void mouse(std::string); friend class CCompositor; friend class CInputManager; diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 21e6b56d..2b099ac3 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -385,7 +385,6 @@ void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) { // notify the keybind manager static auto *const PPASSMOUSE = &g_pConfigManager->getConfigValuePtr("binds:pass_mouse_when_bound")->intValue; - static auto *const PMAINMODINTERNAL = &g_pConfigManager->getConfigValuePtr("general:main_mod_internal")->intValue; const auto PASS = g_pKeybindManager->onMouseEvent(e); if (!PASS && !*PPASSMOUSE) @@ -400,22 +399,8 @@ void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) { if (g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) && g_pCompositor->m_pLastWindow->m_bIsFloating) g_pCompositor->moveWindowToTop(g_pCompositor->m_pLastWindow); - if ((e->button == BTN_LEFT || e->button == BTN_RIGHT) && wlr_keyboard_get_modifiers(PKEYBOARD) == (uint32_t)*PMAINMODINTERNAL) { - currentlyDraggedWindow = g_pCompositor->windowFromCursor(); - dragButton = e->button; - - g_pLayoutManager->getCurrentLayout()->onBeginDragWindow(); - - return; - } break; case WLR_BUTTON_RELEASED: - if (currentlyDraggedWindow) { - g_pLayoutManager->getCurrentLayout()->onEndDragWindow(); - currentlyDraggedWindow = nullptr; - dragButton = -1; - } - break; } diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp index 82d047f3..9069e131 100644 --- a/src/managers/input/InputManager.hpp +++ b/src/managers/input/InputManager.hpp @@ -12,6 +12,12 @@ enum eClickBehaviorMode { CLICKMODE_KILL }; +enum eMouseBindMode { + MBIND_INVALID = -1, + MBIND_MOVE = 0, + MBIND_RESIZE +}; + struct STouchData { CWindow* touchFocusWindow = nullptr; Vector2D touchSurfaceOrigin; @@ -59,7 +65,7 @@ public: // for dragging floating windows CWindow* currentlyDraggedWindow = nullptr; - int dragButton = -1; + eMouseBindMode dragMode = MBIND_INVALID; SDrag m_sDrag;