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
This commit is contained in:
parent
1f4e3d88c8
commit
03ffd08ebb
2 changed files with 30 additions and 23 deletions
|
|
@ -1,9 +1,7 @@
|
||||||
use crate::os_input_output::ClientOsApi;
|
use crate::os_input_output::ClientOsApi;
|
||||||
use crate::InputInstruction;
|
use crate::InputInstruction;
|
||||||
use zellij_utils::channels::SenderWithContext;
|
use zellij_utils::channels::SenderWithContext;
|
||||||
use zellij_utils::input::mouse::{MouseButton, MouseEvent};
|
use zellij_utils::termwiz::input::{InputEvent, InputParser, MouseButtons};
|
||||||
|
|
||||||
use zellij_utils::termwiz::input::{InputEvent, InputParser};
|
|
||||||
|
|
||||||
pub(crate) fn stdin_loop(
|
pub(crate) fn stdin_loop(
|
||||||
os_input: Box<dyn ClientOsApi>,
|
os_input: Box<dyn ClientOsApi>,
|
||||||
|
|
@ -17,8 +15,7 @@ pub(crate) fn stdin_loop(
|
||||||
current_buffer.append(&mut buf.to_vec());
|
current_buffer.append(&mut buf.to_vec());
|
||||||
let maybe_more = false; // read_from_stdin should (hopefully) always empty the STDIN buffer completely
|
let maybe_more = false; // read_from_stdin should (hopefully) always empty the STDIN buffer completely
|
||||||
let parse_input_event = |input_event: InputEvent| {
|
let parse_input_event = |input_event: InputEvent| {
|
||||||
holding_mouse = should_hold_mouse(input_event.clone());
|
if holding_mouse && is_mouse_press_or_hold(&input_event) {
|
||||||
if holding_mouse {
|
|
||||||
let mut poller = os_input.stdin_poller();
|
let mut poller = os_input.stdin_poller();
|
||||||
loop {
|
loop {
|
||||||
let ready = poller.ready();
|
let ready = poller.ready();
|
||||||
|
|
@ -32,30 +29,28 @@ pub(crate) fn stdin_loop(
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
holding_mouse = is_mouse_press_or_hold(&input_event);
|
||||||
|
|
||||||
send_input_instructions
|
send_input_instructions
|
||||||
.send(InputInstruction::KeyEvent(
|
.send(InputInstruction::KeyEvent(
|
||||||
input_event,
|
input_event,
|
||||||
current_buffer.drain(..).collect(),
|
current_buffer.drain(..).collect(),
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
|
||||||
};
|
};
|
||||||
input_parser.parse(&buf, parse_input_event, maybe_more);
|
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 {
|
if let InputEvent::Mouse(mouse_event) = input_event {
|
||||||
let mouse_event = zellij_utils::input::mouse::MouseEvent::from(mouse_event);
|
if mouse_event.mouse_buttons.contains(MouseButtons::LEFT)
|
||||||
if let MouseEvent::Press(button, _point) = mouse_event {
|
|| mouse_event.mouse_buttons.contains(MouseButtons::RIGHT)
|
||||||
match button {
|
{
|
||||||
MouseButton::Left | MouseButton::Right => {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,7 @@ pub(crate) struct Tab {
|
||||||
// it seems that optimization is possible using `active_panes`
|
// it seems that optimization is possible using `active_panes`
|
||||||
focus_pane_id: Option<PaneId>,
|
focus_pane_id: Option<PaneId>,
|
||||||
copy_on_select: bool,
|
copy_on_select: bool,
|
||||||
|
last_mouse_hold_position: Option<Position>,
|
||||||
terminal_emulator_colors: Rc<RefCell<Palette>>,
|
terminal_emulator_colors: Rc<RefCell<Palette>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -354,6 +355,7 @@ impl Tab {
|
||||||
clipboard_provider,
|
clipboard_provider,
|
||||||
focus_pane_id: None,
|
focus_pane_id: None,
|
||||||
copy_on_select: copy_options.copy_on_select,
|
copy_on_select: copy_options.copy_on_select,
|
||||||
|
last_mouse_hold_position: None,
|
||||||
terminal_emulator_colors,
|
terminal_emulator_colors,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1547,7 +1549,7 @@ impl Tab {
|
||||||
relative_position.line.0 + 1
|
relative_position.line.0 + 1
|
||||||
);
|
);
|
||||||
self.write_to_active_terminal(mouse_event.into_bytes(), client_id);
|
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);
|
pane.start_selection(&relative_position, client_id);
|
||||||
self.selecting_with_mouse = true;
|
self.selecting_with_mouse = true;
|
||||||
}
|
}
|
||||||
|
|
@ -1588,6 +1590,8 @@ 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) {
|
||||||
|
self.last_mouse_hold_position = None;
|
||||||
|
|
||||||
if self.floating_panes.panes_are_visible()
|
if self.floating_panes.panes_are_visible()
|
||||||
&& self.floating_panes.pane_is_being_moved_with_mouse()
|
&& 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) {
|
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;
|
let search_selectable = true;
|
||||||
|
|
||||||
if self.floating_panes.panes_are_visible()
|
if self.floating_panes.panes_are_visible()
|
||||||
|
|
@ -1646,7 +1658,7 @@ impl Tab {
|
||||||
|
|
||||||
if let Some(active_pane) = active_pane {
|
if let Some(active_pane) = active_pane {
|
||||||
let relative_position = active_pane.relative_position(position_on_screen);
|
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
|
// ensure that coordinates are valid
|
||||||
let col = (relative_position.column.0 + 1)
|
let col = (relative_position.column.0 + 1)
|
||||||
.max(1)
|
.max(1)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue