mirror of
https://github.com/fish-shell/fish-shell
synced 2024-11-10 23:24:39 +00:00
Correct handling of SGR mouse tracking events
They are of variable length, taking semicolon-separated ASCII characters and not single chars/bytes as the parameters. Additionally, the global maximum size for a CSI is 16 characters (NPAR), even though I believe the maximum possible mouse-tracking CSI is 12 characters.
This commit is contained in:
parent
7e77dc8964
commit
774488686c
1 changed files with 24 additions and 5 deletions
|
@ -509,6 +509,10 @@ class event_queue_peeker_t {
|
|||
return count;
|
||||
}
|
||||
|
||||
constexpr size_t max_len() const {
|
||||
return N;
|
||||
}
|
||||
|
||||
void consume() {
|
||||
consumed_ = true;
|
||||
}
|
||||
|
@ -528,7 +532,9 @@ class event_queue_peeker_t {
|
|||
};
|
||||
|
||||
bool inputter_t::have_mouse_tracking_csi() {
|
||||
event_queue_peeker_t<12> peeker(event_queue_);
|
||||
// Maximum length of any CSI is NPAR (which is nominally 16), although this does not account for
|
||||
// user input intermixed with pseudo input generated by the tty emulator.
|
||||
event_queue_peeker_t<16> peeker(event_queue_);
|
||||
|
||||
// Check for the CSI first
|
||||
if (peeker.next().maybe_char() != L'\x1B'
|
||||
|
@ -540,11 +546,24 @@ bool inputter_t::have_mouse_tracking_csi() {
|
|||
size_t length = 0;
|
||||
if (next == L'M') {
|
||||
// Generic X10 or modified VT200 sequence. It doesn't matter which, they're both 6 chars
|
||||
// reporting the button that was clicked and its location.
|
||||
// (although in mode 1005, the characters may be unicode and not necessarily just one byte
|
||||
// long) reporting the button that was clicked and its location.
|
||||
length = 6;
|
||||
} else if (next == L'P') {
|
||||
// VT200 mouse highlighting. 12 characters, comes after generic button press event.
|
||||
length = 12;
|
||||
} else if (next == L'<') {
|
||||
// Extended (SGR/1006) mouse reporting mode, with semicolon-separated parameters for button
|
||||
// code, Px, and Py, ending with 'M' for button press or 'm' for button release.
|
||||
while (true) {
|
||||
next = peeker.next().maybe_char();
|
||||
if (next == L'M' || next == L'm') {
|
||||
// However much we've read, we've consumed the CSI in its entirety.
|
||||
length = peeker.len();
|
||||
break;
|
||||
}
|
||||
if (peeker.len() == 16) {
|
||||
// This is likely a malformed mouse-reporting CSI but we can't do anything about it.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (next == L't') {
|
||||
// VT200 button released in mouse highlighting mode at valid text location. 5 chars.
|
||||
length = 5;
|
||||
|
|
Loading…
Reference in a new issue