From d8118364ab71e305e037ceee21a3bedda570d7b0 Mon Sep 17 00:00:00 2001 From: littleblack111 Date: Thu, 31 Oct 2024 00:27:38 +0800 Subject: [PATCH 1/6] bind: new long press option impl #8245 --- src/config/ConfigManager.cpp | 5 ++++- src/managers/KeybindManager.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 909dfc636c3..fe06166b008 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -2163,6 +2163,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); @@ -2184,6 +2185,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') { @@ -2258,7 +2261,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 5be6a1d9ed7..525f124dc8b 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) From 338252cb126853c7708b6495f38063c75b0721d8 Mon Sep 17 00:00:00 2001 From: littleblack111 Date: Thu, 31 Oct 2024 10:45:33 +0800 Subject: [PATCH 2/6] fix: added longPress to SKeybind --- src/managers/KeybindManager.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp index 24a098368df..f9ecd79c3fd 100644 --- a/src/managers/KeybindManager.hpp +++ b/src/managers/KeybindManager.hpp @@ -28,6 +28,7 @@ struct SKeybind { std::string description = ""; bool release = false; bool repeat = false; + bool longPress = false; bool mouse = false; bool nonConsuming = false; bool transparent = false; From dd3caeb9ec699901eda762aa9f33f054e9bc9c91 Mon Sep 17 00:00:00 2001 From: littleblack111 Date: Thu, 31 Oct 2024 10:59:48 +0800 Subject: [PATCH 3/6] only allow longPress if release is not set --- src/config/ConfigManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index fe06166b008..a16e7270f07 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -2185,8 +2185,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 == 'o' && !release) { + longPress = true; } else if (arg == 'd') { hasDescription = true; } else if (arg == 'p') { From 0f961f42f557099f6c22497341d97aa5b97bde13 Mon Sep 17 00:00:00 2001 From: littleblack111 Date: Sun, 3 Nov 2024 10:13:26 +0800 Subject: [PATCH 4/6] fix: compatibility check --- src/config/ConfigManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index a16e7270f07..e5684c6b0b6 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -2185,7 +2185,7 @@ std::optional CConfigManager::handleBind(const std::string& command ignoreMods = true; } else if (arg == 's') { multiKey = true; - } else if (arg == 'o' && !release) { + } else if (arg == 'o') { longPress = true; } else if (arg == 'd') { hasDescription = true; @@ -2196,8 +2196,8 @@ std::optional CConfigManager::handleBind(const std::string& command } } - if (release && repeat) - return "flags r and e are mutually exclusive"; + if ((longPress || release) && repeat) + return "flags e is mutually exclusive with r and o"; if (mouse && (repeat || release || locked)) return "flag m is exclusive"; From cb82b33a2961ba521c72ed75d8975f06329b4f7c Mon Sep 17 00:00:00 2001 From: littleblack111 Date: Mon, 4 Nov 2024 17:16:19 +0800 Subject: [PATCH 5/6] fix: wrong arg order regarding struct SKeybind --- src/config/ConfigManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index e5684c6b0b6..fd6d0b0a66a 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -2261,7 +2261,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, longPress, hasDescription, dontInhibit}); + repeat, longPress, mouse, nonConsuming, transparent, ignoreMods, multiKey, hasDescription, dontInhibit}); } return {}; From 39b12496b77ada278cf23e26eb7b31b8e944172a Mon Sep 17 00:00:00 2001 From: littleblack111 Date: Mon, 4 Nov 2024 22:16:53 +0800 Subject: [PATCH 6/6] add: longPress to the bindRequest --- src/debug/HyprCtl.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index 93e0f620ba3..fefbe11b074 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -838,6 +838,7 @@ std::string bindsRequest(eHyprCtlOutputFormat format, std::string request) { "mouse": {}, "release": {}, "repeat": {}, + "longPress": {}, "non_consuming": {}, "has_description": {}, "modmask": {}, @@ -849,7 +850,7 @@ std::string bindsRequest(eHyprCtlOutputFormat format, std::string request) { "dispatcher": "{}", "arg": "{}" }},)#", - kb.locked ? "true" : "false", kb.mouse ? "true" : "false", kb.release ? "true" : "false", kb.repeat ? "true" : "false", kb.nonConsuming ? "true" : "false", + kb.locked ? "true" : "false", kb.mouse ? "true" : "false", kb.release ? "true" : "false", kb.repeat ? "true" : "false", kb.longPress ? "true" : "false", kb.nonConsuming ? "true" : "false", kb.hasDescription ? "true" : "false", kb.modmask, escapeJSONStrings(kb.submap), escapeJSONStrings(kb.key), kb.keycode, kb.catchAll ? "true" : "false", escapeJSONStrings(kb.description), escapeJSONStrings(kb.handler), escapeJSONStrings(kb.arg)); }