summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2024-11-16 07:21:59 +0800
committerGitHub <noreply@github.com>2024-11-15 23:21:59 +0000
commit7affc34ab43c5d5cbf670759b839a9e990d8bbea (patch)
tree0216331ac38eb1333e91cb786ff8bb2c3aaccb1d /src
parent098e491a43e8b26f4382b48651a4131464bf6a2f (diff)
bind: new long press option (#8302)
--------- Co-authored-by: Vaxry <vaxry@vaxry.net>
Diffstat (limited to 'src')
-rw-r--r--src/config/ConfigManager.cpp13
-rw-r--r--src/debug/HyprCtl.cpp7
-rw-r--r--src/managers/KeybindManager.cpp40
-rw-r--r--src/managers/KeybindManager.hpp5
4 files changed, 53 insertions, 12 deletions
diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp
index 10299277..58db00e9 100644
--- a/src/config/ConfigManager.cpp
+++ b/src/config/ConfigManager.cpp
@@ -2171,6 +2171,7 @@ std::optional<std::string> 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);
@@ -2192,6 +2193,8 @@ std::optional<std::string> 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') {
@@ -2201,8 +2204,8 @@ std::optional<std::string> 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";
@@ -2264,9 +2267,9 @@ std::optional<std::string> CConfigManager::handleBind(const std::string& command
return "Invalid catchall, catchall keybinds are only allowed in submaps.";
}
- 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});
+ g_pKeybindManager->addKeybind(SKeybind{parsedKey.key, KEYSYMS, parsedKey.keycode, parsedKey.catchAll, MOD, MODS, HANDLER,
+ COMMAND, locked, m_szCurrentSubmap, DESCRIPTION, release, repeat, longPress,
+ mouse, nonConsuming, transparent, ignoreMods, multiKey, hasDescription, dontInhibit});
}
return {};
diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp
index 6429e781..c5eba0a7 100644
--- a/src/debug/HyprCtl.cpp
+++ b/src/debug/HyprCtl.cpp
@@ -843,6 +843,7 @@ std::string bindsRequest(eHyprCtlOutputFormat format, std::string request) {
"mouse": {},
"release": {},
"repeat": {},
+ "longPress": {},
"non_consuming": {},
"has_description": {},
"modmask": {},
@@ -854,9 +855,9 @@ 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.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));
+ 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));
}
trimTrailingComma(ret);
ret += "]";
diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp
index f2fdab53..b14637f7 100644
--- a/src/managers/KeybindManager.cpp
+++ b/src/managers/KeybindManager.cpp
@@ -13,6 +13,7 @@
#include "eventLoop/EventLoopManager.hpp"
#include "debug/Log.hpp"
#include "helpers/varlist/VarList.hpp"
+#include "eventLoop/EventLoopManager.hpp"
#include <optional>
#include <iterator>
@@ -130,9 +131,25 @@ CKeybindManager::CKeybindManager() {
m_tScrollTimer.reset();
+ m_pLongPressTimer = makeShared<CEventLoopTimer>(
+ std::nullopt,
+ [this](SP<CEventLoopTimer> self, void* data) {
+ if (!m_pLastLongPressKeybind || g_pSeatManager->keyboard.expired())
+ return;
+
+ const auto DISPATCHER = g_pKeybindManager->m_mDispatchers.find(m_pLastLongPressKeybind->handler);
+
+ Debug::log(LOG, "Long press timeout passed, calling dispatcher.");
+ DISPATCHER->second(m_pLastLongPressKeybind->arg);
+ },
+ nullptr);
+
+ g_pEventLoopManager->addTimer(m_pLongPressTimer);
+
static auto P = g_pHookSystem->hookDynamic("configReloaded", [this](void* hk, SCallbackInfo& info, std::any param) {
// clear cuz realloc'd
- m_pActiveKeybind = nullptr;
+ m_pActiveKeybind = nullptr;
+ m_pLastLongPressKeybind = nullptr;
m_vPressedSpecialBinds.clear();
});
}
@@ -140,12 +157,17 @@ CKeybindManager::CKeybindManager() {
CKeybindManager::~CKeybindManager() {
if (m_pXKBTranslationState)
xkb_state_unref(m_pXKBTranslationState);
+ if (m_pLongPressTimer && g_pEventLoopManager) {
+ g_pEventLoopManager->removeTimer(m_pLongPressTimer);
+ m_pLongPressTimer.reset();
+ }
}
void CKeybindManager::addKeybind(SKeybind kb) {
m_lKeybinds.push_back(kb);
- m_pActiveKeybind = nullptr;
+ m_pActiveKeybind = nullptr;
+ m_pLastLongPressKeybind = nullptr;
}
void CKeybindManager::removeKeybind(uint32_t mod, const SParsedKey& key) {
@@ -158,7 +180,8 @@ void CKeybindManager::removeKeybind(uint32_t mod, const SParsedKey& key) {
}
}
- m_pActiveKeybind = nullptr;
+ m_pActiveKeybind = nullptr;
+ m_pLastLongPressKeybind = nullptr;
}
uint32_t CKeybindManager::stringToModMask(std::string mods) {
@@ -409,6 +432,8 @@ bool CKeybindManager::onKeyEvent(std::any event, SP<IKeyboard> pKeyboard) {
m_pActiveKeybind = nullptr;
}
+ m_pLastLongPressKeybind = nullptr;
+
bool suppressEvent = false;
if (e.state == WL_KEYBOARD_KEY_STATE_PRESSED) {
@@ -705,6 +730,15 @@ SDispatchResult CKeybindManager::handleKeybinds(const uint32_t modmask, const SP
}
}
+ if (k.longPress) {
+ const auto PACTIVEKEEB = g_pSeatManager->keyboard.lock();
+
+ m_pLongPressTimer->updateTimeout(std::chrono::milliseconds(PACTIVEKEEB->repeatDelay));
+ m_pLastLongPressKeybind = &k;
+
+ continue;
+ }
+
const auto DISPATCHER = m_mDispatchers.find(k.mouse ? "mouse" : k.handler);
if (SPECIALTRIGGERED && !pressed)
diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp
index 24a09836..4a0af6e9 100644
--- a/src/managers/KeybindManager.hpp
+++ b/src/managers/KeybindManager.hpp
@@ -8,6 +8,7 @@
#include <functional>
#include <xkbcommon/xkbcommon.h>
#include "../devices/IPointer.hpp"
+#include "eventLoop/EventLoopTimer.hpp"
class CInputManager;
class CConfigManager;
@@ -28,6 +29,7 @@ struct SKeybind {
std::string description = "";
bool release = false;
bool repeat = false;
+ bool longPress = false;
bool mouse = false;
bool nonConsuming = false;
bool transparent = false;
@@ -119,7 +121,8 @@ class CKeybindManager {
inline static std::string m_szCurrentSelectedSubmap = "";
- SKeybind* m_pActiveKeybind = nullptr;
+ SKeybind * m_pActiveKeybind = nullptr, *m_pLastLongPressKeybind = nullptr;
+ SP<CEventLoopTimer> m_pLongPressTimer;
uint32_t m_uTimeLastMs = 0;
uint32_t m_uLastCode = 0;