pub struct PointerSequence { /* private fields */ }Expand description
Everything the tree knows about one press: who is competing for it, and who won.
Lives in PointerEntry::sequence
for as long as the pointer is down. The ordered decision procedure this
type is the state of is written out in docs/events-and-gestures.md §4.2 and
in this module’s own header.
Implementations§
Source§impl PointerSequence
impl PointerSequence
Sourcepub fn new(
pointer: PointerInfo,
path: Vec<WidgetId>,
touch_action: TouchAction,
dead_zone_boundary: Option<WidgetId>,
origin: Point,
started_at: EventTime,
) -> Self
pub fn new( pointer: PointerInfo, path: Vec<WidgetId>, touch_action: TouchAction, dead_zone_boundary: Option<WidgetId>, origin: Point, started_at: EventTime, ) -> Self
Open a sequence for pointer’s press at origin.
path runs target → root and is frozen: a rebuild mid-gesture
cannot change who was competing for a press that has already started.
Sourcepub fn pointer(&self) -> PointerInfo
pub fn pointer(&self) -> PointerInfo
Which pointer this sequence follows.
Sourcepub fn touch_action(&self) -> TouchAction
pub fn touch_action(&self) -> TouchAction
The TouchAction frozen at press — the intersection of every
declaration from the root down to the pressed target.
Sourcepub fn dead_zone_boundary(&self) -> Option<WidgetId>
pub fn dead_zone_boundary(&self) -> Option<WidgetId>
The innermost gesture_dead_zone node on the frozen path, if any.
Nothing at or above it may be enrolled.
Sourcepub fn members(&self) -> &[SequenceMember]
pub fn members(&self) -> &[SequenceMember]
Every enrolled member, innermost first.
Sourcepub fn winner(&self) -> Option<WidgetId>
pub fn winner(&self) -> Option<WidgetId>
The node that owns this press, once one has been decided.
Sourcepub fn is_decided(&self) -> bool
pub fn is_decided(&self) -> bool
Whether arbitration is over.
Sourcepub fn capture(&self) -> Option<WidgetId>
pub fn capture(&self) -> Option<WidgetId>
The node holding this pointer’s capture, as the sequence recorded it.
Sourcepub fn set_capture(&mut self, captor: Option<WidgetId>)
pub fn set_capture(&mut self, captor: Option<WidgetId>)
Record who holds the capture.
Sourcepub fn pressed_owner(&self) -> Option<WidgetId>
pub fn pressed_owner(&self) -> Option<WidgetId>
The node whose gesture arena took the press — the tap owner, when the press was not claimed by anything else.
Sourcepub fn set_pressed_owner(&mut self, owner: Option<WidgetId>)
pub fn set_pressed_owner(&mut self, owner: Option<WidgetId>)
Record the node whose gesture arena took the press.
Sourcepub fn press_origin(&self) -> Point
pub fn press_origin(&self) -> Point
Where the press landed.
Sourcepub fn last_position(&self) -> Point
pub fn last_position(&self) -> Point
Where the pointer was at its most recent sample.
Sourcepub fn set_last_position(&mut self, position: Point)
pub fn set_last_position(&mut self, position: Point)
Record the pointer’s current position.
Sourcepub fn started_at(&self) -> EventTime
pub fn started_at(&self) -> EventTime
When the press landed, on the tree’s input timeline.
Sourcepub fn taps_cancelled(&self) -> bool
pub fn taps_cancelled(&self) -> bool
Whether the press has already been told it is no longer a tap.
The cancel_taps revocation fires once per press: it resets the
node’s TapStreak, and repeating it on every
subsequent move would keep clearing state a live drag may still want.
Sourcepub fn set_taps_cancelled(&mut self)
pub fn set_taps_cancelled(&mut self)
Record that the tap family has been revoked for this press.
Sourcepub fn is_terminating(&self) -> bool
pub fn is_terminating(&self) -> bool
Whether the sequence is inside its own terminal dispatch — set while the
Up that ends it is being delivered, so a teardown triggered from a
handler cannot cancel a press that has already completed.
Sourcepub fn set_terminating(&mut self, terminating: bool)
pub fn set_terminating(&mut self, terminating: bool)
Mark the sequence as inside its terminal dispatch.
Sourcepub fn latch_slop(&self, profile: &GestureProfile) -> f32
pub fn latch_slop(&self, profile: &GestureProfile) -> f32
The slop a positional member of this sequence latches at.
profile.drag_slop in every configuration except a direct pointer
under a frozen TouchAction::NONE, where the subtree has declared
that a contact does nothing but manipulate it and the jitter floor is
the right threshold. A precise pointer always uses drag_slop: reading
slop_precise for it would silently retune every mouse drag latch from
5 dp to 2.
Sourcepub fn may_enrol(&self, id: WidgetId) -> bool
pub fn may_enrol(&self, id: WidgetId) -> bool
Whether id may be enrolled at all: it must be on the frozen path and
strictly below the dead-zone boundary.
Sourcepub fn has_member(&self, id: WidgetId) -> bool
pub fn has_member(&self, id: WidgetId) -> bool
Whether id is already enrolled.
Sourcepub fn enrol(&mut self, id: WidgetId, role: MemberRole) -> bool
pub fn enrol(&mut self, id: WidgetId, role: MemberRole) -> bool
Enrol id as a competitor, keeping the member list innermost-first.
Refused — and reported as false — when id is at or above the
dead-zone boundary, when it is not on the frozen path, or when it is
already enrolled.
Sourcepub fn enrol_drag(
&mut self,
id: WidgetId,
role: MemberRole,
activation: DragActivation,
profile: &GestureProfile,
) -> bool
pub fn enrol_drag( &mut self, id: WidgetId, role: MemberRole, activation: DragActivation, profile: &GestureProfile, ) -> bool
Enrol a drag member whose DragActivation defers it.
AfterLongPress (and Auto resolving to it) sets eligible_at to the
long-press deadline and arms the self-rejection rule: the member is out
the moment the press travels past the tap boundary, because that travel
is a pan, not a considered grab.
Sourcepub fn defer_own_drag(
&mut self,
id: WidgetId,
activation: DragActivation,
profile: &GestureProfile,
) -> bool
pub fn defer_own_drag( &mut self, id: WidgetId, activation: DragActivation, profile: &GestureProfile, ) -> bool
Give the press owner’s own drag a say when the node is already enrolled in another role.
One node holds exactly one SequenceMember — decide,
reject and hold are all keyed on that —
and enrol refuses a second. But a node can genuinely
want two roles: a SceneView with selection or magnetism on declares a
PanClaim and carries on_drag on the same HandlerSet.
begin_sequence enrols it as the pan claimant before any handler runs,
so its drag was refused and its DragActivation was never consulted —
and its DragRecognizer, driven by the ordinary capture dispatch that
precedes the arbitration walk, then latched at drag_slop and decided
the sequence at half the travel the pan needed. A surface shaped like
that could not pan under a finger at all.
Rather than enrol the node twice, the deferral is attached to the member
it already has. The member goes on competing as a pan on pan_slop; its
node’s own recognizers are held off until activation allows them, by
the same resolve_activation every other
drag member is resolved through — so Auto on a direct pointer with an
eligible pan means AfterLongPress, and Immediate means “today’s
behaviour, on request”.
Refused, and reported as false, unless the member exists, is live and
holds a MemberRole::Pan — so a mouse, which enrols no pan member at
all (GestureProfile::pan_slop is None for it and
PanClaim::devices admits only direct pointers), can never reach it.
A decided sequence refuses too: arbitration is over.
Sourcepub fn withdraw_own_drag(&mut self, id: WidgetId)
pub fn withdraw_own_drag(&mut self, id: WidgetId)
Take a member’s deferred self-drag out of the running for good.
Three callers, one rule each:
- the pan half won, so the press is a pan and the node’s recognizers must stay silent for the rest of it;
- the press travelled past
long_press_slopbefore the deadline, so it was never a hold. That is the ruleLongPressRecognizerapplies to itself — it fails on the first move past that slop rather than waiting for its timer — and applying it here is what stops a deliberate, slow pan from arming a grab merely by outlasting the clock; - the press left the tap boundary, the same reading
enrol_drag’srejects_on_tap_slopgives that travel.
The last two are both positional and both apply only while the self-drag
is still unripe — see Self::unripe_own_drag_members. They are not
redundant: long_press_slop is a radius around the press and bites on a
surface the finger never leaves, while TapBoundary is the node’s own
rect for a coarse pointer and bites on a small node the finger slides off
without travelling far.
Sourcepub fn own_drag_blocked(&self, id: WidgetId, now: EventTime) -> bool
pub fn own_drag_blocked(&self, id: WidgetId, now: EventTime) -> bool
Whether id’s own drag/swipe recognizers must be kept out of this
press at now. false for a node that is not a member, and for every
member carrying no self-drag.
Sourcepub fn set_drag_activation_override(
&mut self,
id: WidgetId,
activation: DragActivation,
)
pub fn set_drag_activation_override( &mut self, id: WidgetId, activation: DragActivation, )
Record a per-press DragActivation for id, overriding the node’s
build-time declaration for this press alone.
Last writer wins: a handler that answers twice on one press means the second answer.
Sourcepub fn drag_activation_override(&self, id: WidgetId) -> Option<DragActivation>
pub fn drag_activation_override(&self, id: WidgetId) -> Option<DragActivation>
The per-press DragActivation a handler chose for id, if one did.
Sourcepub fn resolve_activation(&self, activation: DragActivation) -> DragActivation
pub fn resolve_activation(&self, activation: DragActivation) -> DragActivation
What DragActivation::Auto means for this sequence.
Immediate for a precise pointer or a subtree that has declared
TouchAction::NONE (nothing else can want the press); AfterLongPress
for a coarse pointer with an eligible pan competitor, because the axis
is already spoken for.
Sourcepub fn has_deferred_grab_for(&self, id: WidgetId) -> bool
pub fn has_deferred_grab_for(&self, id: WidgetId) -> bool
Whether id’s own grab on this press is waiting out the long-press
deadline — i.e. the hold is what arms that node’s grab.
Two deferrals answer to this, and both are set only when
resolve_activation answered
DragActivation::AfterLongPress:
- a member deferred whole, by
enrol_drag—eligible_at; - the self-drag half of a dual-role member, by
defer_own_drag—own_drag_eligible_at. It has to count: the node’s grab is armed by the same hold, so without this aSceneViewwith selection on would spend one hold on both its marquee and its own long press.
§Why it is keyed on a node and not on the sequence
“One hold cannot mean two things” is a statement about one node, not
about a press. A press reaches an ancestor chain, and a deferred grab
somewhere on it says nothing about what a hold means further in: a
SceneView that marquees after a hold is not thereby declaring that
every heavyweight widget inside it has given up its touch long press and
its touch context menu. A finger has no secondary button — the hold is
the context-menu route — so answering this sequence-wide silently
removed the only touch route to a context menu from every descendant of
any dual-role container, which is an accessibility loss and not a rule.
The ancestor-wide door exists and is explicit:
LongPressRole::DragHandle, which WidgetTree::long_press_is_a_grab
walks from the queried node to the root. A container that really does
own every hold in its subtree says so there.
A mouse never has one of these at all: both resolutions need an eligible pan competitor and a mouse enrols none.
Read by the framework through WidgetTree::long_press_is_a_grab.
Sourcepub fn has_eligible_pan(&self) -> bool
pub fn has_eligible_pan(&self) -> bool
Whether any live member is a pan claimant. A mouse never has one:
GestureProfile::pan_slop is None for it and PanClaim::devices
admits only direct pointers.
Sourcepub fn pan_is_eligible(
&self,
claim: &PanClaim,
profile: &GestureProfile,
) -> bool
pub fn pan_is_eligible( &self, claim: &PanClaim, profile: &GestureProfile, ) -> bool
Whether claim is eligible for this sequence’s pointer at all: the
claim must admit the device, the pointer’s profile must have a pan slop,
and the frozen TouchAction must permit at least one claimed axis.
Sourcepub fn pan_axis_past_slop(
&self,
claim: &PanClaim,
profile: &GestureProfile,
) -> Option<Axis>
pub fn pan_axis_past_slop( &self, claim: &PanClaim, profile: &GestureProfile, ) -> Option<Axis>
The axis a pan member of this sequence would win on, if its travel has
passed pan_slop on one the claim and the frozen action both permit.
A diagonal tie resolves by dominant axis — the one that has moved further — so a pan that is mostly vertical scrolls vertically even when both axes are claimed.
Sourcepub fn decide(&mut self, id: WidgetId) -> Vec<WidgetId>
pub fn decide(&mut self, id: WidgetId) -> Vec<WidgetId>
Declare id the winner and reject every other live member.
Returns the members that were knocked out, so the caller can cancel each exactly once.
Sourcepub fn hold(&mut self, id: WidgetId, now: EventTime)
pub fn hold(&mut self, id: WidgetId, now: EventTime)
Defer id’s decision until it releases or profile.max_hold elapses.
Sourcepub fn release_hold(&mut self, id: WidgetId)
pub fn release_hold(&mut self, id: WidgetId)
End id’s hold, putting it back in the running.
Sourcepub fn expire_holds(&mut self, now: EventTime, profile: &GestureProfile)
pub fn expire_holds(&mut self, now: EventTime, profile: &GestureProfile)
Release every hold older than profile.max_hold.
A hold exists so an application recognizer can await an asynchronous decision; leaving one standing would strand the press, so the framework times it out rather than trusting the holder.
Sourcepub fn next_hold_deadline(&self, profile: &GestureProfile) -> Option<EventTime>
pub fn next_hold_deadline(&self, profile: &GestureProfile) -> Option<EventTime>
When expire_holds next has work: the earliest
instant at which a standing hold reaches profile.max_hold.
A deferred member’s eligible_at is deliberately not a term here.
It looks like a sibling deadline and is not one. Nothing happens at that
instant: eligibility is never stored, it is re-derived by
SequenceMember::is_eligible_at against whatever instant its caller
names, and no reader transitions anything on reaching it. Two call
sites read it — the arbitration walk, and the arena gate the ordinary
bubble and the timer tick share, the one naming the sample being
dispatched and the other the tick’s own instant — and each of them only
answers a question its caller already had. A press that has sat
still past its long_press is already eligible the moment it moves,
with no intervening tick, so waking the event loop at eligible_at
would buy an idle frame with nothing to do in it. The expiry of a hold
is the opposite: it is a stored state transition, and if nobody performs
it the hold stands past the duration the framework promises to trust it
for.
Sourcepub fn revalidate(&mut self, arena: &WidgetArena) -> Vec<WidgetId>
pub fn revalidate(&mut self, arena: &WidgetArena) -> Vec<WidgetId>
Drop every member whose node is no longer active, reporting them so the caller can cancel each individually.
Run every sample: a rebuild mints fresh ids, and a member left pointing
at a destroyed node would either be fed events forever or silently win.
The sequence dies only when the winner or the captor dies — see
lost_owner.
Sourcepub fn lost_owner(&self, arena: &WidgetArena) -> bool
pub fn lost_owner(&self, arena: &WidgetArena) -> bool
Whether the node that owns this sequence — its winner, or failing that its captor — has gone away. The sequence itself must then be cancelled.
Sourcepub fn member_report(&self) -> Vec<(WidgetId, MemberRole, MemberState)>
pub fn member_report(&self) -> Vec<(WidgetId, MemberRole, MemberState)>
The role and state of every member, for
WidgetTree::sequence_members.
Trait Implementations§
Source§impl Clone for PointerSequence
impl Clone for PointerSequence
Source§fn clone(&self) -> PointerSequence
fn clone(&self) -> PointerSequence
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more