From e7a0f0e8760934f8b6c9fc0fa9acd387fdc93321 Mon Sep 17 00:00:00 2001 From: Hourann Date: Tue, 8 Apr 2025 04:10:14 +0800 Subject: [PATCH] terminal: Fix misaligned mouse selection when inline assist is active (#26112) This PR fixes an issue where mouse selection in the terminal would be offset when the Terminal Inline Assistant was active. The problem was caused by incorrect coordinate translation when handling mouse events with an active inline assistant. The fix adjusts mouse event coordinates by properly accounting for the terminal view's `scroll_top` value when the inline assistant is present, ensuring that text selection precisely follows the mouse cursor position. Closes #26111 Release Notes: - Fixed text selection misalignment in terminal when the inline assistant is active Co-authored-by: Peter Tripp --- crates/terminal_view/src/terminal_element.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/crates/terminal_view/src/terminal_element.rs b/crates/terminal_view/src/terminal_element.rs index 66a7b837719eb29f723c3e6b5c0d6a8262963c8a..e41f535f3e38cf81c70e3050699b564e3e158af1 100644 --- a/crates/terminal_view/src/terminal_element.rs +++ b/crates/terminal_view/src/terminal_element.rs @@ -425,14 +425,23 @@ impl TerminalElement { fn register_mouse_listeners(&mut self, mode: TermMode, hitbox: &Hitbox, window: &mut Window) { let focus = self.focus.clone(); let terminal = self.terminal.clone(); + let terminal_view = self.terminal_view.clone(); self.interactivity.on_mouse_down(MouseButton::Left, { let terminal = terminal.clone(); let focus = focus.clone(); + let terminal_view = terminal_view.clone(); + move |e, window, cx| { window.focus(&focus); + + let scroll_top = terminal_view.read(cx).scroll_top; terminal.update(cx, |terminal, cx| { - terminal.mouse_down(e, cx); + let mut adjusted_event = e.clone(); + if scroll_top > Pixels::ZERO { + adjusted_event.position.y += scroll_top; + } + terminal.mouse_down(&adjusted_event, cx); cx.notify(); }) } @@ -442,6 +451,7 @@ impl TerminalElement { let terminal = self.terminal.clone(); let hitbox = hitbox.clone(); let focus = focus.clone(); + let terminal_view = terminal_view.clone(); move |e: &MouseMoveEvent, phase, window, cx| { if phase != DispatchPhase::Bubble { return; @@ -449,9 +459,15 @@ impl TerminalElement { if e.pressed_button.is_some() && !cx.has_active_drag() && focus.is_focused(window) { let hovered = hitbox.is_hovered(window); + + let scroll_top = terminal_view.read(cx).scroll_top; terminal.update(cx, |terminal, cx| { if terminal.selection_started() || hovered { - terminal.mouse_drag(e, hitbox.bounds, cx); + let mut adjusted_event = e.clone(); + if scroll_top > Pixels::ZERO { + adjusted_event.position.y += scroll_top; + } + terminal.mouse_drag(&adjusted_event, hitbox.bounds, cx); cx.notify(); } })