diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 769a7525..b0275fa1 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -2169,6 +2169,7 @@ std::optional CConfigManager::handleBind(const std::string& command bool transparent = false; bool ignoreMods = false; bool multiKey = false; + bool longPress = false; bool hasDescription = false; bool dontInhibit = false; const auto BINDARGS = command.substr(4); @@ -2190,6 +2191,8 @@ std::optional CConfigManager::handleBind(const std::string& command ignoreMods = true; } else if (arg == 's') { multiKey = true; + } else if (arg == 'o') { + longPress = true; } else if (arg == 'd') { hasDescription = true; } else if (arg == 'p') { @@ -2264,7 +2267,7 @@ std::optional CConfigManager::handleBind(const std::string& command g_pKeybindManager->addKeybind(SKeybind{ parsedKey.key, KEYSYMS, parsedKey.keycode, parsedKey.catchAll, MOD, MODS, HANDLER, COMMAND, locked, m_szCurrentSubmap, DESCRIPTION, release, - repeat, mouse, nonConsuming, transparent, ignoreMods, multiKey, hasDescription, dontInhibit}); + repeat, mouse, nonConsuming, transparent, ignoreMods, multiKey, longPress, hasDescription, dontInhibit}); } return {}; diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 5be6a1d9..525f124d 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -567,6 +567,20 @@ int repeatKeyHandler(void* data) { return 0; } +int longPressHandler(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 long press triggered, calling dispatcher."); + DISPATCHER->second((*ppActiveKeybind)->arg); + + return 0; +} + eMultiKeyCase CKeybindManager::mkKeysymSetMatches(const std::set keybindKeysyms, const std::set pressedKeysyms) { // Returns whether two sets of keysyms are equal, partially equal, or not // matching. (Partially matching means that pressed is a subset of bound) @@ -701,6 +715,16 @@ SDispatchResult CKeybindManager::handleKeybinds(const uint32_t modmask, const SP } } + if (k.longPress) { + m_pActiveKeybind = &k; + m_pActiveKeybindEventSource = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, longPressHandler, &m_pActiveKeybind); + + const auto PACTIVEKEEB = g_pSeatManager->keyboard.lock(); + + wl_event_source_timer_update(m_pActiveKeybindEventSource, PACTIVEKEEB->repeatDelay); + continue; + } + const auto DISPATCHER = m_mDispatchers.find(k.mouse ? "mouse" : k.handler); if (SPECIALTRIGGERED && !pressed)