mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-21 11:31:15 -03:00
Fix query response wait confusion over builtin read
Every reader gets their own wait handle which is wrong and not actually needed - it's a singleton. We should probaly make it global. Let's do an intermediate solution for now -- not much time this weekend ;). Fixes #11110
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
use std::ptr;
|
||||
use std::sync::atomic::{AtomicBool, AtomicU8, AtomicUsize, Ordering};
|
||||
use std::sync::{Mutex, MutexGuard};
|
||||
|
||||
// The range of key codes for inputrc-style keyboard functions.
|
||||
pub const R_END_INPUT_FUNCTIONS: usize = (ReadlineCmd::ReverseRepeatJump as usize) + 1;
|
||||
@@ -801,7 +802,7 @@ fn try_readch(&mut self, blocking: bool) -> Option<CharEvent> {
|
||||
reader,
|
||||
"Received interrupt key, giving up waiting for response from terminal"
|
||||
);
|
||||
let ok = self.unblock_input();
|
||||
let ok = unblock_input(self.blocking_wait());
|
||||
assert!(ok);
|
||||
}
|
||||
continue;
|
||||
@@ -1062,7 +1063,9 @@ fn parse_csi(&mut self, buffer: &mut Vec<u8>) -> Option<Key> {
|
||||
if code != 0 || c != b'M' || modifiers.is_some() {
|
||||
return None;
|
||||
}
|
||||
let Some(wait) = self.blocking_wait() else {
|
||||
let wait_guard = self.blocking_wait();
|
||||
let Some(wait) = &*wait_guard else {
|
||||
drop(wait_guard);
|
||||
self.on_mouse_left_click(position);
|
||||
return None;
|
||||
};
|
||||
@@ -1109,7 +1112,8 @@ fn parse_csi(&mut self, buffer: &mut Vec<u8>) -> Option<Key> {
|
||||
return invalid_sequence(buffer);
|
||||
};
|
||||
FLOG!(reader, "Received cursor position report y:", y, "x:", x);
|
||||
let Some(BlockingWait::CursorPosition(wait)) = self.blocking_wait() else {
|
||||
let wait_guard = self.blocking_wait();
|
||||
let Some(BlockingWait::CursorPosition(wait)) = &*wait_guard else {
|
||||
CURSOR_POSITION_REPORTING_SUPPORTED.store(true);
|
||||
return None;
|
||||
};
|
||||
@@ -1124,6 +1128,7 @@ fn parse_csi(&mut self, buffer: &mut Vec<u8>) -> Option<Key> {
|
||||
ImplicitEvent::ScrollbackPushContinuation(y)
|
||||
}
|
||||
};
|
||||
drop(wait_guard);
|
||||
self.push_front(CharEvent::Implicit(continuation));
|
||||
return None;
|
||||
}
|
||||
@@ -1536,15 +1541,13 @@ fn drop_leading_readline_events(&mut self) {
|
||||
}
|
||||
}
|
||||
|
||||
fn blocking_wait(&self) -> Option<&BlockingWait> {
|
||||
None
|
||||
fn blocking_wait(&self) -> MutexGuard<Option<BlockingWait>> {
|
||||
static NO_WAIT: Mutex<Option<BlockingWait>> = Mutex::new(None);
|
||||
NO_WAIT.lock().unwrap()
|
||||
}
|
||||
fn is_blocked(&self) -> bool {
|
||||
false
|
||||
}
|
||||
fn unblock_input(&mut self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn on_mouse_left_click(&mut self, _position: ViewportPosition) {}
|
||||
|
||||
@@ -1559,7 +1562,7 @@ fn enqueue_interrupt_key(&mut self) {
|
||||
let vintr = shell_modes().c_cc[libc::VINTR];
|
||||
if vintr != 0 {
|
||||
let interrupt_evt = CharEvent::from_key(Key::from_single_byte(vintr));
|
||||
if self.unblock_input() {
|
||||
if unblock_input(self.blocking_wait()) {
|
||||
FLOG!(
|
||||
reader,
|
||||
"Received interrupt, giving up on waiting for terminal response"
|
||||
@@ -1590,6 +1593,14 @@ fn has_lookahead(&self) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn unblock_input(mut wait_guard: MutexGuard<Option<BlockingWait>>) -> bool {
|
||||
if wait_guard.is_none() {
|
||||
return false;
|
||||
}
|
||||
*wait_guard = None;
|
||||
true
|
||||
}
|
||||
|
||||
fn invalid_sequence(buffer: &[u8]) -> Option<Key> {
|
||||
FLOG!(
|
||||
reader,
|
||||
|
||||
Reference in New Issue
Block a user