From f0e4f6622e3e9addc530119b804d2f71395455e7 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Wed, 14 Jun 2023 04:08:56 -0700 Subject: [PATCH] Implement pass binds (#2503) * Implement pass binds Pass binds run the associated dispatcher but do not prevent windows from receiving the bind. * Fix pass binds not working properly with release binds * Rename `pass` to `nonConsuming` --- src/config/ConfigManager.cpp | 19 +++++++++++-------- src/debug/HyprCtl.cpp | 8 ++++++-- src/managers/KeybindManager.cpp | 6 +++++- src/managers/KeybindManager.hpp | 21 +++++++++++---------- 4 files changed, 33 insertions(+), 21 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index f41a48d9..d86e5410 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -770,11 +770,12 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v // bind[fl]=SUPER,G,exec,dmenu_run // flags - bool locked = false; - bool release = false; - bool repeat = false; - bool mouse = false; - const auto BINDARGS = command.substr(4); + bool locked = false; + bool release = false; + bool repeat = false; + bool mouse = false; + bool nonConsuming = false; + const auto BINDARGS = command.substr(4); for (auto& arg : BINDARGS) { if (arg == 'l') { @@ -785,6 +786,8 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v repeat = true; } else if (arg == 'm') { mouse = true; + } else if (arg == 'n') { + nonConsuming = true; } else { parseError = "bind: invalid flag"; return; @@ -842,11 +845,11 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v if (KEY != "") { if (isNumber(KEY) && std::stoi(KEY) > 9) - g_pKeybindManager->addKeybind(SKeybind{"", std::stoi(KEY), MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat, mouse}); + g_pKeybindManager->addKeybind(SKeybind{"", std::stoi(KEY), MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat, mouse, nonConsuming}); else if (KEY.find("code:") == 0 && isNumber(KEY.substr(5))) - g_pKeybindManager->addKeybind(SKeybind{"", std::stoi(KEY.substr(5)), MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat, mouse}); + g_pKeybindManager->addKeybind(SKeybind{"", std::stoi(KEY.substr(5)), MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat, mouse, nonConsuming}); else - g_pKeybindManager->addKeybind(SKeybind{KEY, -1, MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat, mouse}); + g_pKeybindManager->addKeybind(SKeybind{KEY, -1, MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat, mouse, nonConsuming}); } } diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index 7510e96e..58099bc8 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -592,6 +592,8 @@ std::string bindsRequest(HyprCtl::eHyprCtlOutputFormat format) { ret += "r"; if (kb.repeat) ret += "e"; + if (kb.nonConsuming) + ret += "n"; ret += getFormat("\n\tmodmask: %u\n\tsubmap: %s\n\tkey: %s\n\tkeycode: %d\n\tdispatcher: %s\n\targ: %s\n\n", kb.modmask, kb.submap.c_str(), kb.key.c_str(), kb.keycode, kb.handler.c_str(), kb.arg.c_str()); @@ -607,6 +609,7 @@ std::string bindsRequest(HyprCtl::eHyprCtlOutputFormat format) { "mouse": %s, "release": %s, "repeat": %s, + "non_consuming": %s, "modmask": %u, "submap": "%s", "key": "%s", @@ -614,8 +617,9 @@ std::string bindsRequest(HyprCtl::eHyprCtlOutputFormat format) { "dispatcher": "%s", "arg": "%s" },)#", - kb.locked ? "true" : "false", kb.mouse ? "true" : "false", kb.release ? "true" : "false", kb.repeat ? "true" : "false", kb.modmask, - escapeJSONStrings(kb.submap).c_str(), escapeJSONStrings(kb.key).c_str(), kb.keycode, escapeJSONStrings(kb.handler).c_str(), escapeJSONStrings(kb.arg).c_str()); + kb.locked ? "true" : "false", kb.mouse ? "true" : "false", kb.release ? "true" : "false", kb.repeat ? "true" : "false", kb.nonConsuming ? "true" : "false", + kb.modmask, escapeJSONStrings(kb.submap).c_str(), escapeJSONStrings(kb.key).c_str(), kb.keycode, escapeJSONStrings(kb.handler).c_str(), + escapeJSONStrings(kb.arg).c_str()); } trimTrailingComma(ret); ret += "]"; diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 19b2fba7..17cb6a6f 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -414,6 +414,9 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string& } if (pressed && k.release) { + if (k.nonConsuming) + return false; + // suppress down event m_kHeldBack = keysym; return true; @@ -452,7 +455,8 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string& wl_event_source_timer_update(m_pActiveKeybindEventSource, PACTIVEKEEB->repeatDelay); } - found = true; + if (!k.nonConsuming) + found = true; } return found; diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp index b45e83fa..37cab05c 100644 --- a/src/managers/KeybindManager.hpp +++ b/src/managers/KeybindManager.hpp @@ -11,16 +11,17 @@ class CConfigManager; class CPluginSystem; struct SKeybind { - std::string key = ""; - int keycode = -1; - uint32_t modmask = 0; - std::string handler = ""; - std::string arg = ""; - bool locked = false; - std::string submap = ""; - bool release = false; - bool repeat = false; - bool mouse = false; + std::string key = ""; + int keycode = -1; + uint32_t modmask = 0; + std::string handler = ""; + std::string arg = ""; + bool locked = false; + std::string submap = ""; + bool release = false; + bool repeat = false; + bool mouse = false; + bool nonConsuming = false; // DO NOT INITIALIZE bool shadowed = false;