From b8b951deabaa3c02c96b0d60833abb944cca7001 Mon Sep 17 00:00:00 2001 From: ForLoveOfCats Date: Wed, 17 Aug 2022 18:11:54 -0400 Subject: [PATCH] Clear last-mouse-moved pressed button when that button gets a mouse-up This fixes an annoying issue where if the last mouse moved event was during a drag it would never trigger mouse cursor changes until next mouse move reset it. It makes sense to continue to not change the cursor while the button is pressed so instead this tracks when the mouse button is released in order to update the mouse move event --- crates/gpui/src/platform/event.rs | 2 +- crates/gpui/src/presenter.rs | 94 +++++++++++++++++-------------- 2 files changed, 53 insertions(+), 43 deletions(-) diff --git a/crates/gpui/src/platform/event.rs b/crates/gpui/src/platform/event.rs index 6ac75926be426e2a7512d35ea9c06cd5c7f64047..9a84b8ef2f26a1e67488f3548263037b18be4d28 100644 --- a/crates/gpui/src/platform/event.rs +++ b/crates/gpui/src/platform/event.rs @@ -64,7 +64,7 @@ impl Default for MouseButton { } } -#[derive(Clone, Debug, Default)] +#[derive(Clone, Copy, Debug, Default)] pub struct MouseButtonEvent { pub button: MouseButton, pub position: Vector2F, diff --git a/crates/gpui/src/presenter.rs b/crates/gpui/src/presenter.rs index 023e013d1393428752cd43ea45fc2f0c61fc101a..3e6c97a2087a4b45d5bd0f9890832cb3a4935084 100644 --- a/crates/gpui/src/presenter.rs +++ b/crates/gpui/src/presenter.rs @@ -31,7 +31,7 @@ pub struct Presenter { font_cache: Arc, text_layout_cache: TextLayoutCache, asset_cache: Arc, - last_mouse_moved_event: Option, + last_mouse_moved_event: Option, hovered_region_ids: HashSet, clicked_region: Option, right_clicked_region: Option, @@ -268,15 +268,27 @@ impl Presenter { } } } - Event::MouseUp(e @ MouseButtonEvent { position, .. }) => { + + &Event::MouseUp( + e @ MouseButtonEvent { + position, button, .. + }, + ) => { self.prev_drag_position.take(); if let Some(region) = self.clicked_region.take() { invalidated_views.push(region.view_id); - if region.bounds.contains_point(*position) { + if region.bounds.contains_point(position) { clicked_region = Some((region, MouseRegionEvent::Click(e.clone()))); } } + + if let Some(moved) = &mut self.last_mouse_moved_event { + if moved.pressed_button == Some(button) { + moved.pressed_button = None; + } + } } + Event::MouseMoved(e @ MouseMovedEvent { position, .. }) => { if let Some((clicked_region, prev_drag_position)) = self .clicked_region @@ -290,13 +302,17 @@ impl Presenter { *prev_drag_position = *position; } - self.last_mouse_moved_event = Some(event.clone()); + self.last_mouse_moved_event = Some(e.clone()); } + _ => {} } - let (mut handled, mut event_cx) = - self.handle_hover_events(&event, &mut invalidated_views, cx); + let (mut handled, mut event_cx) = if let Event::MouseMoved(e) = &event { + self.handle_hover_events(e, &mut invalidated_views, cx) + } else { + (false, self.build_event_context(cx)) + }; for (handler, view_id, region_event) in mouse_down_out_handlers { event_cx.with_current_view(view_id, |event_cx| handler(region_event, event_cx)) @@ -353,51 +369,45 @@ impl Presenter { fn handle_hover_events<'a>( &'a mut self, - event: &Event, + e @ MouseMovedEvent { + position, + pressed_button, + .. + }: &MouseMovedEvent, invalidated_views: &mut Vec, cx: &'a mut MutableAppContext, ) -> (bool, EventContext<'a>) { let mut hover_regions = Vec::new(); - if let Event::MouseMoved( - e @ MouseMovedEvent { - position, - pressed_button, - .. - }, - ) = event - { - if pressed_button.is_none() { - let mut style_to_assign = CursorStyle::Arrow; - for region in self.cursor_regions.iter().rev() { - if region.bounds.contains_point(*position) { - style_to_assign = region.style; - break; - } + + if pressed_button.is_none() { + let mut style_to_assign = CursorStyle::Arrow; + for region in self.cursor_regions.iter().rev() { + if region.bounds.contains_point(*position) { + style_to_assign = region.style; + break; } - cx.platform().set_cursor_style(style_to_assign); + } + cx.platform().set_cursor_style(style_to_assign); - let mut hover_depth = None; - for (region, depth) in self.mouse_regions.iter().rev() { - if region.bounds.contains_point(*position) - && hover_depth.map_or(true, |hover_depth| hover_depth == *depth) - { - hover_depth = Some(*depth); - if let Some(region_id) = region.id() { - if !self.hovered_region_ids.contains(®ion_id) { - invalidated_views.push(region.view_id); - hover_regions - .push((region.clone(), MouseRegionEvent::Hover(true, *e))); - self.hovered_region_ids.insert(region_id); - } - } - } else if let Some(region_id) = region.id() { - if self.hovered_region_ids.contains(®ion_id) { + let mut hover_depth = None; + for (region, depth) in self.mouse_regions.iter().rev() { + if region.bounds.contains_point(*position) + && hover_depth.map_or(true, |hover_depth| hover_depth == *depth) + { + hover_depth = Some(*depth); + if let Some(region_id) = region.id() { + if !self.hovered_region_ids.contains(®ion_id) { invalidated_views.push(region.view_id); - hover_regions - .push((region.clone(), MouseRegionEvent::Hover(false, *e))); - self.hovered_region_ids.remove(®ion_id); + hover_regions.push((region.clone(), MouseRegionEvent::Hover(true, *e))); + self.hovered_region_ids.insert(region_id); } } + } else if let Some(region_id) = region.id() { + if self.hovered_region_ids.contains(®ion_id) { + invalidated_views.push(region.view_id); + hover_regions.push((region.clone(), MouseRegionEvent::Hover(false, *e))); + self.hovered_region_ids.remove(®ion_id); + } } } }