diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 076a3fdde3..03625c80e7 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -3299,15 +3299,15 @@ impl<'a, 'b, V: 'static> ViewContext<'a, 'b, V> { let region_id = MouseRegionId::new(tag, self.view_id, region_id); MouseState { hovered: self.window.hovered_region_ids.contains(®ion_id), - clicked: if let Some((clicked_region_id, button)) = self.window.clicked_region { - if region_id == clicked_region_id { - Some(button) - } else { - None - } - } else { - None - }, + mouse_down: !self.window.clicked_region_ids.is_empty(), + clicked: self + .window + .clicked_region_ids + .iter() + .find(|click_region_id| **click_region_id == region_id) + // If we've gotten here, there should always be a clicked region. + // But let's be defensive and return None if there isn't. + .and_then(|_| self.window.clicked_region.map(|(_, button)| button)), accessed_hovered: false, accessed_clicked: false, } @@ -3823,14 +3823,20 @@ impl<'a, T> DerefMut for Reference<'a, T> { pub struct MouseState { pub(crate) hovered: bool, pub(crate) clicked: Option, + pub(crate) mouse_down: bool, pub(crate) accessed_hovered: bool, pub(crate) accessed_clicked: bool, } impl MouseState { + pub fn dragging(&mut self) -> bool { + self.accessed_hovered = true; + self.hovered && self.mouse_down + } + pub fn hovered(&mut self) -> bool { self.accessed_hovered = true; - self.hovered + self.hovered && (!self.mouse_down || self.clicked.is_some()) } pub fn clicked(&mut self) -> Option { diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index 5638699565..4b8b0534d5 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -617,10 +617,11 @@ impl<'a> WindowContext<'a> { } } - if self - .window - .platform_window - .is_topmost_for_position(*position) + if pressed_button.is_none() + && self + .window + .platform_window + .is_topmost_for_position(*position) { self.platform().set_cursor_style(style_to_assign); } @@ -787,6 +788,11 @@ impl<'a> WindowContext<'a> { .contains_point(self.window.mouse_position) { valid_regions.push(mouse_region.clone()); + } else { + // Let the view know that it hasn't been clicked anymore + if mouse_region.notify_on_click { + notified_views.insert(mouse_region.id().view_id()); + } } } } diff --git a/crates/workspace/src/pane/dragged_item_receiver.rs b/crates/workspace/src/pane/dragged_item_receiver.rs index 5e487b49b4..bbe391b5b5 100644 --- a/crates/workspace/src/pane/dragged_item_receiver.rs +++ b/crates/workspace/src/pane/dragged_item_receiver.rs @@ -42,7 +42,11 @@ where let mut handler = MouseEventHandler::above::(region_id, cx, |state, cx| { // Observing hovered will cause a render when the mouse enters regardless // of if mouse position was accessed before - let drag_position = if state.hovered() { drag_position } else { None }; + let drag_position = if state.dragging() { + drag_position + } else { + None + }; Stack::new() .with_child(render_child(state, cx)) .with_children(drag_position.map(|drag_position| {