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 mut pasting = false;
|
||||||
let bracketed_paste_start = vec![27, 91, 50, 48, 48, 126]; // \u{1b}[200~
|
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();
|
let adjusted_keys = keys_to_adjust();
|
||||||
loop {
|
loop {
|
||||||
let mut stdin_buffer = os_input.read_from_stdin();
|
let mut stdin_buffer = os_input.read_from_stdin();
|
||||||
|
|
@ -149,6 +150,19 @@ pub(crate) fn stdin_loop(
|
||||||
continue;
|
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_input_instructions
|
||||||
.send(InputInstruction::KeyEvent(key_event, raw_bytes))
|
.send(InputInstruction::KeyEvent(key_event, raw_bytes))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,7 @@ pub(crate) struct Tab {
|
||||||
draw_pane_frames: bool,
|
draw_pane_frames: bool,
|
||||||
session_is_mirrored: bool,
|
session_is_mirrored: bool,
|
||||||
pending_vte_events: HashMap<RawFd, Vec<VteBytes>>,
|
pending_vte_events: HashMap<RawFd, Vec<VteBytes>>,
|
||||||
|
selecting_with_mouse: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
||||||
|
|
@ -370,6 +371,7 @@ impl Tab {
|
||||||
pending_vte_events: HashMap::new(),
|
pending_vte_events: HashMap::new(),
|
||||||
connected_clients_in_app,
|
connected_clients_in_app,
|
||||||
connected_clients,
|
connected_clients,
|
||||||
|
selecting_with_mouse: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3368,6 +3370,7 @@ impl Tab {
|
||||||
if let Some(pane) = self.get_pane_at(position, false) {
|
if let Some(pane) = self.get_pane_at(position, false) {
|
||||||
let relative_position = pane.relative_position(position);
|
let relative_position = pane.relative_position(position);
|
||||||
pane.start_selection(&relative_position);
|
pane.start_selection(&relative_position);
|
||||||
|
self.selecting_with_mouse = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
pub fn handle_right_click(&mut self, position: &Position, client_id: ClientId) {
|
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) {
|
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);
|
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
|
// on release, get the selected text from the active pane, and reset it's selection
|
||||||
let mut selected_text = None;
|
let mut selected_text = None;
|
||||||
|
|
@ -3414,6 +3421,7 @@ impl Tab {
|
||||||
if let Some(selected_text) = selected_text {
|
if let Some(selected_text) = selected_text {
|
||||||
self.write_selection_to_clipboard(&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) {
|
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) {
|
if let Some(active_pane_id) = self.get_active_pane_id(client_id) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue