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:
@@ -136,7 +136,9 @@ pub struct IndentGuideLayout {
|
||||
|
||||
/// Implements the necessary functionality for rendering indent guides inside a uniform list.
|
||||
mod uniform_list {
|
||||
use gpui::{DispatchPhase, Hitbox, MouseButton, MouseDownEvent, MouseMoveEvent};
|
||||
use gpui::{
|
||||
DispatchPhase, Hitbox, HitboxBehavior, MouseButton, MouseDownEvent, MouseMoveEvent,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
@@ -256,7 +258,12 @@ mod uniform_list {
|
||||
.indent_guides
|
||||
.as_ref()
|
||||
.iter()
|
||||
.map(|guide| window.insert_hitbox(guide.hitbox.unwrap_or(guide.bounds), false))
|
||||
.map(|guide| {
|
||||
window.insert_hitbox(
|
||||
guide.hitbox.unwrap_or(guide.bounds),
|
||||
HitboxBehavior::Normal,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
Self::PrepaintState::Interactive {
|
||||
hitboxes: Rc::new(hitboxes),
|
||||
|
||||
@@ -2,9 +2,9 @@ use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use gpui::{
|
||||
AnyElement, AnyView, App, Bounds, Corner, DismissEvent, DispatchPhase, Element, ElementId,
|
||||
Entity, Focusable as _, GlobalElementId, HitboxId, InteractiveElement, IntoElement, LayoutId,
|
||||
Length, ManagedView, MouseDownEvent, ParentElement, Pixels, Point, Style, Window, anchored,
|
||||
deferred, div, point, prelude::FluentBuilder, px, size,
|
||||
Entity, Focusable as _, GlobalElementId, HitboxBehavior, HitboxId, InteractiveElement,
|
||||
IntoElement, LayoutId, Length, ManagedView, MouseDownEvent, ParentElement, Pixels, Point,
|
||||
Style, Window, anchored, deferred, div, point, prelude::FluentBuilder, px, size,
|
||||
};
|
||||
|
||||
use crate::prelude::*;
|
||||
@@ -421,7 +421,7 @@ impl<M: ManagedView> Element for PopoverMenu<M> {
|
||||
((), element_state)
|
||||
});
|
||||
|
||||
window.insert_hitbox(bounds, false).id
|
||||
window.insert_hitbox(bounds, HitboxBehavior::Normal).id
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@ use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use gpui::{
|
||||
AnyElement, App, Bounds, Corner, DismissEvent, DispatchPhase, Element, ElementId, Entity,
|
||||
Focusable as _, GlobalElementId, Hitbox, InteractiveElement, IntoElement, LayoutId,
|
||||
ManagedView, MouseButton, MouseDownEvent, ParentElement, Pixels, Point, Window, anchored,
|
||||
deferred, div, px,
|
||||
Focusable as _, GlobalElementId, Hitbox, HitboxBehavior, InteractiveElement, IntoElement,
|
||||
LayoutId, ManagedView, MouseButton, MouseDownEvent, ParentElement, Pixels, Point, Window,
|
||||
anchored, deferred, div, px,
|
||||
};
|
||||
|
||||
pub struct RightClickMenu<M: ManagedView> {
|
||||
@@ -185,7 +185,7 @@ impl<M: ManagedView> Element for RightClickMenu<M> {
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> PrepaintState {
|
||||
let hitbox = window.insert_hitbox(bounds, false);
|
||||
let hitbox = window.insert_hitbox(bounds, HitboxBehavior::Normal);
|
||||
|
||||
if let Some(child) = request_layout.child_element.as_mut() {
|
||||
child.prepaint(window, cx);
|
||||
|
||||
@@ -3,9 +3,9 @@ use std::{any::Any, cell::Cell, fmt::Debug, ops::Range, rc::Rc, sync::Arc};
|
||||
use crate::{IntoElement, prelude::*, px, relative};
|
||||
use gpui::{
|
||||
Along, App, Axis as ScrollbarAxis, BorderStyle, Bounds, ContentMask, Corners, Edges, Element,
|
||||
ElementId, Entity, EntityId, GlobalElementId, Hitbox, Hsla, IsZero, LayoutId, ListState,
|
||||
MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels, Point, ScrollHandle, ScrollWheelEvent,
|
||||
Size, Style, UniformListScrollHandle, Window, quad,
|
||||
ElementId, Entity, EntityId, GlobalElementId, Hitbox, HitboxBehavior, Hsla, IsZero, LayoutId,
|
||||
ListState, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels, Point, ScrollHandle,
|
||||
ScrollWheelEvent, Size, Style, UniformListScrollHandle, Window, quad,
|
||||
};
|
||||
|
||||
pub struct Scrollbar {
|
||||
@@ -226,7 +226,7 @@ impl Element for Scrollbar {
|
||||
_: &mut App,
|
||||
) -> Self::PrepaintState {
|
||||
window.with_content_mask(Some(ContentMask { bounds }), |window| {
|
||||
window.insert_hitbox(bounds, false)
|
||||
window.insert_hitbox(bounds, HitboxBehavior::Normal)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user