keybinds: fix multikey binds breaking after scroll wheel events (#12638)

This commit is contained in:
Mr. Goferito 2025-12-26 23:16:31 +01:00 committed by GitHub
parent 33df518f97
commit d7f26038ee
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 46 additions and 10 deletions

View file

@ -456,6 +456,35 @@ static void testSubmap() {
Tests::killAllWindows();
}
static void testBindsAfterScroll() {
NLog::log("{}Testing binds after scroll", Colors::GREEN);
clearFlag();
OK(getFromSocket("/keyword binds Alt_R,w,exec,touch " + flagFile));
// press keybind before scroll
OK(getFromSocket("/dispatch plugin:test:keybind 1,0,108")); // Alt_R press
OK(getFromSocket("/dispatch plugin:test:keybind 1,4,25")); // w press
EXPECT(attemptCheckFlag(20, 50), true);
OK(getFromSocket("/dispatch plugin:test:keybind 0,4,25")); // w release
OK(getFromSocket("/dispatch plugin:test:keybind 0,0,108")); // Alt_R release
// scroll
OK(getFromSocket("/dispatch plugin:test:scroll 120"));
OK(getFromSocket("/dispatch plugin:test:scroll -120"));
OK(getFromSocket("/dispatch plugin:test:scroll 120"));
// press keybind after scroll
OK(getFromSocket("/dispatch plugin:test:keybind 1,0,108")); // Alt_R press
OK(getFromSocket("/dispatch plugin:test:keybind 1,4,25")); // w press
EXPECT(attemptCheckFlag(20, 50), true);
OK(getFromSocket("/dispatch plugin:test:keybind 0,4,25")); // w release
OK(getFromSocket("/dispatch plugin:test:keybind 0,0,108")); // Alt_R release
clearFlag();
OK(getFromSocket("/keyword unbind Alt_R,w"));
}
static void testSubmapUniversal() {
NLog::log("{}Testing submap universal", Colors::GREEN);
@ -507,6 +536,7 @@ static bool test() {
testShortcutRepeatKeyRelease();
testSubmap();
testSubmapUniversal();
testBindsAfterScroll();
clearFlag();
return !ret;

View file

@ -647,16 +647,22 @@ SDispatchResult CKeybindManager::handleKeybinds(const uint32_t modmask, const SP
bool found = false;
SDispatchResult res;
if (pressed) {
if (keycodeToModifier(key.keycode))
m_mkMods.insert(key.keysym);
else
m_mkKeys.insert(key.keysym);
} else {
if (keycodeToModifier(key.keycode))
m_mkMods.erase(key.keysym);
else
m_mkKeys.erase(key.keysym);
// Skip keysym tracking for events with no keysym (e.g., scroll wheel events).
// Scroll events have keysym=0 and are always "pressed" (never released),
// so without this check, 0 gets inserted into m_mkKeys and never removed,
// breaking multi-key binds (binds flag 's'). See issue #8699.
if (key.keysym != 0) {
if (pressed) {
if (keycodeToModifier(key.keycode))
m_mkMods.insert(key.keysym);
else
m_mkKeys.insert(key.keysym);
} else {
if (keycodeToModifier(key.keycode))
m_mkMods.erase(key.keysym);
else
m_mkKeys.erase(key.keysym);
}
}
for (auto& k : m_keybinds) {