diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index fa9a1334..deca2fcd 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -512,10 +512,14 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v // flags bool locked = false; + bool release = false; const auto ARGS = command.substr(4); + for (auto& arg : ARGS) { if (arg == 'l') { locked = true; + } else if (arg == 'r') { + release = true; } else { parseError = "bind: invalid flag"; return; @@ -552,9 +556,9 @@ 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}); + g_pKeybindManager->addKeybind(SKeybind{"", std::stoi(KEY), MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release}); else - g_pKeybindManager->addKeybind(SKeybind{KEY, -1, MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap}); + g_pKeybindManager->addKeybind(SKeybind{KEY, -1, MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release}); } } diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 1d7a4ba4..52afbfdd 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -82,7 +82,31 @@ uint32_t CKeybindManager::stringToModMask(std::string mods) { return modMask; } -bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const xkb_keysym_t& key, const int& keycode) { +bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard) { + const auto KEYCODE = e->keycode + 8; // Because to xkbcommon it's +8 from libinput + + const xkb_keysym_t* keysyms; + int syms = xkb_state_key_get_syms(wlr_keyboard_from_input_device(pKeyboard->keyboard)->xkb_state, KEYCODE, &keysyms); + + const auto MODS = g_pInputManager->accumulateModsFromAllKBs(); + + bool found = false; + if (e->state == WL_KEYBOARD_KEY_STATE_PRESSED) { + for (int i = 0; i < syms; ++i) + found = g_pKeybindManager->handleKeybinds(MODS, keysyms[i], 0, true) || found; + + found = g_pKeybindManager->handleKeybinds(MODS, 0, KEYCODE, true) || found; + } else if (e->state == WL_KEYBOARD_KEY_STATE_RELEASED) { + for (int i = 0; i < syms; ++i) + found = g_pKeybindManager->handleKeybinds(MODS, keysyms[i], 0, false) || found; + + found = g_pKeybindManager->handleKeybinds(MODS, 0, KEYCODE, false) || found; + } + + return !found; +} + +bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const xkb_keysym_t& key, const int& keycode, bool pressed) { bool found = false; if (handleInternalKeybinds(key)) @@ -92,10 +116,9 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const xkb_keysym_t Debug::log(LOG, "Keybind handling only locked (inhibitor)"); for (auto& k : m_lKeybinds) { - if (modmask != k.modmask || (g_pCompositor->m_sSeat.exclusiveClient && !k.locked) || k.submap != m_szCurrentSelectedSubmap) + if (modmask != k.modmask || (g_pCompositor->m_sSeat.exclusiveClient && !k.locked) || k.submap != m_szCurrentSelectedSubmap || (!pressed && !k.release)) continue; - if (k.keycode != -1) { if (keycode != k.keycode) continue; @@ -114,6 +137,11 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const xkb_keysym_t continue; } + if (pressed && k.release) { + // suppress down event + return true; + } + const auto DISPATCHER = m_mDispatchers.find(k.handler); // Should never happen, as we check in the ConfigManager, but oh well diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp index 3aece7be..fc3b06f8 100644 --- a/src/managers/KeybindManager.hpp +++ b/src/managers/KeybindManager.hpp @@ -14,13 +14,15 @@ struct SKeybind { std::string arg = ""; bool locked = false; std::string submap = ""; + bool release = false; }; class CKeybindManager { public: CKeybindManager(); - bool handleKeybinds(const uint32_t&, const xkb_keysym_t&, const int&); + bool onKeyEvent(wlr_keyboard_key_event*, SKeyboard*); + void addKeybind(SKeybind); void removeKeybind(uint32_t, const std::string&); uint32_t stringToModMask(std::string); @@ -33,6 +35,8 @@ private: inline static std::string m_szCurrentSelectedSubmap = ""; + bool handleKeybinds(const uint32_t&, const xkb_keysym_t&, const int&, bool); + bool handleInternalKeybinds(xkb_keysym_t); bool handleVT(xkb_keysym_t); diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index f1ef0a91..c922421c 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -629,26 +629,11 @@ void CInputManager::destroyMouse(wlr_input_device* mouse) { } void CInputManager::onKeyboardKey(wlr_keyboard_key_event* e, SKeyboard* pKeyboard) { - const auto KEYCODE = e->keycode + 8; // Because to xkbcommon it's +8 from libinput - - const xkb_keysym_t* keysyms; - int syms = xkb_state_key_get_syms(wlr_keyboard_from_input_device(pKeyboard->keyboard)->xkb_state, KEYCODE, &keysyms); - - const auto MODS = accumulateModsFromAllKBs(); + bool passEvent = g_pKeybindManager->onKeyEvent(e, pKeyboard); wlr_idle_notify_activity(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat); - bool found = false; - if (e->state == WL_KEYBOARD_KEY_STATE_PRESSED) { - for (int i = 0; i < syms; ++i) - found = g_pKeybindManager->handleKeybinds(MODS, keysyms[i], 0) || found; - - found = g_pKeybindManager->handleKeybinds(MODS, 0, KEYCODE) || found; - } else if (e->state == WL_KEYBOARD_KEY_STATE_RELEASED) { - // hee hee - } - - if (!found) { + if (passEvent) { wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(pKeyboard->keyboard)); wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, e->time_msec, e->keycode, e->state); } diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp index 514d5bad..107d891f 100644 --- a/src/managers/input/InputManager.hpp +++ b/src/managers/input/InputManager.hpp @@ -76,6 +76,9 @@ public: CTimer m_tmrLastCursorMovement; + // for shared mods + uint32_t accumulateModsFromAllKBs(); + private: // for click behavior override @@ -92,9 +95,6 @@ private: STabletTool* ensureTabletToolPresent(wlr_tablet_tool*); void applyConfigToKeyboard(SKeyboard*); - - // for shared mods - uint32_t accumulateModsFromAllKBs(); }; inline std::unique_ptr g_pInputManager; \ No newline at end of file