From bb539f0a8ddaac711138b0beeebcf711c523076c Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Mon, 25 Jul 2022 14:42:49 +0200 Subject: [PATCH] added keybind repeat flag --- src/config/ConfigManager.cpp | 7 ++++-- src/managers/KeybindManager.cpp | 42 +++++++++++++++++++++++++++++++++ src/managers/KeybindManager.hpp | 5 ++++ 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 32097a2b..86929918 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -513,6 +513,7 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v // flags bool locked = false; bool release = false; + bool repeat = false; const auto ARGS = command.substr(4); for (auto& arg : ARGS) { @@ -520,6 +521,8 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v locked = true; } else if (arg == 'r') { release = true; + } else if (arg == 'e') { + repeat = true; } else { parseError = "bind: invalid flag"; return; @@ -556,9 +559,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, release}); + g_pKeybindManager->addKeybind(SKeybind{"", std::stoi(KEY), MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat}); else - g_pKeybindManager->addKeybind(SKeybind{KEY, -1, MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release}); + g_pKeybindManager->addKeybind(SKeybind{KEY, -1, MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat}); } } diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index d9072b47..af39a95a 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -37,6 +37,8 @@ CKeybindManager::CKeybindManager() { void CKeybindManager::addKeybind(SKeybind kb) { m_lKeybinds.push_back(kb); + + m_pActiveKeybind = nullptr; } void CKeybindManager::removeKeybind(uint32_t mod, const std::string& key) { @@ -58,6 +60,8 @@ void CKeybindManager::removeKeybind(uint32_t mod, const std::string& key) { break; } } + + m_pActiveKeybind = nullptr; } uint32_t CKeybindManager::stringToModMask(std::string mods) { @@ -92,6 +96,13 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard bool found = false; if (e->state == WL_KEYBOARD_KEY_STATE_PRESSED) { + // clean repeat + if (m_pActiveKeybindEventSource) { + wl_event_source_remove(m_pActiveKeybindEventSource); + m_pActiveKeybindEventSource = nullptr; + m_pActiveKeybind = nullptr; + } + m_dPressedKeycodes.push_back(KEYCODE); m_dPressedKeysyms.push_back(keysym); @@ -102,6 +113,12 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard if (found) shadowKeybinds(keysym, KEYCODE); } else if (e->state == WL_KEYBOARD_KEY_STATE_RELEASED) { + // clean repeat + if (m_pActiveKeybindEventSource) { + wl_event_source_remove(m_pActiveKeybindEventSource); + m_pActiveKeybindEventSource = nullptr; + m_pActiveKeybind = nullptr; + } m_dPressedKeycodes.erase(std::remove(m_dPressedKeycodes.begin(), m_dPressedKeycodes.end(), KEYCODE)); m_dPressedKeysyms.erase(std::remove(m_dPressedKeysyms.begin(), m_dPressedKeysyms.end(), keysym)); @@ -131,6 +148,22 @@ bool CKeybindManager::onAxisEvent(wlr_pointer_axis_event* e) { return !found; } +int repeatKeyHandler(void* data) { + SKeybind** ppActiveKeybind = (SKeybind**)data; + + if (!*ppActiveKeybind) + return 0; + + const auto DISPATCHER = g_pKeybindManager->m_mDispatchers.find((*ppActiveKeybind)->handler); + + Debug::log(LOG, "Keybind repeat triggered, calling dispatcher."); + DISPATCHER->second((*ppActiveKeybind)->arg); + + wl_event_source_timer_update(g_pKeybindManager->m_pActiveKeybindEventSource, 1000 / g_pInputManager->m_pActiveKeyboard->repeatRate); + + return 0; +} + bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string& key, const xkb_keysym_t& keysym, const int& keycode, bool pressed, uint32_t time) { bool found = false; @@ -187,6 +220,15 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string& DISPATCHER->second(k.arg); } + if (k.repeat) { + m_pActiveKeybind = &k; + m_pActiveKeybindEventSource = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, repeatKeyHandler, &m_pActiveKeybind); + + const auto PACTIVEKEEB = g_pInputManager->m_pActiveKeyboard; + + wl_event_source_timer_update(m_pActiveKeybindEventSource, PACTIVEKEEB->repeatDelay); + } + found = true; } diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp index 8bd14512..2ae9b77b 100644 --- a/src/managers/KeybindManager.hpp +++ b/src/managers/KeybindManager.hpp @@ -15,6 +15,7 @@ struct SKeybind { bool locked = false; std::string submap = ""; bool release = false; + bool repeat = false; // DO NOT INITIALIZE bool shadowed = false; @@ -35,6 +36,8 @@ public: std::unordered_map> m_mDispatchers; + wl_event_source* m_pActiveKeybindEventSource = nullptr; + private: std::list m_lKeybinds; std::deque m_dPressedKeysyms; @@ -44,6 +47,8 @@ private: xkb_keysym_t m_kHeldBack = 0; + SKeybind* m_pActiveKeybind = nullptr; + bool handleKeybinds(const uint32_t&, const std::string&, const xkb_keysym_t&, const int&, bool, uint32_t); bool handleInternalKeybinds(xkb_keysym_t);