terminal: Retain relative order of responses (#16456)
Partially addresses #8497 (namely, the occurring with `delta`) As I mentioned in https://github.com/zed-industries/zed/issues/8497#issuecomment-2226896371, zed currently replies to OSC color requests (`OSC 10`, `OSC 11`, ...) out of order when immediately followed by another request (for example `CSI c`). All other terminals that [I have tested](https://github.com/bash/terminal-colorsaurus/blob/main/doc/terminal-survey.md) maintain relative order when replying to requests. ## Solution Respond to the `ColorRequest` in `process_event` (in the same place where other PTY writes happen) instead of queuing it up in the internal event queue. ## Alternative I initially thought that I could handle the color request similarly to the `TextAreaSizeRequest` where the size is stored in `last_content` and updated on `sync`. However this causes the terminal to report out-of-date values when a "set color" sequence is followed by a color request. ## Tests 1. `OSC 11; ?` (request bg color) + `CSI c` (request device attributes): ```shell printf '\e]11;?\e\\ \e[c' && cat -v # Expected result: ^[]11;rgb:dcdc/dcdc/dddd^[\^[[?6c # Current result: ^[[?6c^[]11;rgb:dcdc/dcdc/dddd^[\ (❌) # Result with this PR: ^[]11;rgb:dcdc/dcdc/dddd^[\^[[?6c (✅) # Result with alternative: ^[]11;rgb:dcdc/dcdc/dddd^[\^[[?6c (✅) ``` 2. `OSC 11; rgb:f0f0/f0f0/f0f0` (set bg color) + `OSC 11; ?` (request bg color) ```shell printf '\e]11;rgb:f0f0/f0f0/f0f0\e\\ \e]11;?\e\\' && cat -v # Expected result: ^[]11;rgb:f0f0/f0f0/f0f0^[\ # Current result: ^[]11;rgb:f0f0/f0f0/f0f0^[\ (✅) # Result with this PR: ^[]11;rgb:f0f0/f0f0/f0f0^[\ (✅) # Result with alternative: ^[]11;rgb:OUT_OF_DATE_COLOR_HERE^[\ (❌) ``` Release Notes: - N/A
This commit is contained in:
parent
b7a66e4491
commit
9245015d1a
1 changed files with 14 additions and 11 deletions
|
@ -18,7 +18,7 @@ use alacritty_terminal::{
|
||||||
Config, RenderableCursor, TermMode,
|
Config, RenderableCursor, TermMode,
|
||||||
},
|
},
|
||||||
tty::{self, setup_env},
|
tty::{self, setup_env},
|
||||||
vte::ansi::{ClearMode, Handler, NamedPrivateMode, PrivateMode, Rgb},
|
vte::ansi::{ClearMode, Handler, NamedPrivateMode, PrivateMode},
|
||||||
Term,
|
Term,
|
||||||
};
|
};
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
|
@ -127,7 +127,6 @@ pub enum MaybeNavigationTarget {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
enum InternalEvent {
|
enum InternalEvent {
|
||||||
ColorRequest(usize, Arc<dyn Fn(Rgb) -> String + Sync + Send + 'static>),
|
|
||||||
Resize(TerminalSize),
|
Resize(TerminalSize),
|
||||||
Clear,
|
Clear,
|
||||||
// FocusNextMatch,
|
// FocusNextMatch,
|
||||||
|
@ -688,9 +687,19 @@ impl Terminal {
|
||||||
cx.emit(Event::TitleChanged);
|
cx.emit(Event::TitleChanged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AlacTermEvent::ColorRequest(idx, fun_ptr) => {
|
AlacTermEvent::ColorRequest(index, format) => {
|
||||||
self.events
|
// It's important that the color request is processed here to retain relative order
|
||||||
.push_back(InternalEvent::ColorRequest(*idx, fun_ptr.clone()));
|
// with other PTY writes. Otherwise applications might witness out-of-order
|
||||||
|
// responses to requests. For example: An application sending `OSC 11 ; ? ST`
|
||||||
|
// (color request) followed by `CSI c` (request device attributes) would receive
|
||||||
|
// the response to `CSI c` first.
|
||||||
|
// Instead of locking, we could store the colors in `self.last_content`. But then
|
||||||
|
// we might respond with out of date value if a "set color" sequence is immediately
|
||||||
|
// followed by a color request sequence.
|
||||||
|
let color = self.term.lock().colors()[*index].unwrap_or_else(|| {
|
||||||
|
to_alac_rgb(get_color_at_index(*index, cx.theme().as_ref()))
|
||||||
|
});
|
||||||
|
self.write_to_pty(format(color));
|
||||||
}
|
}
|
||||||
AlacTermEvent::ChildExit(error_code) => {
|
AlacTermEvent::ChildExit(error_code) => {
|
||||||
self.register_task_finished(Some(*error_code), cx);
|
self.register_task_finished(Some(*error_code), cx);
|
||||||
|
@ -714,12 +723,6 @@ impl Terminal {
|
||||||
cx: &mut ModelContext<Self>,
|
cx: &mut ModelContext<Self>,
|
||||||
) {
|
) {
|
||||||
match event {
|
match event {
|
||||||
InternalEvent::ColorRequest(index, format) => {
|
|
||||||
let color = term.colors()[*index].unwrap_or_else(|| {
|
|
||||||
to_alac_rgb(get_color_at_index(*index, cx.theme().as_ref()))
|
|
||||||
});
|
|
||||||
self.write_to_pty(format(color))
|
|
||||||
}
|
|
||||||
InternalEvent::Resize(mut new_size) => {
|
InternalEvent::Resize(mut new_size) => {
|
||||||
new_size.size.height = cmp::max(new_size.line_height, new_size.height());
|
new_size.size.height = cmp::max(new_size.line_height, new_size.height());
|
||||||
new_size.size.width = cmp::max(new_size.cell_width, new_size.width());
|
new_size.size.width = cmp::max(new_size.cell_width, new_size.width());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue