pub struct PenPacket {
pub tool: PenKind,
pub position: Point,
pub pressure: f32,
pub tilt: Option<(f32, f32)>,
pub twist: Option<f32>,
pub buttons: PenButtons,
pub in_proximity: bool,
pub down: bool,
pub device_time_ms: Option<u32>,
}Expand description
One digitizer packet, normalised.
A packet is a level, not an edge: it describes the tool’s complete state
at one instant, and the translator derives the transitions (enter, down, up,
leave, button changes) by comparing consecutive packets. That is the shape
both backends produce naturally — Wayland accumulates axes and commits them
on frame, Win32 fills one POINTER_PEN_INFO per message — and it means a
dropped packet costs a sample, never a stuck button.
Fields§
§tool: PenKindThe tool the digitizer says is in use. The eraser end is a tool, not a button.
position: PointWindow-logical position, already divided by the window’s scale factor.
pressure: f32Normalised tip pressure, 0.0..=1.0. 0.0 while hovering.
tilt: Option<(f32, f32)>(tilt_x, tilt_y) in degrees, each -90.0..=90.0, or None when the
tool has no tilt axis.
twist: Option<f32>Barrel rotation in degrees, 0.0..=359.0, or None when the tool has
no rotation axis.
The stylus buttons held.
in_proximity: boolWhether the tool is within the digitizer’s detection range. A packet
with in_proximity: false ends the hover session.
down: boolWhether the tip is touching the surface.
device_time_ms: Option<u32>The device’s own millisecond counter, on whatever clock the OS uses,
or None from a source that has no clock at all.
Deliberately not an EventTime: the epoch is unknown. Wayland’s
frame time is the compositor’s, Win32’s dwTime is
GetTickCount’s, and neither has a known offset from the tree’s epoch,
so as an absolute this number is a lie dressed as precision.
Within one drained batch it is exact as a relative, and that is the
only way it is ever read: back_date places a batch on the tree’s
timeline by anchoring the newest packet at the poll’s now and walking
backwards through these deltas. That is what stops twenty packets
spanning one drain from all claiming a single instant, which is what
they did while this field did not exist.
A u32 because both platforms report one, wrap included: back_date
reads the deltas with wrapping_sub, so a counter rolling over inside
a batch costs nothing.
Implementations§
Source§impl PenPacket
impl PenPacket
Sourcepub fn hovering(tool: PenKind, position: Point) -> Self
pub fn hovering(tool: PenKind, position: Point) -> Self
A hovering packet: in proximity, tip up, no pressure, no buttons.
Sourcepub fn out_of_proximity(tool: PenKind, position: Point) -> Self
pub fn out_of_proximity(tool: PenKind, position: Point) -> Self
The packet a tool leaving the digitizer’s range produces. Position is the last known one — the tool did not move, it stopped being seen.
Sourcepub const fn at_device_ms(self, ms: u32) -> Self
pub const fn at_device_ms(self, ms: u32) -> Self
This packet stamped with the device’s own millisecond counter.
The value a shim reads off the digitizer — Wayland’s frame time,
Win32’s dwTime. See device_time_ms for why
it stays a raw counter rather than becoming an EventTime.
Trait Implementations§
impl Copy for PenPacket
impl StructuralPartialEq for PenPacket
Auto Trait Implementations§
impl Freeze for PenPacket
impl RefUnwindSafe for PenPacket
impl Send for PenPacket
impl Sync for PenPacket
impl Unpin for PenPacket
impl UnsafeUnpin for PenPacket
impl UnwindSafe for PenPacket
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.