From 63cae4765a2bde8181abd868022c2eaade2dc411 Mon Sep 17 00:00:00 2001 From: Khoa Vo Date: Sat, 4 Jul 2026 17:18:29 +0700 Subject: [PATCH] fix: remove MSC_SCAN fallback, deduplicate multi-device events in non-grabbed mode - Remove MSC_SCAN/MSC event processing that could cause double-processing - In non-grabbed evdev mode, only process engine events from primary device to prevent doubled characters when multiple keyboard devices report same keys - Add per-key diagnostic logging for non-grabbed path --- daemon/src/main.rs | 50 +++++++++------------------------------------- 1 file changed, 9 insertions(+), 41 deletions(-) diff --git a/daemon/src/main.rs b/daemon/src/main.rs index 630eee3..79d901a 100644 --- a/daemon/src/main.rs +++ b/daemon/src/main.rs @@ -1468,50 +1468,12 @@ fn run_with_evdev( }; last_event_time = std::time::Instant::now(); - // Collect all EV_KEY keycodes first so we can skip redundant MSC_SCAN events - let mut key_processed: HashSet = HashSet::new(); - for event in &event_list { - if event.event_type() == evdev::EventType::KEY { - key_processed.insert(event.code()); - } - } - - // Cache last MSC_SCAN keycode (VM workaround: some VMs emit EV_MSC instead of EV_KEY) - let mut last_msc_code: Option = None; for event in event_list { - let ev_type = event.event_type(); - let ev_code = event.code(); - let ev_value = event.value(); - - // Handle both EV_KEY (normal) and EV_MSC/MSC_SCAN (VM fallback) - let is_key = ev_type == evdev::EventType::KEY; - let is_msc_key = !is_key && ev_type == evdev::EventType::MISC && ev_code == 4; - if !is_key && !is_msc_key { + if event.event_type() != evdev::EventType::KEY { continue; } - - let (keycode_val, value) = if is_key { - (ev_code, ev_value) - } else { - // MSC_SCAN contains Linux keycode in value. - // Skip if this keycode was already processed as EV_KEY. - let scan_code = ev_value as u16; - if key_processed.contains(&scan_code) { - continue; - } - let is_press = last_msc_code.map_or(true, |prev| prev != ev_code); - last_msc_code = Some(ev_code); - if !is_press { - continue; - } - let code = if ev_value >= 0 && ev_value <= KEY_MAX as i32 { - ev_value as u16 - } else { - continue; - }; - (code, 1i32) - }; - let keycode = keycode_val; + let keycode = event.code(); + let value = event.value(); let key = evdev::Key(keycode); // Update key state dynamically @@ -1565,6 +1527,12 @@ fn run_with_evdev( } } + // In non-grabbed mode, only process engine from primary device (i==0) + // to avoid double-processing when multiple keyboard devices report same keys + if !grabbed && i != 0 { + continue; + } + if !grabbed { if value != 1 { continue;