gpui: Support hitbox blocking mouse interaction except scrolling (#31712)
tl;dr: This adds `.block_mouse_except_scroll()` which should typically be used instead of `.occlude()` for cases when the mouse shouldn't interact with elements drawn below an element. The rationale for treating scroll events differently: * Mouse move / click / styles / tooltips are for elements the user is interacting with directly. * Mouse scroll events are about finding the current outer scroll container. Most use of `occlude` should probably be switched to this, but I figured I'd derisk this change by minimizing behavior changes to just the 3 uses of `block_mouse_except_scroll`. GPUI changes: * Added `InteractiveElement::block_mouse_except_scroll()`, and removes `stop_mouse_events_except_scroll()` * Added `Hitbox::should_handle_scroll()` to be used when handling scroll wheel events. * `Window::insert_hitbox` now takes `HitboxBehavior` instead of `occlude: bool`. - `false` for that bool is now `HitboxBehavior::Normal`. - `true` for that bool is now `HitboxBehavior::BlockMouse`. - The new mode is `HitboxBehavior::BlockMouseExceptScroll`. * Removes `Default` impl for `HitboxId` since applications should not manually create `HitboxId(0)`. Release Notes: - N/A
This commit is contained in:
parent
2abc5893c1
commit
9086784038
16 changed files with 231 additions and 99 deletions
|
@ -21907,7 +21907,7 @@ fn render_diff_hunk_controls(
|
|||
.rounded_b_lg()
|
||||
.bg(cx.theme().colors().editor_background)
|
||||
.gap_1()
|
||||
.stop_mouse_events_except_scroll()
|
||||
.block_mouse_except_scroll()
|
||||
.shadow_md()
|
||||
.child(if status.has_secondary_hunk() {
|
||||
Button::new(("stage", row as u64), "Stage")
|
||||
|
|
|
@ -42,13 +42,13 @@ use git::{
|
|||
use gpui::{
|
||||
Action, Along, AnyElement, App, AppContext, AvailableSpace, Axis as ScrollbarAxis, BorderStyle,
|
||||
Bounds, ClickEvent, ContentMask, Context, Corner, Corners, CursorStyle, DispatchPhase, Edges,
|
||||
Element, ElementInputHandler, Entity, Focusable as _, FontId, GlobalElementId, Hitbox, Hsla,
|
||||
InteractiveElement, IntoElement, IsZero, Keystroke, Length, ModifiersChangedEvent, MouseButton,
|
||||
MouseDownEvent, MouseMoveEvent, MouseUpEvent, PaintQuad, ParentElement, Pixels, ScrollDelta,
|
||||
ScrollHandle, ScrollWheelEvent, ShapedLine, SharedString, Size, StatefulInteractiveElement,
|
||||
Style, Styled, TextRun, TextStyleRefinement, WeakEntity, Window, anchored, deferred, div, fill,
|
||||
linear_color_stop, linear_gradient, outline, point, px, quad, relative, size, solid_background,
|
||||
transparent_black,
|
||||
Element, ElementInputHandler, Entity, Focusable as _, FontId, GlobalElementId, Hitbox,
|
||||
HitboxBehavior, Hsla, InteractiveElement, IntoElement, IsZero, Keystroke, Length,
|
||||
ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, PaintQuad,
|
||||
ParentElement, Pixels, ScrollDelta, ScrollHandle, ScrollWheelEvent, ShapedLine, SharedString,
|
||||
Size, StatefulInteractiveElement, Style, Styled, TextRun, TextStyleRefinement, WeakEntity,
|
||||
Window, anchored, deferred, div, fill, linear_color_stop, linear_gradient, outline, point, px,
|
||||
quad, relative, size, solid_background, transparent_black,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use language::language_settings::{
|
||||
|
@ -1620,7 +1620,7 @@ impl EditorElement {
|
|||
);
|
||||
|
||||
let layout = ScrollbarLayout::for_minimap(
|
||||
window.insert_hitbox(minimap_bounds, false),
|
||||
window.insert_hitbox(minimap_bounds, HitboxBehavior::Normal),
|
||||
visible_editor_lines,
|
||||
total_editor_lines,
|
||||
minimap_line_height,
|
||||
|
@ -1791,7 +1791,7 @@ impl EditorElement {
|
|||
if matches!(hunk, DisplayDiffHunk::Unfolded { .. }) {
|
||||
let hunk_bounds =
|
||||
Self::diff_hunk_bounds(snapshot, line_height, gutter_hitbox.bounds, hunk);
|
||||
*hitbox = Some(window.insert_hitbox(hunk_bounds, true));
|
||||
*hitbox = Some(window.insert_hitbox(hunk_bounds, HitboxBehavior::BlockMouse));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2883,7 +2883,7 @@ impl EditorElement {
|
|||
let hitbox = line_origin.map(|line_origin| {
|
||||
window.insert_hitbox(
|
||||
Bounds::new(line_origin, size(shaped_line.width, line_height)),
|
||||
false,
|
||||
HitboxBehavior::Normal,
|
||||
)
|
||||
});
|
||||
#[cfg(test)]
|
||||
|
@ -6371,7 +6371,7 @@ impl EditorElement {
|
|||
}
|
||||
};
|
||||
|
||||
if phase == DispatchPhase::Bubble && hitbox.is_hovered(window) {
|
||||
if phase == DispatchPhase::Bubble && hitbox.should_handle_scroll(window) {
|
||||
delta = delta.coalesce(event.delta);
|
||||
editor.update(cx, |editor, cx| {
|
||||
let position_map: &PositionMap = &position_map;
|
||||
|
@ -7651,15 +7651,17 @@ impl Element for EditorElement {
|
|||
.map(|(guide, active)| (self.column_pixels(*guide, window, cx), *active))
|
||||
.collect::<SmallVec<[_; 2]>>();
|
||||
|
||||
let hitbox = window.insert_hitbox(bounds, false);
|
||||
let gutter_hitbox =
|
||||
window.insert_hitbox(gutter_bounds(bounds, gutter_dimensions), false);
|
||||
let hitbox = window.insert_hitbox(bounds, HitboxBehavior::Normal);
|
||||
let gutter_hitbox = window.insert_hitbox(
|
||||
gutter_bounds(bounds, gutter_dimensions),
|
||||
HitboxBehavior::Normal,
|
||||
);
|
||||
let text_hitbox = window.insert_hitbox(
|
||||
Bounds {
|
||||
origin: gutter_hitbox.top_right(),
|
||||
size: size(text_width, bounds.size.height),
|
||||
},
|
||||
false,
|
||||
HitboxBehavior::Normal,
|
||||
);
|
||||
|
||||
let content_origin = text_hitbox.origin + content_offset;
|
||||
|
@ -8880,7 +8882,7 @@ impl EditorScrollbars {
|
|||
})
|
||||
.map(|(viewport_size, scroll_range)| {
|
||||
ScrollbarLayout::new(
|
||||
window.insert_hitbox(scrollbar_bounds_for(axis), false),
|
||||
window.insert_hitbox(scrollbar_bounds_for(axis), HitboxBehavior::Normal),
|
||||
viewport_size,
|
||||
scroll_range,
|
||||
glyph_grid_cell.along(axis),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue