Skip to main content

PointerSequence

Struct PointerSequence 

Source
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

Source

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.

Source

pub fn pointer(&self) -> PointerInfo

Which pointer this sequence follows.

Source

pub fn path(&self) -> &[WidgetId]

The frozen hit path, target → root.

Source

pub fn touch_action(&self) -> TouchAction

The TouchAction frozen at press — the intersection of every declaration from the root down to the pressed target.

Source

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.

Source

pub fn members(&self) -> &[SequenceMember]

Every enrolled member, innermost first.

Source

pub fn winner(&self) -> Option<WidgetId>

The node that owns this press, once one has been decided.

Source

pub fn is_decided(&self) -> bool

Whether arbitration is over.

Source

pub fn capture(&self) -> Option<WidgetId>

The node holding this pointer’s capture, as the sequence recorded it.

Source

pub fn set_capture(&mut self, captor: Option<WidgetId>)

Record who holds the capture.

Source

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.

Source

pub fn set_pressed_owner(&mut self, owner: Option<WidgetId>)

Record the node whose gesture arena took the press.

Source

pub fn press_origin(&self) -> Point

Where the press landed.

Source

pub fn last_position(&self) -> Point

Where the pointer was at its most recent sample.

Source

pub fn set_last_position(&mut self, position: Point)

Record the pointer’s current position.

Source

pub fn started_at(&self) -> EventTime

When the press landed, on the tree’s input timeline.

Source

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.

Source

pub fn set_taps_cancelled(&mut self)

Record that the tap family has been revoked for this press.

Source

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.

Source

pub fn set_terminating(&mut self, terminating: bool)

Mark the sequence as inside its terminal dispatch.

Source

pub fn travel(&self) -> f32

How far the pointer has travelled from the press point.

Source

pub fn travel_on(&self, axis: Axis) -> f32

How far the pointer has travelled along one axis.

Source

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.

Source

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.

Source

pub fn has_member(&self, id: WidgetId) -> bool

Whether id is already enrolled.

Source

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.

Source

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.

Source

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 SequenceMemberdecide, 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.

Source

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_slop before the deadline, so it was never a hold. That is the rule LongPressRecognizer applies 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’s rejects_on_tap_slop gives 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.

Source

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.

Source

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.

Source

pub fn drag_activation_override(&self, id: WidgetId) -> Option<DragActivation>

The per-press DragActivation a handler chose for id, if one did.

Source

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.

Source

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_drageligible_at;
  • the self-drag half of a dual-role member, by defer_own_dragown_drag_eligible_at. It has to count: the node’s grab is armed by the same hold, so without this a SceneView with 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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn reject(&mut self, id: WidgetId)

Withdraw id from the running.

Source

pub fn hold(&mut self, id: WidgetId, now: EventTime)

Defer id’s decision until it releases or profile.max_hold elapses.

Source

pub fn release_hold(&mut self, id: WidgetId)

End id’s hold, putting it back in the running.

Source

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.

Source

pub fn is_held(&self) -> bool

Whether any member is holding.

Source

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.

Source

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.

Source

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.

Source

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

Source§

fn clone(&self) -> PointerSequence

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for PointerSequence

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for PointerSequence

Source§

fn eq(&self, other: &PointerSequence) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for PointerSequence

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.