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:
parent
fc2a79c7a5
commit
6e35f29b0f
2 changed files with 22 additions and 0 deletions
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue