termina: Fix text selection for first line scrolls up (#26842)

Smit Barmase created

Closes #21626
 
Now scroll will only happen when cursor goes beyond the bounds of
terminal.
 
 Before:
 


https://github.com/user-attachments/assets/9ac48e80-d0e0-44c9-87ad-14ed748de78d


 After:


https://github.com/user-attachments/assets/c697c1fc-a6d2-4b9a-aad4-5b0c79837c2a
 
Release Notes:

- Fixed an issue where selecting the first line in the terminal would
cause it to scroll.

Change summary

crates/terminal/src/terminal.rs | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)

Detailed changes

crates/terminal/src/terminal.rs 🔗

@@ -1523,14 +1523,11 @@ impl Terminal {
 
             // Doesn't make sense to scroll the alt screen
             if !self.last_content.mode.contains(TermMode::ALT_SCREEN) {
-                let scroll_delta = match self.drag_line_delta(e, region) {
+                let scroll_lines = match self.drag_line_delta(e, region) {
                     Some(value) => value,
                     None => return,
                 };
 
-                let scroll_lines =
-                    (scroll_delta / self.last_content.terminal_bounds.line_height) as i32;
-
                 self.events
                     .push_back(InternalEvent::Scroll(AlacScroll::Delta(scroll_lines)));
             }
@@ -1539,18 +1536,21 @@ impl Terminal {
         }
     }
 
-    fn drag_line_delta(&self, e: &MouseMoveEvent, region: Bounds<Pixels>) -> Option<Pixels> {
-        //TODO: Why do these need to be doubled? Probably the same problem that the IME has
-        let top = region.origin.y + (self.last_content.terminal_bounds.line_height * 2.);
-        let bottom = region.bottom_left().y - (self.last_content.terminal_bounds.line_height * 2.);
-        let scroll_delta = if e.position.y < top {
-            (top - e.position.y).pow(1.1)
+    fn drag_line_delta(&self, e: &MouseMoveEvent, region: Bounds<Pixels>) -> Option<i32> {
+        let top = region.origin.y;
+        let bottom = region.bottom_left().y;
+
+        let scroll_lines = if e.position.y < top {
+            let scroll_delta = (top - e.position.y).pow(1.1);
+            (scroll_delta / self.last_content.terminal_bounds.line_height).ceil() as i32
         } else if e.position.y > bottom {
-            -((e.position.y - bottom).pow(1.1))
+            let scroll_delta = -((e.position.y - bottom).pow(1.1));
+            (scroll_delta / self.last_content.terminal_bounds.line_height).floor() as i32
         } else {
-            return None; //Nothing to do
+            return None;
         };
-        Some(scroll_delta)
+
+        Some(scroll_lines)
     }
 
     pub fn mouse_down(&mut self, e: &MouseDownEvent, _cx: &mut Context<Self>) {