mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-11 05:31:14 -03:00
Degrade gracefully when failing to receive cursor position report
Follow up the cursor position report query with a primary device attribute one. When that one arrives, any cursor position response must have arrived too. This allows us to prevent a hang on terminals that only support primary device attribute.
This commit is contained in:
@@ -210,7 +210,7 @@ Optional Commands
|
|||||||
and the second parameter is the column number.
|
and the second parameter is the column number.
|
||||||
Both start at 1.
|
Both start at 1.
|
||||||
|
|
||||||
This is required for terminals that either
|
This is used inside terminals that either
|
||||||
|
|
||||||
- implement the OSC 133 :ref:`click_events <term-compat-osc-133>` feature.
|
- implement the OSC 133 :ref:`click_events <term-compat-osc-133>` feature.
|
||||||
- advertise the :ref:`indn <term-compat-indn>` capability via :ref:`XTGETTCAP <term-compat-xtgettcap>`
|
- advertise the :ref:`indn <term-compat-indn>` capability via :ref:`XTGETTCAP <term-compat-xtgettcap>`
|
||||||
@@ -284,8 +284,8 @@ Optional Commands
|
|||||||
``\e]133;A; click_events=1\x07``
|
``\e]133;A; click_events=1\x07``
|
||||||
-
|
-
|
||||||
- Mark prompt start (OSC 133), with kitty's ``click_events`` extension.
|
- Mark prompt start (OSC 133), with kitty's ``click_events`` extension.
|
||||||
If ``click_events`` is implemented,
|
The ``click_events`` extension enables mouse clicks to move the cursor or select pager items,
|
||||||
the :ref:`cursor position reporting <term-compat-cursor-position-report>` feature is required.
|
assuming that :ref:`cursor position reporting <term-compat-cursor-position-report>` is available.
|
||||||
- FinalTerm, kitty
|
- FinalTerm, kitty
|
||||||
* - ``\e]133;C; cmdline_url= Pt \x07``
|
* - ``\e]133;C; cmdline_url= Pt \x07``
|
||||||
-
|
-
|
||||||
|
|||||||
@@ -756,14 +756,26 @@ pub fn function_set_status(&mut self, status: bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Eq, PartialEq)]
|
#[derive(Clone, Eq, PartialEq)]
|
||||||
pub enum CursorPositionQuery {
|
pub enum CursorPositionQueryKind {
|
||||||
MouseLeft(ViewportPosition),
|
MouseLeft(ViewportPosition),
|
||||||
ScrollbackPush,
|
ScrollbackPush,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Eq, PartialEq)]
|
||||||
|
pub struct CursorPositionQuery {
|
||||||
|
pub kind: CursorPositionQueryKind,
|
||||||
|
pub result: Option<ViewportPosition>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CursorPositionQuery {
|
||||||
|
pub fn new(kind: CursorPositionQueryKind) -> Self {
|
||||||
|
Self { kind, result: None }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Eq, PartialEq)]
|
#[derive(Eq, PartialEq)]
|
||||||
pub enum TerminalQuery {
|
pub enum TerminalQuery {
|
||||||
PrimaryDeviceAttribute,
|
Initial,
|
||||||
CursorPosition(CursorPositionQuery),
|
CursorPosition(CursorPositionQuery),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -87,8 +87,8 @@
|
|||||||
};
|
};
|
||||||
use crate::input::init_input;
|
use crate::input::init_input;
|
||||||
use crate::input_common::{
|
use crate::input_common::{
|
||||||
stop_query, CharEvent, CharInputStyle, CursorPositionQuery, ImplicitEvent, InputData,
|
stop_query, CharEvent, CharInputStyle, CursorPositionQuery, CursorPositionQueryKind,
|
||||||
QueryResponseEvent, ReadlineCmd, TerminalQuery,
|
ImplicitEvent, InputData, QueryResponseEvent, ReadlineCmd, TerminalQuery,
|
||||||
};
|
};
|
||||||
use crate::io::IoChain;
|
use crate::io::IoChain;
|
||||||
use crate::key::ViewportPosition;
|
use crate::key::ViewportPosition;
|
||||||
@@ -276,7 +276,7 @@ pub(crate) fn initial_query(
|
|||||||
query_capabilities_via_dcs(out.by_ref(), vars);
|
query_capabilities_via_dcs(out.by_ref(), vars);
|
||||||
}
|
}
|
||||||
out.write_command(QueryPrimaryDeviceAttribute);
|
out.write_command(QueryPrimaryDeviceAttribute);
|
||||||
Some(TerminalQuery::PrimaryDeviceAttribute)
|
Some(TerminalQuery::Initial)
|
||||||
};
|
};
|
||||||
RefCell::new(query)
|
RefCell::new(query)
|
||||||
});
|
});
|
||||||
@@ -1548,7 +1548,12 @@ pub fn request_cursor_position(&mut self, out: &mut Outputter, q: CursorPosition
|
|||||||
let mut query = self.blocking_query();
|
let mut query = self.blocking_query();
|
||||||
assert!(query.is_none());
|
assert!(query.is_none());
|
||||||
*query = Some(TerminalQuery::CursorPosition(q));
|
*query = Some(TerminalQuery::CursorPosition(q));
|
||||||
out.write_command(QueryCursorPosition);
|
{
|
||||||
|
out.begin_buffering();
|
||||||
|
out.write_command(QueryCursorPosition);
|
||||||
|
out.write_command(QueryPrimaryDeviceAttribute);
|
||||||
|
out.end_buffering();
|
||||||
|
}
|
||||||
drop(query);
|
drop(query);
|
||||||
self.save_screen_state();
|
self.save_screen_state();
|
||||||
}
|
}
|
||||||
@@ -2560,19 +2565,16 @@ fn handle_char_event(&mut self, injected_event: Option<CharEvent>) -> ControlFlo
|
|||||||
FLOG!(reader, "Mouse left click", position);
|
FLOG!(reader, "Mouse left click", position);
|
||||||
self.request_cursor_position(
|
self.request_cursor_position(
|
||||||
&mut Outputter::stdoutput().borrow_mut(),
|
&mut Outputter::stdoutput().borrow_mut(),
|
||||||
CursorPositionQuery::MouseLeft(position),
|
CursorPositionQuery::new(CursorPositionQueryKind::MouseLeft(position)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CharEvent::QueryResponse(query_result) => {
|
CharEvent::QueryResponse(query_result) => {
|
||||||
let maybe_query = self.blocking_query();
|
let mut maybe_query = self.blocking_query();
|
||||||
let query = &maybe_query;
|
let query = &mut maybe_query;
|
||||||
use QueryResponseEvent::*;
|
use QueryResponseEvent::*;
|
||||||
let query = match (&**query, query_result) {
|
let query = match (&mut **query, query_result) {
|
||||||
(
|
(Some(TerminalQuery::Initial), PrimaryDeviceAttributeResponse) => {
|
||||||
Some(TerminalQuery::PrimaryDeviceAttribute),
|
|
||||||
PrimaryDeviceAttributeResponse,
|
|
||||||
) => {
|
|
||||||
if get_kitty_keyboard_capability() == Capability::Unknown {
|
if get_kitty_keyboard_capability() == Capability::Unknown {
|
||||||
set_kitty_keyboard_capability(
|
set_kitty_keyboard_capability(
|
||||||
reader_save_screen_state,
|
reader_save_screen_state,
|
||||||
@@ -2584,15 +2586,28 @@ fn handle_char_event(&mut self, injected_event: Option<CharEvent>) -> ControlFlo
|
|||||||
(
|
(
|
||||||
Some(TerminalQuery::CursorPosition(cursor_pos_query)),
|
Some(TerminalQuery::CursorPosition(cursor_pos_query)),
|
||||||
CursorPositionResponse(cursor_pos),
|
CursorPositionResponse(cursor_pos),
|
||||||
|
) => {
|
||||||
|
cursor_pos_query.result = Some(cursor_pos);
|
||||||
|
maybe_query
|
||||||
|
}
|
||||||
|
(
|
||||||
|
Some(TerminalQuery::CursorPosition(cursor_pos_query)),
|
||||||
|
PrimaryDeviceAttributeResponse,
|
||||||
) => {
|
) => {
|
||||||
let cursor_pos_query = cursor_pos_query.clone();
|
let cursor_pos_query = cursor_pos_query.clone();
|
||||||
drop(maybe_query);
|
drop(maybe_query);
|
||||||
match cursor_pos_query {
|
use CursorPositionQueryKind::*;
|
||||||
CursorPositionQuery::MouseLeft(click_position) => {
|
let cursor_pos = cursor_pos_query.result;
|
||||||
self.mouse_left_click(cursor_pos, click_position);
|
match cursor_pos_query.kind {
|
||||||
|
MouseLeft(click_position) => {
|
||||||
|
if let Some(cursor_pos) = cursor_pos {
|
||||||
|
self.mouse_left_click(cursor_pos, click_position);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CursorPositionQuery::ScrollbackPush => {
|
ScrollbackPush => {
|
||||||
self.screen.push_to_scrollback(cursor_pos.y);
|
if let Some(cursor_pos) = cursor_pos {
|
||||||
|
self.screen.push_to_scrollback(cursor_pos.y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.blocking_query()
|
self.blocking_query()
|
||||||
@@ -3908,12 +3923,12 @@ fn handle_readline_command(&mut self, c: ReadlineCmd) {
|
|||||||
drop(query);
|
drop(query);
|
||||||
self.request_cursor_position(
|
self.request_cursor_position(
|
||||||
&mut Outputter::stdoutput().borrow_mut(),
|
&mut Outputter::stdoutput().borrow_mut(),
|
||||||
CursorPositionQuery::ScrollbackPush,
|
CursorPositionQuery::new(CursorPositionQueryKind::ScrollbackPush),
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
match query {
|
match query {
|
||||||
TerminalQuery::PrimaryDeviceAttribute => panic!(),
|
TerminalQuery::Initial => panic!(),
|
||||||
TerminalQuery::CursorPosition(_) => {
|
TerminalQuery::CursorPosition(_) => {
|
||||||
// TODO: re-queue it I guess.
|
// TODO: re-queue it I guess.
|
||||||
FLOG!(
|
FLOG!(
|
||||||
|
|||||||
Reference in New Issue
Block a user