mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-24 05:41:14 -03:00
Work around torn byte sequences in qemu kbd input with 1ms timeout
As reported on gitter, fish running inside a qemu console randomly fails to recognize multi-byte sequences like "\e[D" (right); it sometimes recognizes the first two bytes as "alt-[" and the last byte as the "D" key. This because8bf8b10f68(Extended & human-friendly keys, 2024-03-30) changed our approach to reading multi-byte key sequences. Previously, we'd wait forever (or rather fish_sequence_key_delay_ms) for the "D" byte. As of8bf8b10f68, we assume the entire sequence is already present in the input buffer; and stop parsing the sequence if stdin is not readable. It would be more technically correct to implement the VT state machine but then we'd probably want to to figure out a timeout or a reset key, in case of transport or terminal issues. Returning early is also what we have historically done for multi-byte code points. Also, other terminal programs have been using it for many years without problems. I don't know why this happens in qemu but it seems we can work around by setting a 1ms timeout. This timeout should be small enough two keys "escape" and "[" typed by a human will still be seen separate. Refs: https://matrix.to/#/!YLTeaulxSDauOOxBoR:matrix.org/$Cfi9wL8FGLAI6_VAQWG2mG_VxsADUPvdPB46P41Jdbs https://matrix.to/#/!YLTeaulxSDauOOxBoR:matrix.org/$O_-LZ1W7Dk6L_4Rj0MyCry6GtO2JQlEas8fH9PrSYT8
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
use std::ptr;
|
||||
use std::sync::atomic::{AtomicBool, AtomicU8, AtomicUsize, Ordering};
|
||||
use std::sync::{Mutex, MutexGuard};
|
||||
use std::time::Duration;
|
||||
|
||||
// The range of key codes for inputrc-style keyboard functions.
|
||||
pub const R_END_INPUT_FUNCTIONS: usize = (ReadlineCmd::ReverseRepeatJump as usize) + 1;
|
||||
@@ -341,7 +342,7 @@ fn readb(in_fd: RawFd, blocking: bool) -> ReadbResult {
|
||||
let select_res = fdset.check_readable(if blocking {
|
||||
Timeout::Forever
|
||||
} else {
|
||||
Timeout::ZERO
|
||||
Timeout::Duration(Duration::from_millis(1))
|
||||
});
|
||||
if select_res < 0 {
|
||||
let err = errno::errno().0;
|
||||
|
||||
Reference in New Issue
Block a user