Skip to main content

accumulate_wheel

Function accumulate_wheel 

Source
pub fn accumulate_wheel(
    wheels: MessageReader<'_, '_, MouseWheel>,
    hovered: Query<'_, '_, Entity, With<Hovered>>,
    parents: Query<'_, '_, &ChildOf>,
    children_q: Query<'_, '_, (&ChildOf, &Transform)>,
    transforms: Query<'_, '_, &Transform>,
    sliders: Query<'_, '_, (), With<SliderValue>>,
    scrolls: Query<'_, '_, (Entity, &mut Scroll, &mut ScrollOffset)>,
)
Expand description

Accumulate wheel deltas into the ScrollOffset of the innermost scrollable ancestor of whatever entity the pointer is hovering that can still scroll in the event’s direction (spec section 16.5).

Why bubbling at all: hit_test picks the deepest candidate under the cursor (so a tile beats its column container), but the Scroll component lives on the container, not on the leaf - so we walk the [ChildOf] chain upward. Nested-scroll routing (Qt propagation model): the innermost hovered scroll area handles the wheel first; when it is already at its limit on the event’s direction (or the event’s axes don’t intersect its allowed ScrollAxis), it does not consume the event and the next scrollable ancestor gets it. An inner list pinned at its bottom + wheel-down therefore scrolls the outer page, while wheel-up still scrolls the inner list.

If no scroll ancestor on the chain can consume the event (every scroller is pinned at its limit for this direction), the event is routed to the innermost scroller anyway so overshoot / rubber-band handling still observes the gesture - clamp_scroll_offsets keeps the offset in bounds, so this is a visual no-op on hard-clamp platforms. The cursor being over chrome with no Scroll ancestor at all keeps the old fallback: the world’s first Scroll entity, so wheel still does something sensible in single-scroller apps.

Drains the MouseWheel buffer into a local vec first to avoid losing events during archetype churn (the previous single_mut version did).