Fix buffer rendering on every mouse move (#32408)

Closes #32210

This notify was added in #13433. Solution is to only notify when the
breakpoint indicator state has changed.

Also improves the logic for enqueuing a task to delay showing - now only
does this if it isn't already visible, and that delay task now only
notifies if still hovering.

Release Notes:

- Fixed a bug where buffers render on every mouse move.
This commit is contained in:
Michael Sloan 2025-06-09 14:10:03 -06:00 committed by GitHub
parent c4fd9e1a6b
commit bbd2262a93
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 31 additions and 26 deletions

View file

@ -923,7 +923,7 @@ enum SelectionDragState {
/// Represents a breakpoint indicator that shows up when hovering over lines in the gutter that don't have
/// a breakpoint on them.
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
struct PhantomBreakpointIndicator {
display_row: DisplayRow,
/// There's a small debounce between hovering over the line and showing the indicator.
@ -931,6 +931,7 @@ struct PhantomBreakpointIndicator {
is_active: bool,
collides_with_existing_breakpoint: bool,
}
/// Zed's primary implementation of text input, allowing users to edit a [`MultiBuffer`].
///
/// See the [module level documentation](self) for more information.

View file

@ -1031,7 +1031,7 @@ impl EditorElement {
editor.set_gutter_hovered(gutter_hovered, cx);
editor.mouse_cursor_hidden = false;
if gutter_hovered {
let breakpoint_indicator = if gutter_hovered {
let new_point = position_map
.point_for_position(event.position)
.previous_valid;
@ -1045,7 +1045,6 @@ impl EditorElement {
.buffer_for_excerpt(buffer_anchor.excerpt_id)
.and_then(|buffer| buffer.file().map(|file| (buffer, file)))
{
let was_hovered = editor.gutter_breakpoint_indicator.0.is_some();
let as_point = text::ToPoint::to_point(&buffer_anchor.text_anchor, buffer_snapshot);
let is_visible = editor
@ -1073,38 +1072,43 @@ impl EditorElement {
.is_some()
});
editor.gutter_breakpoint_indicator.0 = Some(PhantomBreakpointIndicator {
display_row: new_point.row(),
is_active: is_visible,
collides_with_existing_breakpoint: has_existing_breakpoint,
});
editor.gutter_breakpoint_indicator.1.get_or_insert_with(|| {
cx.spawn(async move |this, cx| {
if !was_hovered {
if !is_visible {
editor.gutter_breakpoint_indicator.1.get_or_insert_with(|| {
cx.spawn(async move |this, cx| {
cx.background_executor()
.timer(Duration::from_millis(200))
.await;
}
this.update(cx, |this, cx| {
if let Some(indicator) = this.gutter_breakpoint_indicator.0.as_mut() {
indicator.is_active = true;
}
cx.notify();
this.update(cx, |this, cx| {
if let Some(indicator) = this.gutter_breakpoint_indicator.0.as_mut()
{
indicator.is_active = true;
cx.notify();
}
})
.ok();
})
.ok();
})
});
});
}
Some(PhantomBreakpointIndicator {
display_row: new_point.row(),
is_active: is_visible,
collides_with_existing_breakpoint: has_existing_breakpoint,
})
} else {
editor.gutter_breakpoint_indicator = (None, None);
editor.gutter_breakpoint_indicator.1 = None;
None
}
} else {
editor.gutter_breakpoint_indicator = (None, None);
}
editor.gutter_breakpoint_indicator.1 = None;
None
};
cx.notify();
if &breakpoint_indicator != &editor.gutter_breakpoint_indicator.0 {
editor.gutter_breakpoint_indicator.0 = breakpoint_indicator;
cx.notify();
}
// Don't trigger hover popover if mouse is hovering over context menu
if text_hitbox.is_hovered(window) {