ltk/event_loop/
repeat.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// SPDX-License-Identifier: LGPL-2.1-only
// Copyright (C) 2026 Liberux Labs, S. L. <info@liberux.net>

use crate::input::event::KeyInput;

use super::sources::TimerToken;

/// Snapshot of the key whose repeat timer is currently armed.
///
/// Stored on [`super::app_data::AppData::key_repeat`] between press and
/// release of a held-down key. The timer's calloop callback reads this
/// back to re-dispatch the same `KeyInput` against the same focus, so a
/// held arrow key keeps moving the cursor in the originally-focused text
/// input even if the focus migrates mid-repeat (which it should not —
/// release cancels the timer, and focus changes only happen via Tab /
/// pointer events that arrive after `release_key` is processed).
pub( crate ) struct KeyRepeatState
{
	pub event: KeyInput,
	pub token: TimerToken,
}

/// Snapshot of the button whose press-and-hold repeat timer is
/// currently armed. Mirrors [`KeyRepeatState`] for pointer / touch
/// presses on a [`crate::widget::button::Button`] built with
/// `.repeating( true )`. The timer's callback re-runs the press
/// against the *current* widget tree: it looks the pressed widget
/// up by `flat_idx` on the focus surface, reads its `on_press`
/// fresh, and pushes that into the pending queue. Re-resolving each
/// tick is what makes a stepper button work — the message a stepper
/// builds is `"go to value + step"` computed at view-build time, so
/// replaying the captured message would re-issue the same target
/// after the first fire and the user would see the value freeze
/// after one step. Reading the live `on_press` instead picks up the
/// new target the time picker just rebuilt with the updated value.
///
/// Cancelled on release, pointer leave, gesture cancel, focus loss
/// and long-press promotion. Also self-cancels on the first tick
/// where the widget at `idx` no longer exists or no longer carries
/// an `on_press` message — view restructuring (e.g. tab switch)
/// invalidates the snapshot and we stop rather than firing the
/// wrong widget's message.
pub( crate ) struct ButtonRepeatState
{
	/// Lets [`super::app_data::AppData::stop_button_repeat`] remove the
	/// timer from the run loop. The surface focus and pressed `flat_idx`
	/// live in the timer's closure capture instead of here — the only
	/// caller that needs to act on them is the closure itself.
	pub token: TimerToken,
}