mirror of
https://github.com/hyprwm/Hyprland
synced 2024-12-23 11:09:49 +01:00
keybinds: track pressed special binds
Ignore mods only if we're processing a special bind, and only if it's pressed. Otherwise we might shadow normal key releases via ignoring mods. Fixes #3240
This commit is contained in:
parent
807fc20525
commit
dcb909df04
2 changed files with 15 additions and 1 deletions
|
@ -71,6 +71,12 @@ CKeybindManager::CKeybindManager() {
|
|||
m_mDispatchers["global"] = global;
|
||||
|
||||
m_tScrollTimer.reset();
|
||||
|
||||
g_pHookSystem->hookDynamic("configReloaded", [this](void* hk, std::any param) {
|
||||
// clear cuz realloc'd
|
||||
m_pActiveKeybind = nullptr;
|
||||
m_vPressedSpecialBinds.clear();
|
||||
});
|
||||
}
|
||||
|
||||
void CKeybindManager::addKeybind(SKeybind kb) {
|
||||
|
@ -422,7 +428,9 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string&
|
|||
|
||||
for (auto& k : m_lKeybinds) {
|
||||
const bool SPECIALDISPATCHER = k.handler == "global" || k.handler == "pass" || k.handler == "mouse";
|
||||
const bool IGNOREMODS = SPECIALDISPATCHER && !pressed; // ignore mods. Pass, global dispatchers should be released immediately once the key is released.
|
||||
const bool SPECIALTRIGGERED =
|
||||
std::find_if(m_vPressedSpecialBinds.begin(), m_vPressedSpecialBinds.end(), [&](const auto& other) { return other == &k; }) != m_vPressedSpecialBinds.end();
|
||||
const bool IGNOREMODS = SPECIALDISPATCHER && !pressed && SPECIALTRIGGERED; // ignore mods. Pass, global dispatchers should be released immediately once the key is released.
|
||||
|
||||
if ((modmask != k.modmask && !IGNOREMODS) || (g_pCompositor->m_sSeat.exclusiveClient && !k.locked) || k.submap != m_szCurrentSelectedSubmap || k.shadowed)
|
||||
continue;
|
||||
|
@ -464,6 +472,11 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string&
|
|||
|
||||
const auto DISPATCHER = m_mDispatchers.find(k.mouse ? "mouse" : k.handler);
|
||||
|
||||
if (SPECIALTRIGGERED && !pressed)
|
||||
std::erase_if(m_vPressedSpecialBinds, [&](const auto& other) { return other == &k; });
|
||||
else if (SPECIALDISPATCHER && pressed)
|
||||
m_vPressedSpecialBinds.push_back(&k);
|
||||
|
||||
// Should never happen, as we check in the ConfigManager, but oh well
|
||||
if (DISPATCHER == m_mDispatchers.end()) {
|
||||
Debug::log(ERR, "Invalid handler in a keybind! (handler {} does not exist)", k.handler);
|
||||
|
|
|
@ -75,6 +75,7 @@ class CKeybindManager {
|
|||
uint32_t m_uLastMouseCode = 0;
|
||||
|
||||
bool m_bIsMouseBindActive = false;
|
||||
std::vector<SKeybind*> m_vPressedSpecialBinds;
|
||||
|
||||
int m_iPassPressed = -1; // used for pass
|
||||
|
||||
|
|
Loading…
Reference in a new issue