Fix two mouse event bugs (#2835)

This PR fixes two bugs we discovered in Zed's mouse event handling while
investigating an interesting and mysterious bug we we were seeing, where
spurious `MouseMoved` events would continuously be dispatched after
control-clicking.

Release Notes:

- Fixed a rendering glitch that could occur after control-clicking
certain elements.
This commit is contained in:
Mikayla Maki 2023-08-09 09:04:32 -07:00 committed by GitHub
commit 40030f32d9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 14 additions and 6 deletions

View file

@ -52,8 +52,8 @@ pub struct Window {
cursor_regions: Vec<CursorRegion>, cursor_regions: Vec<CursorRegion>,
mouse_regions: Vec<(MouseRegion, usize)>, mouse_regions: Vec<(MouseRegion, usize)>,
last_mouse_moved_event: Option<Event>, last_mouse_moved_event: Option<Event>,
pub(crate) hovered_region_ids: HashSet<MouseRegionId>, pub(crate) hovered_region_ids: Vec<MouseRegionId>,
pub(crate) clicked_region_ids: HashSet<MouseRegionId>, pub(crate) clicked_region_ids: Vec<MouseRegionId>,
pub(crate) clicked_region: Option<(MouseRegionId, MouseButton)>, pub(crate) clicked_region: Option<(MouseRegionId, MouseButton)>,
mouse_position: Vector2F, mouse_position: Vector2F,
text_layout_cache: TextLayoutCache, text_layout_cache: TextLayoutCache,
@ -678,6 +678,7 @@ impl<'a> WindowContext<'a> {
let mut highest_z_index = None; let mut highest_z_index = None;
let mouse_position = self.window.mouse_position.clone(); let mouse_position = self.window.mouse_position.clone();
let window = &mut *self.window; let window = &mut *self.window;
let prev_hovered_regions = mem::take(&mut window.hovered_region_ids);
for (region, z_index) in window.mouse_regions.iter().rev() { for (region, z_index) in window.mouse_regions.iter().rev() {
// Allow mouse regions to appear transparent to hovers // Allow mouse regions to appear transparent to hovers
if !region.hoverable { if !region.hoverable {
@ -696,7 +697,11 @@ impl<'a> WindowContext<'a> {
// highest_z_index is set. // highest_z_index is set.
if contains_mouse && z_index == highest_z_index.unwrap() { if contains_mouse && z_index == highest_z_index.unwrap() {
//Ensure that hover entrance events aren't sent twice //Ensure that hover entrance events aren't sent twice
if window.hovered_region_ids.insert(region.id()) { if let Err(ix) = window.hovered_region_ids.binary_search(&region.id()) {
window.hovered_region_ids.insert(ix, region.id());
}
// window.hovered_region_ids.insert(region.id());
if !prev_hovered_regions.contains(&region.id()) {
valid_regions.push(region.clone()); valid_regions.push(region.clone());
if region.notify_on_hover { if region.notify_on_hover {
notified_views.insert(region.id().view_id()); notified_views.insert(region.id().view_id());
@ -704,7 +709,7 @@ impl<'a> WindowContext<'a> {
} }
} else { } else {
// Ensure that hover exit events aren't sent twice // Ensure that hover exit events aren't sent twice
if window.hovered_region_ids.remove(&region.id()) { if prev_hovered_regions.contains(&region.id()) {
valid_regions.push(region.clone()); valid_regions.push(region.clone());
if region.notify_on_hover { if region.notify_on_hover {
notified_views.insert(region.id().view_id()); notified_views.insert(region.id().view_id());

View file

@ -1087,7 +1087,10 @@ extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) {
button: MouseButton::Left, button: MouseButton::Left,
modifiers: Modifiers { ctrl: true, .. }, modifiers: Modifiers { ctrl: true, .. },
.. ..
}) => return, }) => {
window_state_borrow.synthetic_drag_counter += 1;
return;
}
_ => None, _ => None,
}; };

View file

@ -177,7 +177,7 @@ impl MouseRegion {
} }
} }
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, PartialOrd, Ord)]
pub struct MouseRegionId { pub struct MouseRegionId {
view_id: usize, view_id: usize,
tag: TypeId, tag: TypeId,