Fix garbled text: correct AppRun Wayland detection + atomic injection
- AppRun no longer sets WAYLAND_DISPLAY on X11 (checks for wayland socket) - execute_commands now uses ydotool for both backspaces+text (same device) - Merged execute_commands and execute_commands_with_grab into one function - grab defaults to true in AppImage config
This commit is contained in:
parent
95f661aaa0
commit
c3bc35ddce
2 changed files with 17 additions and 28 deletions
|
|
@ -428,7 +428,7 @@ fn run_with_evdev(
|
||||||
}
|
}
|
||||||
if let Some(ch) = key_to_char(key) {
|
if let Some(ch) = key_to_char(key) {
|
||||||
let commands = daemon.process_key(ch);
|
let commands = daemon.process_key(ch);
|
||||||
execute_commands(&*injector, &commands);
|
execute_commands(&*injector, &commands, false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Grabbing mode: all output goes through uinput only.
|
// Grabbing mode: all output goes through uinput only.
|
||||||
|
|
@ -445,7 +445,7 @@ fn run_with_evdev(
|
||||||
let commands = daemon.process_key(ch);
|
let commands = daemon.process_key(ch);
|
||||||
if !commands.is_empty() {
|
if !commands.is_empty() {
|
||||||
consumed_keys.insert(keycode);
|
consumed_keys.insert(keycode);
|
||||||
execute_commands_with_grab(&*injector, &commands);
|
execute_commands(&*injector, &commands, true);
|
||||||
} else {
|
} else {
|
||||||
injector.send_char(ch);
|
injector.send_char(ch);
|
||||||
}
|
}
|
||||||
|
|
@ -554,7 +554,7 @@ fn run_stdin_mode(
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
let ch = buffer[0] as char;
|
let ch = buffer[0] as char;
|
||||||
let commands = daemon.process_key(ch);
|
let commands = daemon.process_key(ch);
|
||||||
execute_commands(&*injector, &commands);
|
execute_commands(&*injector, &commands, false);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("[vietc] Read error: {}", e);
|
eprintln!("[vietc] Read error: {}", e);
|
||||||
|
|
@ -566,35 +566,21 @@ fn run_stdin_mode(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_commands(injector: &dyn vietc_protocol::KeyInjector, commands: &[OutputCommand]) {
|
/// Execute commands — accumulate backspaces and text, then inject through
|
||||||
for cmd in commands {
|
/// a single channel (ydotool or wtype) to avoid reordering between backspaces
|
||||||
match cmd {
|
/// (uinput) and text (ydotool).
|
||||||
OutputCommand::Type(text) => {
|
fn execute_commands(injector: &dyn vietc_protocol::KeyInjector, commands: &[OutputCommand], grabbed: bool) {
|
||||||
injector.send_string(text);
|
|
||||||
}
|
|
||||||
OutputCommand::Backspace(count) => {
|
|
||||||
injector.send_backspaces(*count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
injector.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Execute commands with keyboard grabbing active.
|
|
||||||
/// Uses inject_replacement to send backspaces + text through a single
|
|
||||||
/// injection call (wtype), avoiding compositor reordering between
|
|
||||||
/// uinput (backspaces) and wtype (text).
|
|
||||||
fn execute_commands_with_grab(injector: &dyn vietc_protocol::KeyInjector, commands: &[OutputCommand]) {
|
|
||||||
let mut pending_backspaces: usize = 0;
|
let mut pending_backspaces: usize = 0;
|
||||||
let mut pending_text = String::new();
|
let mut pending_text = String::new();
|
||||||
|
|
||||||
for cmd in commands {
|
for cmd in commands {
|
||||||
match cmd {
|
match cmd {
|
||||||
OutputCommand::Backspace(count) => {
|
OutputCommand::Backspace(count) => {
|
||||||
// The engine adds +1 to account for the current character key,
|
// The engine adds +1 to account for the current character key.
|
||||||
// but with grabbing that key was never forwarded to the app,
|
// With grabbing that key was never forwarded to the app, so
|
||||||
// so we subtract 1.
|
// we subtract 1. Without grab, the key WAS forwarded, so we
|
||||||
let adjusted = count.saturating_sub(1);
|
// use the full count.
|
||||||
|
let adjusted = if grabbed { count.saturating_sub(1) } else { *count };
|
||||||
pending_backspaces += adjusted;
|
pending_backspaces += adjusted;
|
||||||
}
|
}
|
||||||
OutputCommand::Type(text) => {
|
OutputCommand::Type(text) => {
|
||||||
|
|
|
||||||
|
|
@ -139,11 +139,14 @@ export PATH="$HERE/usr/bin:$PATH"
|
||||||
# Start daemon (kill old non-root one first if we have root)
|
# Start daemon (kill old non-root one first if we have root)
|
||||||
SUDO_CMD=""
|
SUDO_CMD=""
|
||||||
|
|
||||||
# Fix Wayland env for root: sudo resets XDG_RUNTIME_DIR, breaking wl-copy
|
# Fix Wayland env for root: sudo resets XDG_RUNTIME_DIR, breaking wtype/wl-copy.
|
||||||
|
# Only set WAYLAND_DISPLAY if the user actually has a Wayland session.
|
||||||
if [ "$(id -u)" = "0" ] && [ -z "$XDG_RUNTIME_DIR" ] && [ -n "$SUDO_USER" ]; then
|
if [ "$(id -u)" = "0" ] && [ -z "$XDG_RUNTIME_DIR" ] && [ -n "$SUDO_USER" ]; then
|
||||||
USER_UID=$(id -u "$SUDO_USER" 2>/dev/null || echo 1000)
|
USER_UID=$(id -u "$SUDO_USER" 2>/dev/null || echo 1000)
|
||||||
export XDG_RUNTIME_DIR="/run/user/$USER_UID"
|
export XDG_RUNTIME_DIR="/run/user/$USER_UID"
|
||||||
export WAYLAND_DISPLAY="${WAYLAND_DISPLAY:-wayland-0}"
|
if [ -d "/run/user/$USER_UID" ] && ls "/run/user/$USER_UID/wayland-*" >/dev/null 2>&1; then
|
||||||
|
export WAYLAND_DISPLAY="${WAYLAND_DISPLAY:-wayland-0}"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if command -v pkexec >/dev/null && [ -z "$WAYLAND_DISPLAY" ]; then
|
if command -v pkexec >/dev/null && [ -z "$WAYLAND_DISPLAY" ]; then
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue