keybinds: move to managed pointers

This commit is contained in:
Vaxry 2024-11-18 19:56:26 +00:00
parent 6113f4da7f
commit 936dfedbad
3 changed files with 68 additions and 75 deletions

View file

@ -814,28 +814,28 @@ std::string globalShortcutsRequest(eHyprCtlOutputFormat format, std::string requ
std::string bindsRequest(eHyprCtlOutputFormat format, std::string request) { std::string bindsRequest(eHyprCtlOutputFormat format, std::string request) {
std::string ret = ""; std::string ret = "";
if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) { if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) {
for (auto const& kb : g_pKeybindManager->m_lKeybinds) { for (auto const& kb : g_pKeybindManager->m_vKeybinds) {
ret += "bind"; ret += "bind";
if (kb.locked) if (kb->locked)
ret += "l"; ret += "l";
if (kb.mouse) if (kb->mouse)
ret += "m"; ret += "m";
if (kb.release) if (kb->release)
ret += "r"; ret += "r";
if (kb.repeat) if (kb->repeat)
ret += "e"; ret += "e";
if (kb.nonConsuming) if (kb->nonConsuming)
ret += "n"; ret += "n";
if (kb.hasDescription) if (kb->hasDescription)
ret += "d"; ret += "d";
ret += std::format("\n\tmodmask: {}\n\tsubmap: {}\n\tkey: {}\n\tkeycode: {}\n\tcatchall: {}\n\tdescription: {}\n\tdispatcher: {}\n\targ: {}\n\n", kb.modmask, kb.submap, ret += std::format("\n\tmodmask: {}\n\tsubmap: {}\n\tkey: {}\n\tkeycode: {}\n\tcatchall: {}\n\tdescription: {}\n\tdispatcher: {}\n\targ: {}\n\n", kb->modmask,
kb.key, kb.keycode, kb.catchAll, kb.description, kb.handler, kb.arg); kb->submap, kb->key, kb->keycode, kb->catchAll, kb->description, kb->handler, kb->arg);
} }
} else { } else {
// json // json
ret += "["; ret += "[";
for (auto const& kb : g_pKeybindManager->m_lKeybinds) { for (auto const& kb : g_pKeybindManager->m_vKeybinds) {
ret += std::format( ret += std::format(
R"#( R"#(
{{ {{
@ -855,9 +855,9 @@ std::string bindsRequest(eHyprCtlOutputFormat format, std::string request) {
"dispatcher": "{}", "dispatcher": "{}",
"arg": "{}" "arg": "{}"
}},)#", }},)#",
kb.locked ? "true" : "false", kb.mouse ? "true" : "false", kb.release ? "true" : "false", kb.repeat ? "true" : "false", kb.longPress ? "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->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->catchAll ? "true" : "false", escapeJSONStrings(kb->description), escapeJSONStrings(kb->handler), escapeJSONStrings(kb->arg));
} }
trimTrailingComma(ret); trimTrailingComma(ret);
ret += "]"; ret += "]";

View file

@ -150,7 +150,7 @@ CKeybindManager::CKeybindManager() {
if (m_vActiveKeybinds.size() == 0 || g_pSeatManager->keyboard.expired()) if (m_vActiveKeybinds.size() == 0 || g_pSeatManager->keyboard.expired())
return; return;
for (SKeybind* k : m_vActiveKeybinds) { for (const auto& k : m_vActiveKeybinds) {
const auto DISPATCHER = g_pKeybindManager->m_mDispatchers.find(k->handler); const auto DISPATCHER = g_pKeybindManager->m_mDispatchers.find(k->handler);
Debug::log(LOG, "Keybind repeat triggered, calling dispatcher."); Debug::log(LOG, "Keybind repeat triggered, calling dispatcher.");
@ -168,7 +168,7 @@ CKeybindManager::CKeybindManager() {
static auto P = g_pHookSystem->hookDynamic("configReloaded", [this](void* hk, SCallbackInfo& info, std::any param) { static auto P = g_pHookSystem->hookDynamic("configReloaded", [this](void* hk, SCallbackInfo& info, std::any param) {
// clear cuz realloc'd // clear cuz realloc'd
m_vActiveKeybinds.clear(); m_vActiveKeybinds.clear();
m_pLastLongPressKeybind = nullptr; m_pLastLongPressKeybind.reset();
m_vPressedSpecialBinds.clear(); m_vPressedSpecialBinds.clear();
}); });
} }
@ -187,24 +187,17 @@ CKeybindManager::~CKeybindManager() {
} }
void CKeybindManager::addKeybind(SKeybind kb) { void CKeybindManager::addKeybind(SKeybind kb) {
m_lKeybinds.push_back(kb); m_vKeybinds.emplace_back(makeShared<SKeybind>(kb));
m_vActiveKeybinds.clear(); m_vActiveKeybinds.clear();
m_pLastLongPressKeybind = nullptr; m_pLastLongPressKeybind.reset();
} }
void CKeybindManager::removeKeybind(uint32_t mod, const SParsedKey& key) { void CKeybindManager::removeKeybind(uint32_t mod, const SParsedKey& key) {
for (auto it = m_lKeybinds.begin(); it != m_lKeybinds.end(); ++it) { std::erase_if(m_vKeybinds, [&mod, &key](const auto& el) { return el->modmask == mod && el->key == key.key && el->keycode == key.keycode && el->catchAll == key.catchAll; });
if (it->modmask == mod && it->key == key.key && it->keycode == key.keycode && it->catchAll == key.catchAll) {
it = m_lKeybinds.erase(it);
if (it == m_lKeybinds.end())
break;
}
}
m_vActiveKeybinds.clear(); m_vActiveKeybinds.clear();
m_pLastLongPressKeybind = nullptr; m_pLastLongPressKeybind.reset();
} }
uint32_t CKeybindManager::stringToModMask(std::string mods) { uint32_t CKeybindManager::stringToModMask(std::string mods) {
@ -451,7 +444,7 @@ bool CKeybindManager::onKeyEvent(std::any event, SP<IKeyboard> pKeyboard) {
m_vActiveKeybinds.clear(); m_vActiveKeybinds.clear();
m_pLastLongPressKeybind = nullptr; m_pLastLongPressKeybind.reset();
bool suppressEvent = false; bool suppressEvent = false;
if (e.state == WL_KEYBOARD_KEY_STATE_PRESSED) { if (e.state == WL_KEYBOARD_KEY_STATE_PRESSED) {
@ -612,11 +605,11 @@ eMultiKeyCase CKeybindManager::mkKeysymSetMatches(const std::set<xkb_keysym_t> k
return MK_NO_MATCH; return MK_NO_MATCH;
} }
eMultiKeyCase CKeybindManager::mkBindMatches(const SKeybind keybind) { eMultiKeyCase CKeybindManager::mkBindMatches(const SP<SKeybind> keybind) {
if (mkKeysymSetMatches(keybind.sMkMods, m_sMkMods) != MK_FULL_MATCH) if (mkKeysymSetMatches(keybind->sMkMods, m_sMkMods) != MK_FULL_MATCH)
return MK_NO_MATCH; return MK_NO_MATCH;
return mkKeysymSetMatches(keybind.sMkKeys, m_sMkKeys); return mkKeysymSetMatches(keybind->sMkKeys, m_sMkKeys);
} }
std::string CKeybindManager::getCurrentSubmap() { std::string CKeybindManager::getCurrentSubmap() {
@ -640,35 +633,35 @@ SDispatchResult CKeybindManager::handleKeybinds(const uint32_t modmask, const SP
m_sMkKeys.erase(key.keysym); m_sMkKeys.erase(key.keysym);
} }
for (auto& k : m_lKeybinds) { for (auto& k : m_vKeybinds) {
const bool SPECIALDISPATCHER = k.handler == "global" || k.handler == "pass" || k.handler == "sendshortcut" || k.handler == "mouse"; const bool SPECIALDISPATCHER = k->handler == "global" || k->handler == "pass" || k->handler == "sendshortcut" || k->handler == "mouse";
const bool SPECIALTRIGGERED = const bool SPECIALTRIGGERED =
std::find_if(m_vPressedSpecialBinds.begin(), m_vPressedSpecialBinds.end(), [&](const auto& other) { return other == &k; }) != m_vPressedSpecialBinds.end(); std::find_if(m_vPressedSpecialBinds.begin(), m_vPressedSpecialBinds.end(), [&](const auto& other) { return other == k; }) != m_vPressedSpecialBinds.end();
const bool IGNORECONDITIONS = const bool IGNORECONDITIONS =
SPECIALDISPATCHER && !pressed && SPECIALTRIGGERED; // ignore mods. Pass, global dispatchers should be released immediately once the key is released. SPECIALDISPATCHER && !pressed && SPECIALTRIGGERED; // ignore mods. Pass, global dispatchers should be released immediately once the key is released.
if (!k.dontInhibit && !*PDISABLEINHIBIT && PROTO::shortcutsInhibit->isInhibited()) if (!k->dontInhibit && !*PDISABLEINHIBIT && PROTO::shortcutsInhibit->isInhibited())
continue; continue;
if (!k.locked && g_pSessionLockManager->isSessionLocked()) if (!k->locked && g_pSessionLockManager->isSessionLocked())
continue; continue;
if (!IGNORECONDITIONS && ((modmask != k.modmask && !k.ignoreMods) || k.submap != m_szCurrentSelectedSubmap || k.shadowed)) if (!IGNORECONDITIONS && ((modmask != k->modmask && !k->ignoreMods) || k->submap != m_szCurrentSelectedSubmap || k->shadowed))
continue; continue;
if (k.multiKey) { if (k->multiKey) {
switch (mkBindMatches(k)) { switch (mkBindMatches(k)) {
case MK_NO_MATCH: continue; case MK_NO_MATCH: continue;
case MK_PARTIAL_MATCH: found = true; continue; case MK_PARTIAL_MATCH: found = true; continue;
case MK_FULL_MATCH: found = true; case MK_FULL_MATCH: found = true;
} }
} else if (!key.keyName.empty()) { } else if (!key.keyName.empty()) {
if (key.keyName != k.key) if (key.keyName != k->key)
continue; continue;
} else if (k.keycode != 0) { } else if (k->keycode != 0) {
if (key.keycode != k.keycode) if (key.keycode != k->keycode)
continue; continue;
} else if (k.catchAll) { } else if (k->catchAll) {
if (found || key.submapAtPress != m_szCurrentSelectedSubmap) if (found || key.submapAtPress != m_szCurrentSelectedSubmap)
continue; continue;
} else { } else {
@ -679,8 +672,8 @@ SDispatchResult CKeybindManager::handleKeybinds(const uint32_t modmask, const SP
// oMg such performance hit!!11! // oMg such performance hit!!11!
// this little maneouver is gonna cost us 4µs // this little maneouver is gonna cost us 4µs
const auto KBKEY = xkb_keysym_from_name(k.key.c_str(), XKB_KEYSYM_NO_FLAGS); const auto KBKEY = xkb_keysym_from_name(k->key.c_str(), XKB_KEYSYM_NO_FLAGS);
const auto KBKEYLOWER = xkb_keysym_from_name(k.key.c_str(), XKB_KEYSYM_CASE_INSENSITIVE); const auto KBKEYLOWER = xkb_keysym_from_name(k->key.c_str(), XKB_KEYSYM_CASE_INSENSITIVE);
if (KBKEY == XKB_KEY_NoSymbol && KBKEYLOWER == XKB_KEY_NoSymbol) { if (KBKEY == XKB_KEY_NoSymbol && KBKEYLOWER == XKB_KEY_NoSymbol) {
// Keysym failed to resolve from the key name of the currently iterated bind. // Keysym failed to resolve from the key name of the currently iterated bind.
@ -697,8 +690,8 @@ SDispatchResult CKeybindManager::handleKeybinds(const uint32_t modmask, const SP
continue; continue;
} }
if (pressed && k.release && !SPECIALDISPATCHER) { if (pressed && k->release && !SPECIALDISPATCHER) {
if (k.nonConsuming) if (k->nonConsuming)
continue; continue;
found = true; // suppress the event found = true; // suppress the event
@ -707,7 +700,7 @@ SDispatchResult CKeybindManager::handleKeybinds(const uint32_t modmask, const SP
if (!pressed) { if (!pressed) {
// Require mods to be matching when the key was first pressed. // Require mods to be matching when the key was first pressed.
if (key.modmaskAtPressTime != modmask && !k.ignoreMods) { if (key.modmaskAtPressTime != modmask && !k->ignoreMods) {
// Handle properly `bindr` where a key is itself a bind mod for example: // Handle properly `bindr` where a key is itself a bind mod for example:
// "bindr = SUPER, SUPER_L, exec, $launcher". // "bindr = SUPER, SUPER_L, exec, $launcher".
// This needs to be handled separately for the above case, because `key.modmaskAtPressTime` is set // This needs to be handled separately for the above case, because `key.modmaskAtPressTime` is set
@ -716,8 +709,8 @@ SDispatchResult CKeybindManager::handleKeybinds(const uint32_t modmask, const SP
if (keycodeToModifier(key.keycode) == key.modmaskAtPressTime) if (keycodeToModifier(key.keycode) == key.modmaskAtPressTime)
continue; continue;
} else if (!k.release && !SPECIALDISPATCHER) { } else if (!k->release && !SPECIALDISPATCHER) {
if (k.nonConsuming) if (k->nonConsuming)
continue; continue;
found = true; // suppress the event found = true; // suppress the event
@ -725,25 +718,25 @@ SDispatchResult CKeybindManager::handleKeybinds(const uint32_t modmask, const SP
} }
} }
if (k.longPress) { if (k->longPress) {
const auto PACTIVEKEEB = g_pSeatManager->keyboard.lock(); const auto PACTIVEKEEB = g_pSeatManager->keyboard.lock();
m_pLongPressTimer->updateTimeout(std::chrono::milliseconds(PACTIVEKEEB->repeatDelay)); m_pLongPressTimer->updateTimeout(std::chrono::milliseconds(PACTIVEKEEB->repeatDelay));
m_pLastLongPressKeybind = &k; m_pLastLongPressKeybind = k;
continue; continue;
} }
const auto DISPATCHER = m_mDispatchers.find(k.mouse ? "mouse" : k.handler); const auto DISPATCHER = m_mDispatchers.find(k->mouse ? "mouse" : k->handler);
if (SPECIALTRIGGERED && !pressed) if (SPECIALTRIGGERED && !pressed)
std::erase_if(m_vPressedSpecialBinds, [&](const auto& other) { return other == &k; }); std::erase_if(m_vPressedSpecialBinds, [&](const auto& other) { return other == k; });
else if (SPECIALDISPATCHER && pressed) else if (SPECIALDISPATCHER && pressed)
m_vPressedSpecialBinds.push_back(&k); m_vPressedSpecialBinds.push_back(k);
// Should never happen, as we check in the ConfigManager, but oh well // Should never happen, as we check in the ConfigManager, but oh well
if (DISPATCHER == m_mDispatchers.end()) { if (DISPATCHER == m_mDispatchers.end()) {
Debug::log(ERR, "Invalid handler in a keybind! (handler {} does not exist)", k.handler); Debug::log(ERR, "Invalid handler in a keybind! (handler {} does not exist)", k->handler);
} else { } else {
// call the dispatcher // call the dispatcher
Debug::log(LOG, "Keybind triggered, calling dispatcher ({}, {}, {})", modmask, key.keyName, key.keysym); Debug::log(LOG, "Keybind triggered, calling dispatcher ({}, {}, {})", modmask, key.keyName, key.keysym);
@ -751,27 +744,27 @@ SDispatchResult CKeybindManager::handleKeybinds(const uint32_t modmask, const SP
m_iPassPressed = (int)pressed; m_iPassPressed = (int)pressed;
// if the dispatchers says to pass event then we will // if the dispatchers says to pass event then we will
if (k.handler == "mouse") if (k->handler == "mouse")
res = DISPATCHER->second((pressed ? "1" : "0") + k.arg); res = DISPATCHER->second((pressed ? "1" : "0") + k->arg);
else else
res = DISPATCHER->second(k.arg); res = DISPATCHER->second(k->arg);
m_iPassPressed = -1; m_iPassPressed = -1;
if (k.handler == "submap") { if (k->handler == "submap") {
found = true; // don't process keybinds on submap change. found = true; // don't process keybinds on submap change.
break; break;
} }
} }
if (k.repeat) { if (k->repeat) {
const auto PACTIVEKEEB = g_pSeatManager->keyboard.lock(); const auto PACTIVEKEEB = g_pSeatManager->keyboard.lock();
m_vActiveKeybinds.push_back(&k); m_vActiveKeybinds.push_back(k);
m_pRepeatKeyTimer->updateTimeout(std::chrono::milliseconds(PACTIVEKEEB->repeatDelay)); m_pRepeatKeyTimer->updateTimeout(std::chrono::milliseconds(PACTIVEKEEB->repeatDelay));
} }
if (!k.nonConsuming) if (!k->nonConsuming)
found = true; found = true;
} }
@ -792,17 +785,17 @@ SDispatchResult CKeybindManager::handleKeybinds(const uint32_t modmask, const SP
void CKeybindManager::shadowKeybinds(const xkb_keysym_t& doesntHave, const uint32_t doesntHaveCode) { void CKeybindManager::shadowKeybinds(const xkb_keysym_t& doesntHave, const uint32_t doesntHaveCode) {
// shadow disables keybinds after one has been triggered // shadow disables keybinds after one has been triggered
for (auto& k : m_lKeybinds) { for (auto& k : m_vKeybinds) {
bool shadow = false; bool shadow = false;
if (k.handler == "global" || k.transparent) if (k->handler == "global" || k->transparent)
continue; // can't be shadowed continue; // can't be shadowed
if (k.multiKey && (mkBindMatches(k) == MK_FULL_MATCH)) if (k->multiKey && (mkBindMatches(k) == MK_FULL_MATCH))
shadow = true; shadow = true;
else { else {
const auto KBKEY = xkb_keysym_from_name(k.key.c_str(), XKB_KEYSYM_CASE_INSENSITIVE); const auto KBKEY = xkb_keysym_from_name(k->key.c_str(), XKB_KEYSYM_CASE_INSENSITIVE);
const auto KBKEYUPPER = xkb_keysym_to_upper(KBKEY); const auto KBKEYUPPER = xkb_keysym_to_upper(KBKEY);
for (auto const& pk : m_dPressedKeys) { for (auto const& pk : m_dPressedKeys) {
@ -815,7 +808,7 @@ void CKeybindManager::shadowKeybinds(const xkb_keysym_t& doesntHave, const uint3
} }
} }
if (pk.keycode != 0 && pk.keycode == k.keycode) { if (pk.keycode != 0 && pk.keycode == k->keycode) {
shadow = true; shadow = true;
if (pk.keycode == doesntHaveCode && doesntHaveCode != 0) { if (pk.keycode == doesntHaveCode && doesntHaveCode != 0) {
@ -826,7 +819,7 @@ void CKeybindManager::shadowKeybinds(const xkb_keysym_t& doesntHave, const uint3
} }
} }
k.shadowed = shadow; k->shadowed = shadow;
} }
} }
@ -1004,7 +997,7 @@ SDispatchResult CKeybindManager::kill(std::string args) {
} }
void CKeybindManager::clearKeybinds() { void CKeybindManager::clearKeybinds() {
m_lKeybinds.clear(); m_vKeybinds.clear();
} }
static SDispatchResult toggleActiveFloatingCore(std::string args, std::optional<bool> floatState) { static SDispatchResult toggleActiveFloatingCore(std::string args, std::optional<bool> floatState) {
@ -2182,8 +2175,8 @@ SDispatchResult CKeybindManager::setSubmap(std::string submap) {
return {}; return {};
} }
for (auto const& k : g_pKeybindManager->m_lKeybinds) { for (const auto& k : g_pKeybindManager->m_vKeybinds) {
if (k.submap == submap) { if (k->submap == submap) {
m_szCurrentSelectedSubmap = submap; m_szCurrentSelectedSubmap = submap;
Debug::log(LOG, "Changed keybind submap to {}", submap); Debug::log(LOG, "Changed keybind submap to {}", submap);
g_pEventManager->postEvent(SHyprIPCEvent{"submap", submap}); g_pEventManager->postEvent(SHyprIPCEvent{"submap", submap});

View file

@ -104,7 +104,7 @@ class CKeybindManager {
bool m_bGroupsLocked = false; bool m_bGroupsLocked = false;
std::list<SKeybind> m_lKeybinds; std::vector<SP<SKeybind>> m_vKeybinds;
//since we cant find keycode through keyname in xkb: //since we cant find keycode through keyname in xkb:
//on sendshortcut call, we once search for keyname (e.g. "g") the correct keycode (e.g. 42) //on sendshortcut call, we once search for keyname (e.g. "g") the correct keycode (e.g. 42)
@ -119,15 +119,15 @@ class CKeybindManager {
inline static std::string m_szCurrentSelectedSubmap = ""; inline static std::string m_szCurrentSelectedSubmap = "";
std::vector<SKeybind*> m_vActiveKeybinds; std::vector<WP<SKeybind>> m_vActiveKeybinds;
SKeybind* m_pLastLongPressKeybind = nullptr; WP<SKeybind> m_pLastLongPressKeybind;
SP<CEventLoopTimer> m_pLongPressTimer, m_pRepeatKeyTimer; SP<CEventLoopTimer> m_pLongPressTimer, m_pRepeatKeyTimer;
uint32_t m_uTimeLastMs = 0; uint32_t m_uTimeLastMs = 0;
uint32_t m_uLastCode = 0; uint32_t m_uLastCode = 0;
uint32_t m_uLastMouseCode = 0; uint32_t m_uLastMouseCode = 0;
std::vector<SKeybind*> m_vPressedSpecialBinds; std::vector<WP<SKeybind>> m_vPressedSpecialBinds;
int m_iPassPressed = -1; // used for pass int m_iPassPressed = -1; // used for pass
@ -137,7 +137,7 @@ class CKeybindManager {
std::set<xkb_keysym_t> m_sMkKeys = {}; std::set<xkb_keysym_t> m_sMkKeys = {};
std::set<xkb_keysym_t> m_sMkMods = {}; std::set<xkb_keysym_t> m_sMkMods = {};
eMultiKeyCase mkBindMatches(const SKeybind); eMultiKeyCase mkBindMatches(const SP<SKeybind>);
eMultiKeyCase mkKeysymSetMatches(const std::set<xkb_keysym_t>, const std::set<xkb_keysym_t>); eMultiKeyCase mkKeysymSetMatches(const std::set<xkb_keysym_t>, const std::set<xkb_keysym_t>);
bool handleInternalKeybinds(xkb_keysym_t); bool handleInternalKeybinds(xkb_keysym_t);