summaryrefslogtreecommitdiff
path: root/src/managers/KeybindManager.cpp
diff options
context:
space:
mode:
authorMightyPlaza <123664421+MightyPlaza@users.noreply.github.com>2024-11-18 19:48:13 +0000
committerGitHub <noreply@github.com>2024-11-18 19:48:13 +0000
commit6113f4da7fa9839645525e57ff841db5bb00e475 (patch)
tree2e0f1a0e29185d9ae1e4310c4def7b4b876400c2 /src/managers/KeybindManager.cpp
parentcc923ad031579a5d1ebe07269d5ecb291331ee51 (diff)
keybinds: allow repeating multiple binds (#8290)
Diffstat (limited to 'src/managers/KeybindManager.cpp')
-rw-r--r--src/managers/KeybindManager.cpp69
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)