From 6e35f29b0fabd30ef523d4964153a3f89e53f6f3 Mon Sep 17 00:00:00 2001 From: Thomas Linford Date: Tue, 28 Dec 2021 21:39:20 +0100 Subject: [PATCH] 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 --- zellij-client/src/stdin_handler.rs | 14 ++++++++++++++ zellij-server/src/tab.rs | 8 ++++++++ 2 files changed, 22 insertions(+) diff --git a/zellij-client/src/stdin_handler.rs b/zellij-client/src/stdin_handler.rs index 7d93ac4d..67149b4d 100644 --- a/zellij-client/src/stdin_handler.rs +++ b/zellij-client/src/stdin_handler.rs @@ -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(); diff --git a/zellij-server/src/tab.rs b/zellij-server/src/tab.rs index fc5b0718..77beba73 100644 --- a/zellij-server/src/tab.rs +++ b/zellij-server/src/tab.rs @@ -155,6 +155,7 @@ pub(crate) struct Tab { draw_pane_frames: bool, session_is_mirrored: bool, pending_vte_events: HashMap>, + 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) {