fix: non-grabbed evdev on X11 — switch to XTest injection for instant correction
On X11, uinput injection has high latency (kernel → libinput → X server) compared to XTest' which writes events directly into the X11 event queue. Physical key events reach the app before the uinput backspace correction, causing the VNI control key digit to flash on screen. Fix: when non-grabbed mode is entered on X11 (grab failed or ungrab), replace the uinput injector with X11Injector (XTest). XTest events are processed synchronously by X server and take effect before subsequent physical events.
This commit is contained in:
parent
6756340cb0
commit
5f0f059139
1 changed files with 20 additions and 1 deletions
|
|
@ -1309,7 +1309,7 @@ fn run_with_evdev(
|
||||||
_engine_enabled: Arc<AtomicBool>,
|
_engine_enabled: Arc<AtomicBool>,
|
||||||
display: display::DisplayServer,
|
display: display::DisplayServer,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
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)
|
// Use the first device for grab (only one device can be grabbed at a time)
|
||||||
let primary_idx = 0usize;
|
let primary_idx = 0usize;
|
||||||
|
|
@ -1336,6 +1336,17 @@ fn run_with_evdev(
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 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<u16> = HashSet::new();
|
let mut consumed_keys: HashSet<u16> = HashSet::new();
|
||||||
let mut last_active_window = String::new();
|
let mut last_active_window = String::new();
|
||||||
let mut last_window_class = String::new();
|
let mut last_window_class = String::new();
|
||||||
|
|
@ -1374,6 +1385,14 @@ fn run_with_evdev(
|
||||||
let _ = devices[primary_idx].0.ungrab();
|
let _ = devices[primary_idx].0.ungrab();
|
||||||
grabbed = false;
|
grabbed = false;
|
||||||
log_info("[vietc] Non-grabbed mode: polling all evdev devices for keystrokes");
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue