Text for a one-line field on the box goes in at once

Typed key by key into Chromium's address bar right after it opened, the page load and the
autocomplete took turns with the keys and the address came out mangled (chrome://blankchrome//…,
colons gone) — even after selecting the old text first. A one-line field (one typing replaces)
now gets its text pasted in one go, with a short pause before return; terminals and text areas
are still typed key by key. Reproduced and checked on the box's Chromium.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uirha5F5gJt93t3yEx3XcS
This commit is contained in:
王性驊 2026-11-09 10:42:22 +08:00
parent 9e8135ceda
commit 93ead114cd
1 changed files with 12 additions and 3 deletions

View File

@ -1782,11 +1782,12 @@ pub fn box_script(name: &str, v: &Value, scale: (f64, f64)) -> Result<(String, S
}
None => String::new(),
};
let one_line = by_number(v).and_then(|r| r.ok()).is_some_and(|(_, what)| replaces_field(&what, v));
if !text.is_empty() {
script.push_str(&format!(" && {}", type_script(&text)));
script.push_str(&format!(" && {}", type_script_as(&text, one_line)));
}
if submit {
script.push_str(" && sleep 0.06 && xdotool key --clearmodifiers Return");
script.push_str(&format!(" && sleep {} && xdotool key --clearmodifiers Return", if one_line { "0.2" } else { "0.06" }));
}
let script = script.trim_start_matches(" && ").to_string();
(script, format!("已打字({} 個字){field}{}。", text.chars().count(), if submit { ",再按了 return" } else { "" }))
@ -1829,8 +1830,16 @@ pub fn replaces_field(what: &str, v: &Value) -> bool {
}
fn type_script(text: &str) -> String {
type_script_as(text, false)
}
/// `paste`: put the text in at once (clipboard) even when it is short and plain. Into a one-line
/// field that is how it arrives whole: typed key by key into Chromium's address bar right after
/// it opened, the page load and the autocomplete took turns with the keys and the address came
/// out mangled (colons gone, the old text mixed in).
fn type_script_as(text: &str, paste: bool) -> String {
let q = crate::tools::sh_quote(text);
if text.is_ascii() && text.chars().count() <= TYPE_KEYS_MAX_CHARS {
if !paste && text.is_ascii() && text.chars().count() <= TYPE_KEYS_MAX_CHARS {
return format!("xdotool type --clearmodifiers --delay {TYPE_DELAY_MS} -- {q}");
}
format!("printf '%s' {q} > /tmp/anybot-paste.txt && for s in clipboard primary; do setsid xclip -selection $s -i /tmp/anybot-paste.txt </dev/null >/dev/null 2>&1 & done; sleep 0.15; \