fix: remove space split — paste entire text via clipboard at once
- Splitting spaces into separate uinput events caused them to arrive after the user's next keystrokes, resulting in 'thịtrâm' (no space). - Now paste entire text including spaces via clipboard in one operation. - Trailing spaces may be trimmed by some apps — but this is rarer than the timing-induced space loss from split injection.
This commit is contained in:
parent
eb7960cc77
commit
3ce274c9ae
1 changed files with 12 additions and 37 deletions
|
|
@ -350,59 +350,34 @@ impl UinputInjector {
|
||||||
/// clipboard for Unicode.
|
/// clipboard for Unicode.
|
||||||
fn inject_replacement_atomic(&self, backspaces: usize, text: &str) -> InjectResult {
|
fn inject_replacement_atomic(&self, backspaces: usize, text: &str) -> InjectResult {
|
||||||
// If all ASCII, send keycodes directly — fast and reliable
|
// If all ASCII, send keycodes directly — fast and reliable
|
||||||
if text.chars().all(|c| char_to_linux_keycode(c).is_some()) {
|
if text.chars().all(|c| char_to_linux_keycode(c).is_some() || c == '\n') {
|
||||||
if backspaces > 0 {
|
if backspaces > 0 {
|
||||||
for _ in 0..backspaces {
|
for _ in 0..backspaces {
|
||||||
let _ = self.send_backspace();
|
let _ = self.send_backspace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for ch in text.chars() {
|
for ch in text.chars() {
|
||||||
if ch == '\n' {
|
if ch == '\n' { self.send_enter(); }
|
||||||
self.send_enter();
|
else { let _ = self.send_char(ch); }
|
||||||
} else {
|
|
||||||
let _ = self.send_char(ch);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return InjectResult::Success;
|
return InjectResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unicode text: split into Vietnamese portion (clipboard paste) and
|
// Unicode text: paste entire text via clipboard (includes spaces).
|
||||||
// trailing ASCII whitespace/punctuation (uinput). Clipboard paste
|
// Don't split — splitting causes space to arrive after next keystrokes.
|
||||||
// often trims trailing whitespace, so we send it separately.
|
// Send backspaces first, then clipboard paste everything at once.
|
||||||
let mut split = text.len();
|
|
||||||
for (i, c) in text.char_indices().rev() {
|
|
||||||
if c.is_ascii() && (c.is_whitespace() || matches!(c, '.' | ',' | '!' | '?' | ';' | ':')) {
|
|
||||||
split = i;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let (vn_text, ascii_tail) = text.split_at(split);
|
|
||||||
|
|
||||||
// Backspaces via uinput
|
|
||||||
if backspaces > 0 {
|
if backspaces > 0 {
|
||||||
for _ in 0..backspaces {
|
for _ in 0..backspaces {
|
||||||
let _ = self.send_backspace();
|
let _ = self.send_backspace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clipboard paste for Vietnamese text
|
if self.copy_to_clipboard(text) {
|
||||||
if !vn_text.is_empty() {
|
|
||||||
if self.copy_to_clipboard(vn_text) {
|
|
||||||
self.send_ctrl_v_x11();
|
self.send_ctrl_v_x11();
|
||||||
}
|
} else {
|
||||||
}
|
// Fallback: send base ASCII chars via uinput
|
||||||
|
for ch in text.chars() {
|
||||||
// Trailing ASCII via uinput (spaces, punctuation).
|
let _ = self.send_char(ch);
|
||||||
// Small delay lets the clipboard paste finish before trailing chars arrive.
|
|
||||||
if !ascii_tail.is_empty() {
|
|
||||||
std::thread::sleep(std::time::Duration::from_millis(15));
|
|
||||||
for ch in ascii_tail.chars() {
|
|
||||||
if ch == '\n' {
|
|
||||||
self.send_enter();
|
|
||||||
} else if let Some(kc) = char_to_linux_keycode(ch) {
|
|
||||||
self.send_key_stroke(kc, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue