From 48cd360e3723d5b6c0b7aa9501e4502b2467a6a1 Mon Sep 17 00:00:00 2001 From: Khoa Vo Date: Sat, 4 Jul 2026 16:51:50 +0700 Subject: [PATCH] =?UTF-8?q?Revert=20"fix:=20skip=20non-grabbed=20evdev=20o?= =?UTF-8?q?n=20X11,=20fall=20through=20to=20X11=20keymap=20capture"=20?= =?UTF-8?q?=E2=80=94=20X11=20keymap=20+=20uinput=20creates=20feedback=20lo?= =?UTF-8?q?op=20through=20XQueryKeymap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- daemon/src/main.rs | 53 +++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/daemon/src/main.rs b/daemon/src/main.rs index b5e621b..630eee3 100644 --- a/daemon/src/main.rs +++ b/daemon/src/main.rs @@ -1309,12 +1309,12 @@ fn run_with_evdev( _engine_enabled: Arc, display: display::DisplayServer, ) -> Result<(), Box> { - let injector = create_injector(display)?; + let mut injector = create_injector(display)?; // Use the first device for grab (only one device can be grabbed at a time) let primary_idx = 0usize; - let mut grabbed = match devices.first() { - Some(_) if daemon.grab_enabled => match devices[primary_idx].0.grab() { + let mut grabbed = if daemon.grab_enabled && !devices.is_empty() { + match devices[primary_idx].0.grab() { Ok(()) => { log_info("[vietc] Keyboard grabbed — race condition eliminated"); true @@ -1324,28 +1324,27 @@ fn run_with_evdev( "[vietc] Could not grab keyboard: {} (run as root for grab)", e )); - // On X11, fall through to keymap capture instead of non-grabbed evdev - #[cfg(feature = "x11")] - if display != display::DisplayServer::Wayland { - log_info("[vietc] X11 detected — trying X11 keymap capture"); - return Ok(()); - } - log_info("[vietc] Falling back to non-grabbing evdev mode (may have race)"); + log_info("[vietc] Falling back to non-grabbing mode (may have race)"); false } - }, - _ => { - log_info("[vietc] No keyboard devices available for grab"); - false } + } else { + if !daemon.grab_enabled { + log_info("[vietc] Keyboard grab disabled (config grab = false)"); + log_info("[vietc] Set grab = true in vietc.toml to enable (needs root)"); + } + false }; - // On X11 without evdev grab, use keymap capture instead of non-grabbed evdev. - // Reason: XTest backspace events feed back into evdev, corrupting the engine. - #[cfg(feature = "x11")] - if !grabbed && display != display::DisplayServer::Wayland { - log_info("[vietc] X11 without evdev grab — switching to X11 keymap capture"); - return Ok(()); + // Non-grabbed on X11: use XTest injection for fast, synchronous correction + if !grabbed { + #[cfg(feature = "x11")] + if display != display::DisplayServer::Wayland { + if let Ok(x11_inj) = vietc_protocol::x11_inject::X11Injector::new() { + injector = Box::new(x11_inj); + log_info("[vietc] Non-grabbed: using X11 injection (faster than uinput)"); + } + } } let mut consumed_keys: HashSet = HashSet::new(); @@ -1380,18 +1379,20 @@ fn run_with_evdev( } if grabbed && idle_polls >= 3 && last_event_time.elapsed() > std::time::Duration::from_millis(200) { - #[cfg(feature = "x11")] - if display != display::DisplayServer::Wayland { - log_info("[vietc] No events via grab on X11 — exiting evdev for X11 keymap capture"); - let _ = devices[primary_idx].0.ungrab(); - return Ok(()); - } log_info( "[vietc] No events received via grab — releasing grab, continuing in non-grabbed evdev mode", ); let _ = devices[primary_idx].0.ungrab(); grabbed = false; log_info("[vietc] Non-grabbed mode: polling all evdev devices for keystrokes"); + // Switch to XTest injection for fast synchronous non-grabbed correction + #[cfg(feature = "x11")] + if display != display::DisplayServer::Wayland { + if let Ok(x11_inj) = vietc_protocol::x11_inject::X11Injector::new() { + injector = Box::new(x11_inj); + log_info("[vietc] Non-grabbed: using X11 injection (faster than uinput)"); + } + } continue; }