diff options
| author | MightyPlaza <123664421+MightyPlaza@users.noreply.github.com> | 2024-11-18 19:48:13 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-11-18 19:48:13 +0000 |
| commit | 6113f4da7fa9839645525e57ff841db5bb00e475 (patch) | |
| tree | 2e0f1a0e29185d9ae1e4310c4def7b4b876400c2 /src/managers/KeybindManager.cpp | |
| parent | cc923ad031579a5d1ebe07269d5ecb291331ee51 (diff) | |
keybinds: allow repeating multiple binds (#8290)
Diffstat (limited to 'src/managers/KeybindManager.cpp')
| -rw-r--r-- | src/managers/KeybindManager.cpp | 69 |
1 files changed, 31 insertions, 38 deletions
diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 4d2f4dcc..a0cd01a9 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -144,11 +144,30 @@ CKeybindManager::CKeybindManager() { }, nullptr); + m_pRepeatKeyTimer = makeShared<CEventLoopTimer>( + std::nullopt, + [this](SP<CEventLoopTimer> self, void* data) { + if (m_vActiveKeybinds.size() == 0 || g_pSeatManager->keyboard.expired()) + return; + + for (SKeybind* k : m_vActiveKeybinds) { + const auto DISPATCHER = g_pKeybindManager->m_mDispatchers.find(k->handler); + + Debug::log(LOG, "Keybind repeat triggered, calling dispatcher."); + DISPATCHER->second(k->arg); + } + + const auto PACTIVEKEEB = g_pSeatManager->keyboard.lock(); + self->updateTimeout(std::chrono::milliseconds(1000 / PACTIVEKEEB->repeatRate)); + }, + nullptr); + g_pEventLoopManager->addTimer(m_pLongPressTimer); + g_pEventLoopManager->addTimer(m_pRepeatKeyTimer); static auto P = g_pHookSystem->hookDynamic("configReloaded", [this](void* hk, SCallbackInfo& info, std::any param) { // clear cuz realloc'd - m_pActiveKeybind = nullptr; + m_vActiveKeybinds.clear(); m_pLastLongPressKeybind = nullptr; m_vPressedSpecialBinds.clear(); }); @@ -161,12 +180,16 @@ CKeybindManager::~CKeybindManager() { g_pEventLoopManager->removeTimer(m_pLongPressTimer); m_pLongPressTimer.reset(); } + if (m_pRepeatKeyTimer && g_pEventLoopManager) { + g_pEventLoopManager->removeTimer(m_pRepeatKeyTimer); + m_pRepeatKeyTimer.reset(); + } } void CKeybindManager::addKeybind(SKeybind kb) { m_lKeybinds.push_back(kb); - m_pActiveKeybind = nullptr; + m_vActiveKeybinds.clear(); m_pLastLongPressKeybind = nullptr; } @@ -180,7 +203,7 @@ void CKeybindManager::removeKeybind(uint32_t mod, const SParsedKey& key) { } } - m_pActiveKeybind = nullptr; + m_vActiveKeybinds.clear(); m_pLastLongPressKeybind = nullptr; } @@ -426,11 +449,7 @@ bool CKeybindManager::onKeyEvent(std::any event, SP<IKeyboard> pKeyboard) { .submapAtPress = m_szCurrentSelectedSubmap, }; - if (m_pActiveKeybindEventSource) { - wl_event_source_remove(m_pActiveKeybindEventSource); - m_pActiveKeybindEventSource = nullptr; - m_pActiveKeybind = nullptr; - } + m_vActiveKeybinds.clear(); m_pLastLongPressKeybind = nullptr; @@ -482,11 +501,7 @@ bool CKeybindManager::onAxisEvent(const IPointer::SAxisEvent& e) { m_tScrollTimer.reset(); - if (m_pActiveKeybindEventSource) { - wl_event_source_remove(m_pActiveKeybindEventSource); - m_pActiveKeybindEventSource = nullptr; - m_pActiveKeybind = nullptr; - } + m_vActiveKeybinds.clear(); bool found = false; if (e.source == WL_POINTER_AXIS_SOURCE_WHEEL && e.axis == WL_POINTER_AXIS_VERTICAL_SCROLL) { @@ -525,11 +540,7 @@ bool CKeybindManager::onMouseEvent(const IPointer::SButtonEvent& e) { .modmaskAtPressTime = MODS, }; - if (m_pActiveKeybindEventSource) { - wl_event_source_remove(m_pActiveKeybindEventSource); - m_pActiveKeybindEventSource = nullptr; - m_pActiveKeybind = nullptr; - } + m_vActiveKeybinds.clear(); if (e.state == WL_POINTER_BUTTON_STATE_PRESSED) { m_dPressedKeys.push_back(KEY); @@ -580,22 +591,6 @@ void CKeybindManager::onSwitchOffEvent(const std::string& switchName) { handleKeybinds(0, SPressedKeyWithMods{.keyName = "switch:off:" + switchName}, true); } -int repeatKeyHandler(void* data) { - SKeybind** ppActiveKeybind = (SKeybind**)data; - - if (!*ppActiveKeybind || g_pSeatManager->keyboard.expired()) - 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_pSeatManager->keyboard->repeatRate); - - return 0; -} - eMultiKeyCase CKeybindManager::mkKeysymSetMatches(const std::set<xkb_keysym_t> keybindKeysyms, const std::set<xkb_keysym_t> pressedKeysyms) { // Returns whether two sets of keysyms are equal, partially equal, or not // matching. (Partially matching means that pressed is a subset of bound) @@ -770,12 +765,10 @@ SDispatchResult CKeybindManager::handleKeybinds(const uint32_t modmask, const SP } if (k.repeat) { - m_pActiveKeybind = &k; - m_pActiveKeybindEventSource = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, repeatKeyHandler, &m_pActiveKeybind); - const auto PACTIVEKEEB = g_pSeatManager->keyboard.lock(); - wl_event_source_timer_update(m_pActiveKeybindEventSource, PACTIVEKEEB->repeatDelay); + m_vActiveKeybinds.push_back(&k); + m_pRepeatKeyTimer->updateTimeout(std::chrono::milliseconds(PACTIVEKEEB->repeatDelay)); } if (!k.nonConsuming) |
