From 2e924c9627fba2178155bdf2177eda84e1daf99a Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Sun, 30 May 2021 12:34:34 -0700 Subject: [PATCH] fix over-reporting of mouse drag events neovim doesn't like it when multiple drag events with the same coordinates are received; it appears to treat that as though the mouse button was double clicked. This commit teaches the mouse report encoding to suppress multiple drag events in succession that have the same payload. refs: https://github.com/wez/wezterm/discussions/823 --- docs/changelog.md | 1 + term/src/terminalstate.rs | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/docs/changelog.md b/docs/changelog.md index 2549bc69d..c20234361 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -33,6 +33,7 @@ As features stabilize some brief notes about them will accumulate here. * Fixed: OSC 52 clipboard escape didn't work in the initial pane spawned in the multiplexer server [#764](https://github.com/wez/wezterm/issues/764) * Fixed: splitting panes in multiplexer could fail after a network reconnect [#781](https://github.com/wez/wezterm/issues/781) * Fixed: multiplexer now propagates toast notifications and color palette to client [#489](https://github.com/wez/wezterm/issues/489) [#748](https://github.com/wez/wezterm/issues/748) +* Fixed: neovim interprets drags as double clicks [#823](https://github.com/wez/wezterm/discussions/823) ### 20210502-154244-3f7122cb diff --git a/term/src/terminalstate.rs b/term/src/terminalstate.rs index cff76d1ca..a4c93445f 100644 --- a/term/src/terminalstate.rs +++ b/term/src/terminalstate.rs @@ -274,6 +274,7 @@ pub struct TerminalState { /// Button events enabled button_event_mouse: bool, current_mouse_button: MouseButton, + last_mouse_move: Option, cursor_visible: bool, dec_line_drawing_mode: bool, @@ -474,6 +475,7 @@ impl TerminalState { any_event_mouse: false, button_event_mouse: false, mouse_tracking: false, + last_mouse_move: None, cursor_visible: true, dec_line_drawing_mode: false, current_mouse_button: MouseButton::None, @@ -726,6 +728,14 @@ impl TerminalState { let reportable = self.any_event_mouse || self.current_mouse_button != MouseButton::None; // Note: self.mouse_tracking on its own is for clicks, not drags! if reportable && (self.button_event_mouse || self.any_event_mouse) { + match self.last_mouse_move.as_ref() { + Some(last) if *last == event => { + return Ok(()); + } + _ => {} + } + self.last_mouse_move.replace(event.clone()); + let button = 32 + self.mouse_report_button_number(&event); if self.sgr_mouse { @@ -2026,9 +2036,11 @@ impl TerminalState { Mode::SetDecPrivateMode(DecPrivateMode::Code(DecPrivateModeCode::MouseTracking)) => { self.mouse_tracking = true; + self.last_mouse_move.take(); } Mode::ResetDecPrivateMode(DecPrivateMode::Code(DecPrivateModeCode::MouseTracking)) => { self.mouse_tracking = false; + self.last_mouse_move.take(); } Mode::SetDecPrivateMode(DecPrivateMode::Code( @@ -2040,32 +2052,40 @@ impl TerminalState { Mode::SetDecPrivateMode(DecPrivateMode::Code(DecPrivateModeCode::ButtonEventMouse)) => { self.button_event_mouse = true; + self.last_mouse_move.take(); } Mode::ResetDecPrivateMode(DecPrivateMode::Code( DecPrivateModeCode::ButtonEventMouse, )) => { self.button_event_mouse = false; + self.last_mouse_move.take(); } Mode::SetDecPrivateMode(DecPrivateMode::Code(DecPrivateModeCode::AnyEventMouse)) => { self.any_event_mouse = true; + self.last_mouse_move.take(); } Mode::ResetDecPrivateMode(DecPrivateMode::Code(DecPrivateModeCode::AnyEventMouse)) => { self.any_event_mouse = false; + self.last_mouse_move.take(); } Mode::SetDecPrivateMode(DecPrivateMode::Code(DecPrivateModeCode::FocusTracking)) => { self.focus_tracking = true; + self.last_mouse_move.take(); } Mode::ResetDecPrivateMode(DecPrivateMode::Code(DecPrivateModeCode::FocusTracking)) => { self.focus_tracking = false; + self.last_mouse_move.take(); } Mode::SetDecPrivateMode(DecPrivateMode::Code(DecPrivateModeCode::SGRMouse)) => { self.sgr_mouse = true; + self.last_mouse_move.take(); } Mode::ResetDecPrivateMode(DecPrivateMode::Code(DecPrivateModeCode::SGRMouse)) => { self.sgr_mouse = false; + self.last_mouse_move.take(); } Mode::SetDecPrivateMode(DecPrivateMode::Code(