From 03ffd08ebbbe4b46978229bd17e25931699c5f59 Mon Sep 17 00:00:00 2001 From: Thomas Linford Date: Sat, 30 Apr 2022 18:46:17 +0200 Subject: [PATCH] fix(mouse): improve mouse event reporting (#1329) * fix: do not rebroadcast mouse press events * fix: do not send generated mouse hold events to applications * begin selecting only if click is on terminal pane --- zellij-client/src/stdin_handler.rs | 37 +++++++++++++----------------- zellij-server/src/tab/mod.rs | 16 +++++++++++-- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/zellij-client/src/stdin_handler.rs b/zellij-client/src/stdin_handler.rs index d8321463..e6794ded 100644 --- a/zellij-client/src/stdin_handler.rs +++ b/zellij-client/src/stdin_handler.rs @@ -1,9 +1,7 @@ use crate::os_input_output::ClientOsApi; use crate::InputInstruction; use zellij_utils::channels::SenderWithContext; -use zellij_utils::input::mouse::{MouseButton, MouseEvent}; - -use zellij_utils::termwiz::input::{InputEvent, InputParser}; +use zellij_utils::termwiz::input::{InputEvent, InputParser, MouseButtons}; pub(crate) fn stdin_loop( os_input: Box, @@ -17,8 +15,7 @@ pub(crate) fn stdin_loop( current_buffer.append(&mut buf.to_vec()); let maybe_more = false; // read_from_stdin should (hopefully) always empty the STDIN buffer completely let parse_input_event = |input_event: InputEvent| { - holding_mouse = should_hold_mouse(input_event.clone()); - if holding_mouse { + if holding_mouse && is_mouse_press_or_hold(&input_event) { let mut poller = os_input.stdin_poller(); loop { let ready = poller.ready(); @@ -32,29 +29,27 @@ pub(crate) fn stdin_loop( )) .unwrap(); } - } else { - send_input_instructions - .send(InputInstruction::KeyEvent( - input_event, - current_buffer.drain(..).collect(), - )) - .unwrap(); } + + holding_mouse = is_mouse_press_or_hold(&input_event); + + send_input_instructions + .send(InputInstruction::KeyEvent( + input_event, + current_buffer.drain(..).collect(), + )) + .unwrap(); }; input_parser.parse(&buf, parse_input_event, maybe_more); } } -fn should_hold_mouse(input_event: InputEvent) -> bool { +fn is_mouse_press_or_hold(input_event: &InputEvent) -> bool { if let InputEvent::Mouse(mouse_event) = input_event { - let mouse_event = zellij_utils::input::mouse::MouseEvent::from(mouse_event); - if let MouseEvent::Press(button, _point) = mouse_event { - match button { - MouseButton::Left | MouseButton::Right => { - return true; - } - _ => {} - } + if mouse_event.mouse_buttons.contains(MouseButtons::LEFT) + || mouse_event.mouse_buttons.contains(MouseButtons::RIGHT) + { + return true; } } false diff --git a/zellij-server/src/tab/mod.rs b/zellij-server/src/tab/mod.rs index 18eb99f3..9f9d4d4e 100644 --- a/zellij-server/src/tab/mod.rs +++ b/zellij-server/src/tab/mod.rs @@ -90,6 +90,7 @@ pub(crate) struct Tab { // it seems that optimization is possible using `active_panes` focus_pane_id: Option, copy_on_select: bool, + last_mouse_hold_position: Option, terminal_emulator_colors: Rc>, } @@ -354,6 +355,7 @@ impl Tab { clipboard_provider, focus_pane_id: None, copy_on_select: copy_options.copy_on_select, + last_mouse_hold_position: None, terminal_emulator_colors, } } @@ -1547,7 +1549,7 @@ impl Tab { relative_position.line.0 + 1 ); self.write_to_active_terminal(mouse_event.into_bytes(), client_id); - } else { + } else if let PaneId::Terminal(_) = pane.pid() { pane.start_selection(&relative_position, client_id); self.selecting_with_mouse = true; } @@ -1588,6 +1590,8 @@ impl Tab { } } pub fn handle_mouse_release(&mut self, position: &Position, client_id: ClientId) { + self.last_mouse_hold_position = None; + if self.floating_panes.panes_are_visible() && self.floating_panes.pane_is_being_moved_with_mouse() { @@ -1629,6 +1633,14 @@ impl Tab { } } pub fn handle_mouse_hold(&mut self, position_on_screen: &Position, client_id: ClientId) { + // determine if event is repeated to enable smooth scrolling + let is_repeated = if let Some(last_position) = self.last_mouse_hold_position { + position_on_screen == &last_position + } else { + false + }; + self.last_mouse_hold_position = Some(*position_on_screen); + let search_selectable = true; if self.floating_panes.panes_are_visible() @@ -1646,7 +1658,7 @@ impl Tab { if let Some(active_pane) = active_pane { let relative_position = active_pane.relative_position(position_on_screen); - if active_pane.mouse_mode() { + if active_pane.mouse_mode() && !is_repeated { // ensure that coordinates are valid let col = (relative_position.column.0 + 1) .max(1)