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); + } } } }