fix(mouse): prevent unhandled mouse events escape to terminal (#976)

* workaround to not write csi mouse seqs to terminal

* tab: copy selection to clipboard only if selecting was initiated with left click

* cleanup debug log messages

* unset selecting_with_mouse when selection is empty
This commit is contained in:
Thomas Linford 2021-12-28 21:39:20 +01:00 committed by GitHub
parent fc2a79c7a5
commit 6e35f29b0f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 0 deletions

View file

@ -58,6 +58,7 @@ pub(crate) fn stdin_loop(
) {
let mut pasting = false;
let bracketed_paste_start = vec![27, 91, 50, 48, 48, 126]; // \u{1b}[200~
let csi_mouse_sgr_start = vec![27, 91, 60];
let adjusted_keys = keys_to_adjust();
loop {
let mut stdin_buffer = os_input.read_from_stdin();
@ -149,6 +150,19 @@ pub(crate) fn stdin_loop(
continue;
}
}
// FIXME: termion does not properly parse some csi sgr mouse sequences
// like ctrl + click.
// As a workaround, to avoid writing these sequences to tty stdin,
// we discard them.
if let termion::event::Event::Unsupported(_) = key_event {
if raw_bytes.len() > csi_mouse_sgr_start.len()
&& raw_bytes[0..csi_mouse_sgr_start.len()] == csi_mouse_sgr_start
{
continue;
}
}
send_input_instructions
.send(InputInstruction::KeyEvent(key_event, raw_bytes))
.unwrap();

View file

@ -155,6 +155,7 @@ pub(crate) struct Tab {
draw_pane_frames: bool,
session_is_mirrored: bool,
pending_vte_events: HashMap<RawFd, Vec<VteBytes>>,
selecting_with_mouse: bool,
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
@ -370,6 +371,7 @@ impl Tab {
pending_vte_events: HashMap::new(),
connected_clients_in_app,
connected_clients,
selecting_with_mouse: false,
}
}
@ -3368,6 +3370,7 @@ impl Tab {
if let Some(pane) = self.get_pane_at(position, false) {
let relative_position = pane.relative_position(position);
pane.start_selection(&relative_position);
self.selecting_with_mouse = true;
};
}
pub fn handle_right_click(&mut self, position: &Position, client_id: ClientId) {
@ -3393,6 +3396,10 @@ impl Tab {
}
}
pub fn handle_mouse_release(&mut self, position: &Position, client_id: ClientId) {
if !self.selecting_with_mouse {
return;
}
let active_pane_id = self.get_active_pane_id(client_id);
// on release, get the selected text from the active pane, and reset it's selection
let mut selected_text = None;
@ -3414,6 +3421,7 @@ impl Tab {
if let Some(selected_text) = selected_text {
self.write_selection_to_clipboard(&selected_text);
}
self.selecting_with_mouse = false;
}
pub fn handle_mouse_hold(&mut self, position_on_screen: &Position, client_id: ClientId) {
if let Some(active_pane_id) = self.get_active_pane_id(client_id) {