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:
Michael Sloan 2025-05-29 15:41:15 -06:00 committed by GitHub
parent 2abc5893c1
commit 9086784038
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 231 additions and 99 deletions

View file

@ -902,9 +902,9 @@ mod element {
use std::{cell::RefCell, iter, rc::Rc, sync::Arc};
use gpui::{
Along, AnyElement, App, Axis, BorderStyle, Bounds, Element, GlobalElementId, IntoElement,
MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, Point, Size, Style,
WeakEntity, Window, px, relative, size,
Along, AnyElement, App, Axis, BorderStyle, Bounds, Element, GlobalElementId,
HitboxBehavior, IntoElement, MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement,
Pixels, Point, Size, Style, WeakEntity, Window, px, relative, size,
};
use gpui::{CursorStyle, Hitbox};
use parking_lot::Mutex;
@ -1091,7 +1091,7 @@ mod element {
};
PaneAxisHandleLayout {
hitbox: window.insert_hitbox(handle_bounds, true),
hitbox: window.insert_hitbox(handle_bounds, HitboxBehavior::Normal),
divider_bounds,
}
}

View file

@ -37,10 +37,10 @@ use futures::{
use gpui::{
Action, AnyEntity, AnyView, AnyWeakView, App, AsyncApp, AsyncWindowContext, Bounds, Context,
CursorStyle, Decorations, DragMoveEvent, Entity, EntityId, EventEmitter, FocusHandle,
Focusable, Global, Hsla, KeyContext, Keystroke, ManagedView, MouseButton, PathPromptOptions,
Point, PromptLevel, Render, ResizeEdge, Size, Stateful, Subscription, Task, Tiling, WeakEntity,
WindowBounds, WindowHandle, WindowId, WindowOptions, action_as, actions, canvas,
impl_action_as, impl_actions, point, relative, size, transparent_black,
Focusable, Global, HitboxBehavior, Hsla, KeyContext, Keystroke, ManagedView, MouseButton,
PathPromptOptions, Point, PromptLevel, Render, ResizeEdge, Size, Stateful, Subscription, Task,
Tiling, WeakEntity, WindowBounds, WindowHandle, WindowId, WindowOptions, action_as, actions,
canvas, impl_action_as, impl_actions, point, relative, size, transparent_black,
};
pub use history_manager::*;
pub use item::{
@ -7344,7 +7344,7 @@ pub fn client_side_decorations(
point(px(0.0), px(0.0)),
window.window_bounds().get_bounds().size,
),
false,
HitboxBehavior::Normal,
)
},
move |_bounds, hitbox, window, cx| {