Avoid overwriting mouse wheel scroll with selection auto-scroll (#4207)

Julia created

Release Notes:

- Fixed an issue where mouse wheel events could be ignored while
selecting text near the top or bottom of the editor with the mouse.

Change summary

crates/editor/src/editor.rs  | 10 +++++-----
crates/editor/src/element.rs |  3 +--
crates/editor/src/scroll.rs  | 22 +++++++++++++++++++++-
3 files changed, 27 insertions(+), 8 deletions(-)

Detailed changes

crates/editor/src/editor.rs 🔗

@@ -281,7 +281,7 @@ pub enum SelectPhase {
     Update {
         position: DisplayPoint,
         goal_column: u32,
-        scroll_position: gpui::Point<f32>,
+        scroll_delta: gpui::Point<f32>,
     },
     End,
 }
@@ -1928,8 +1928,8 @@ impl Editor {
             SelectPhase::Update {
                 position,
                 goal_column,
-                scroll_position,
-            } => self.update_selection(position, goal_column, scroll_position, cx),
+                scroll_delta,
+            } => self.update_selection(position, goal_column, scroll_delta, cx),
             SelectPhase::End => self.end_selection(cx),
         }
     }
@@ -2063,7 +2063,7 @@ impl Editor {
         &mut self,
         position: DisplayPoint,
         goal_column: u32,
-        scroll_position: gpui::Point<f32>,
+        scroll_delta: gpui::Point<f32>,
         cx: &mut ViewContext<Self>,
     ) {
         let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
@@ -2152,7 +2152,7 @@ impl Editor {
             return;
         }
 
-        self.set_scroll_position(scroll_position, cx);
+        self.apply_scroll_delta(scroll_delta, cx);
         cx.notify();
     }
 

crates/editor/src/element.rs 🔗

@@ -531,8 +531,7 @@ impl EditorElement {
             SelectPhase::Update {
                 position: point_for_position.previous_valid,
                 goal_column: point_for_position.exact_unclipped.column(),
-                scroll_position: (position_map.snapshot.scroll_position() + scroll_delta)
-                    .clamp(&gpui::Point::default(), &position_map.scroll_max),
+                scroll_delta,
             },
             cx,
         );

crates/editor/src/scroll.rs 🔗

@@ -327,6 +327,16 @@ impl Editor {
         }
     }
 
+    pub fn apply_scroll_delta(
+        &mut self,
+        scroll_delta: gpui::Point<f32>,
+        cx: &mut ViewContext<Self>,
+    ) {
+        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
+        let position = self.scroll_manager.anchor.scroll_position(&display_map) + scroll_delta;
+        self.set_scroll_position_taking_display_map(position, true, false, display_map, cx);
+    }
+
     pub fn set_scroll_position(
         &mut self,
         scroll_position: gpui::Point<f32>,
@@ -343,12 +353,22 @@ impl Editor {
         cx: &mut ViewContext<Self>,
     ) {
         let map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
+        self.set_scroll_position_taking_display_map(scroll_position, local, autoscroll, map, cx);
+    }
 
+    fn set_scroll_position_taking_display_map(
+        &mut self,
+        scroll_position: gpui::Point<f32>,
+        local: bool,
+        autoscroll: bool,
+        display_map: DisplaySnapshot,
+        cx: &mut ViewContext<Self>,
+    ) {
         hide_hover(self, cx);
         let workspace_id = self.workspace.as_ref().map(|workspace| workspace.1);
         self.scroll_manager.set_scroll_position(
             scroll_position,
-            &map,
+            &display_map,
             local,
             autoscroll,
             workspace_id,