pub struct AppShell<R>where
R: Renderer,{ /* private fields */ }Implementations§
Source§impl<R> AppShell<R>
impl<R> AppShell<R>
pub fn debug_info_report(&mut self) -> String
pub fn log_debug_info(&mut self) -> String
Sourcepub fn layout_tree(&mut self) -> Option<&LayoutTree>
pub fn layout_tree(&mut self) -> Option<&LayoutTree>
Get the current layout tree (for robot/testing)
Sourcepub fn semantics_active(&self) -> bool
pub fn semantics_active(&self) -> bool
Whether a semantics snapshot could contain anything at all. Reading the flag costs nothing, unlike collecting the layout-bounds map only to find semantics tracking disabled.
Sourcepub fn semantics_snapshot_revision(&mut self) -> u64
pub fn semantics_snapshot_revision(&mut self) -> u64
Monotonic revision of the accessibility-relevant state. It moves when a layout pass invalidated the cached snapshots, when semantics tracking is toggled, and when any node marked its semantics dirty since the last look. A bridge that stored the revision it last projected can skip the whole snapshot-and-compare while this still reads the same — which on an animation-only frame is every frame.
Sourcepub fn semantics_tree(&mut self) -> Option<&SemanticsTree>
pub fn semantics_tree(&mut self) -> Option<&SemanticsTree>
Get the current semantics tree (for robot/testing)
pub fn root_layout_size(&mut self) -> Option<(f32, f32)>
pub fn node_layout_bounds( &mut self, target: NodeId, ) -> Option<(f32, f32, f32, f32)>
Source§impl<R> AppShell<R>
impl<R> AppShell<R>
pub fn set_semantics_enabled(&mut self, enabled: bool)
Sourcepub fn set_frame_rate_preference(&mut self, preference: FrameRatePreference)
pub fn set_frame_rate_preference(&mut self, preference: FrameRatePreference)
Sets how the platform should vote the display’s frame rate for this
app. The default, FrameRatePreference::Auto, mirrors Compose: the
panel’s fastest rate while frames are being produced, no preference
when the scene is still.
Sourcepub fn frame_rate_preference(&self) -> FrameRatePreference
pub fn frame_rate_preference(&self) -> FrameRatePreference
The app’s current display frame-rate preference. Read by platform backends each frame; the vote itself is applied by the backend that owns the native window.
Source§impl<R> AppShell<R>
impl<R> AppShell<R>
Sourcepub fn set_pointer_source(&mut self, source: PointerSource)
pub fn set_pointer_source(&mut self, source: PointerSource)
Sets the device source (touch/mouse/stylus) of the pointer sample that
the platform is about to dispatch. Call this before set_cursor /
pointer_pressed / pointer_released so the resulting PointerEvents
carry the source so consumers can preserve device-specific gesture
details without changing shared pointer UI.
Sourcepub fn pointer_source(&self) -> PointerSource
pub fn pointer_source(&self) -> PointerSource
The device source of the most recent pointer sample.
pub fn set_cursor(&mut self, x: f32, y: f32) -> bool
Sourcepub fn set_cursor_at_time(
&mut self,
x: f32,
y: f32,
time_ms: Option<i64>,
) -> bool
pub fn set_cursor_at_time( &mut self, x: f32, y: f32, time_ms: Option<i64>, ) -> bool
Like set_cursor, but carries the platform input
timestamp (milliseconds, platform-specific time base) of the sample.
Platforms that deliver input batched/frame-aligned (Android) must use this so gesture velocity is computed from real event times instead of delivery times.
Sourcepub fn set_cursor_at_event_time(
&mut self,
x: f32,
y: f32,
event_time: PointerEventTime,
) -> bool
pub fn set_cursor_at_event_time( &mut self, x: f32, y: f32, event_time: PointerEventTime, ) -> bool
Set the cursor using a timestamp already resolved into both clock domains.
pub fn pointer_pressed(&mut self) -> bool
Sourcepub fn pointer_pressed_at_time(&mut self, time_ms: Option<i64>) -> bool
pub fn pointer_pressed_at_time(&mut self, time_ms: Option<i64>) -> bool
Like pointer_pressed, but carries the
platform input timestamp (milliseconds) of the press sample.
Sourcepub fn pointer_pressed_at_event_time(
&mut self,
event_time: PointerEventTime,
) -> bool
pub fn pointer_pressed_at_event_time( &mut self, event_time: PointerEventTime, ) -> bool
Dispatch primary-button down with an already resolved event timestamp.
pub fn pointer_released(&mut self) -> bool
Sourcepub fn pointer_released_at_position(&mut self, x: f32, y: f32) -> bool
pub fn pointer_released_at_position(&mut self, x: f32, y: f32) -> bool
Releases the pointer at the position carried by the platform’s release
sample (Android ACTION_UP, web pointerup/touchend).
The cursor is moved to (x, y) WITHOUT dispatching a Move event, then
the Up event is dispatched at that position. Platforms whose release
events carry their own coordinates must use this instead of
set_cursor* + pointer_released*: lift-off samples routinely roll back
a few dp against the travel direction as the finger peels off, and
feeding that jitter into gesture velocity trackers as a final Move
sample can flip the sign of the computed fling velocity (flings that
suddenly go the opposite way). Jetpack Compose likewise never feeds the
up sample into velocity tracking.
Sourcepub fn pointer_released_at_position_time(
&mut self,
x: f32,
y: f32,
time_ms: Option<i64>,
) -> bool
pub fn pointer_released_at_position_time( &mut self, x: f32, y: f32, time_ms: Option<i64>, ) -> bool
Like pointer_released_at_position,
but carries the platform input timestamp (milliseconds) of the release
sample.
Sourcepub fn pointer_released_at_position_event_time(
&mut self,
x: f32,
y: f32,
event_time: PointerEventTime,
) -> bool
pub fn pointer_released_at_position_event_time( &mut self, x: f32, y: f32, event_time: PointerEventTime, ) -> bool
Release at a position with an already resolved event timestamp.
Sourcepub fn pointer_released_at_time(&mut self, time_ms: Option<i64>) -> bool
pub fn pointer_released_at_time(&mut self, time_ms: Option<i64>) -> bool
Like pointer_released, but carries the
platform input timestamp (milliseconds) of the release sample.
Sourcepub fn pointer_released_at_event_time(
&mut self,
event_time: PointerEventTime,
) -> bool
pub fn pointer_released_at_event_time( &mut self, event_time: PointerEventTime, ) -> bool
Dispatch primary-button up with an already resolved event timestamp.
Sourcepub fn secondary_pointer_pressed(
&mut self,
pointer_id: u64,
x: f32,
y: f32,
time_ms: Option<i64>,
) -> bool
pub fn secondary_pointer_pressed( &mut self, pointer_id: u64, x: f32, y: f32, time_ms: Option<i64>, ) -> bool
Dispatches an event for a secondary pointer (pointer_id != 0).
Multi-touch gestures act on the element the first finger grabbed, so secondary pointers are routed to the hit path captured by the primary pointer’s Down. They carry no hover/click semantics and are ignored when no primary gesture is in progress.
Returns true when the event was dispatched to at least one target.
Sourcepub fn secondary_pointer_moved(
&mut self,
pointer_id: u64,
x: f32,
y: f32,
time_ms: Option<i64>,
) -> bool
pub fn secondary_pointer_moved( &mut self, pointer_id: u64, x: f32, y: f32, time_ms: Option<i64>, ) -> bool
Move counterpart of secondary_pointer_pressed.
Sourcepub fn secondary_pointer_released(
&mut self,
pointer_id: u64,
x: f32,
y: f32,
time_ms: Option<i64>,
) -> bool
pub fn secondary_pointer_released( &mut self, pointer_id: u64, x: f32, y: f32, time_ms: Option<i64>, ) -> bool
Release counterpart of secondary_pointer_pressed.
Sourcepub fn pointer_zoomed(&mut self, zoom_factor: f32) -> bool
pub fn pointer_zoomed(&mut self, zoom_factor: f32) -> bool
Dispatches a discrete zoom step (desktop ctrl+wheel, browser pinch) to the pointer handlers under the cursor.
zoom_factor is multiplicative: > 1.0 zooms in, < 1.0 zooms out.
Returns true if a handler consumed the event.
Sourcepub fn pointer_scrolled(&mut self, delta_x: f32, delta_y: f32) -> bool
pub fn pointer_scrolled(&mut self, delta_x: f32, delta_y: f32) -> bool
Dispatches a mouse wheel / trackpad scroll event to hovered pointer handlers.
Returns true if a handler consumed the event.
Sourcepub fn set_on_rotary_scroll<F>(&mut self, handler: F)
pub fn set_on_rotary_scroll<F>(&mut self, handler: F)
Installs the window-level rotary (Wear OS crown / rotating bezel) handler — the low-level escape hatch.
The handler runs only after the routed modifier chain has declined the
event (see rotary_scrolled), so an app that
draws everything into a single canvas receives every rotary delta
without registering a focus target or a modifier. Returning true
reports the event as consumed to the platform.
Passing a new handler replaces the previous one.
Sourcepub fn clear_on_rotary_scroll(&mut self)
pub fn clear_on_rotary_scroll(&mut self)
Removes the window-level rotary handler, if one is installed.
Sourcepub fn rotary_scroll_factor(&self) -> f32
pub fn rotary_scroll_factor(&self) -> f32
Pixels per rotary detent used by
rotary_scrolled_by_detents.
Sourcepub fn set_rotary_scroll_factor(&mut self, factor: f32)
pub fn set_rotary_scroll_factor(&mut self, factor: f32)
Sets the pixels-per-detent factor for rotary input.
On Wear OS this must be ViewConfiguration.getScaledVerticalScrollFactor()
for pixel-exact parity with Compose. The host activity can read it over
JNI once at startup and push it here; when it does not, the shell falls
back to DEFAULT_ROTARY_SCROLL_FACTOR_DP scaled by display density.
Non-finite or non-positive values are ignored.
Sourcepub fn rotary_scrolled_by_detents(
&mut self,
detents: f32,
uptime_millis: u64,
) -> bool
pub fn rotary_scrolled_by_detents( &mut self, detents: f32, uptime_millis: u64, ) -> bool
Dispatches a rotary scroll expressed in raw detents (Android
AXIS_SCROLL), converting to pixels with the configured scroll factor.
Applies Compose’s sign convention: a positive detent value (crown turned
up/away) produces a negative vertical_scroll_pixels.
Sourcepub fn rotary_scrolled(&mut self, event: RotaryScrollEvent) -> bool
pub fn rotary_scrolled(&mut self, event: RotaryScrollEvent) -> bool
Dispatches a rotary scroll event (Wear OS crown, Galaxy Watch bezel, or a desktop mouse wheel standing in for one during development).
Routing mirrors Compose’s RotaryInputModifierNode contract:
- Resolve the target chain. When a focus target is registered
([
cranpose_ui::focus_dispatch::active_focus_target]) and still exists in the current scene, its capture path is used, so rotary goes to the focused node exactly as on Wear OS. Cranpose does not yet wire focus automatically, so in practice this falls back to the chain under the current cursor position. - Capture pass, root to leaf, invoking
on_pre_rotary_scroll_eventhandlers. - Bubble pass, leaf to root, invoking
on_rotary_scroll_eventhandlers. - If still unconsumed, the window-level handler installed by
set_on_rotary_scroll.
The first handler returning true consumes the event and stops every
remaining step. Returns true when the event was consumed.
Sourcepub fn cancel_gesture(&mut self)
pub fn cancel_gesture(&mut self)
Cancels any active gesture, dispatching Cancel events to cached targets. Call this when:
- Window loses focus
- Mouse leaves window while button pressed
- Any other gesture abort scenario
Sourcepub fn set_platform_text_input(
&mut self,
handler: Rc<dyn PlatformTextInputHandler>,
)
pub fn set_platform_text_input( &mut self, handler: Rc<dyn PlatformTextInputHandler>, )
Installs the platform soft-keyboard handler for this shell’s app context.
The handler is invoked when a text field gains focus (show_keyboard)
or when text-field focus is cleared or goes stale (hide_keyboard).
Platform runtimes with an on-screen keyboard (Android, iOS) call this
once after creating the shell.
Sourcepub fn clear_platform_text_input(&mut self)
pub fn clear_platform_text_input(&mut self)
Removes the platform soft-keyboard handler, if one is installed.
Sourcepub fn notify_app_paused(&mut self)
pub fn notify_app_paused(&mut self)
Notifies the framework that the host app was paused/backgrounded.
Withdraws any outstanding soft-keyboard request (and hides the keyboard) so the “keyboard shown” state does not survive across the pause and get restored on resume with no focused field. Platform runtimes call this from their pause lifecycle event.
Sourcepub fn notify_app_resumed(&mut self) -> bool
pub fn notify_app_resumed(&mut self) -> bool
Notifies the framework that the host app resumed/foregrounded.
Never auto-shows the soft keyboard, even for a still-focused field: a
warm resume keeps the caret but must not resurrect the keyboard (the user
taps the field to bring it back). Always returns false so the platform
runtime force-hides the OS-restored keyboard. Platform runtimes call this
from their resume lifecycle event.
Sourcepub fn on_key_event(&mut self, event: &KeyEvent) -> bool
pub fn on_key_event(&mut self, event: &KeyEvent) -> bool
Routes a keyboard event to the focused text field, if any.
Returns true if the event was consumed by a text field.
On desktop, Ctrl+C/X/V are handled here when native clipboard support is enabled. On web, these keys are NOT handled here - they bubble to browser for native copy/paste events.
Sourcepub fn on_paste(&mut self, text: &str) -> bool
pub fn on_paste(&mut self, text: &str) -> bool
Handles paste event from platform clipboard.
Returns true if the paste was consumed by a focused text field.
O(1) operation using stored handler.
Sourcepub fn on_copy(&mut self) -> Option<String>
pub fn on_copy(&mut self) -> Option<String>
Handles copy request from platform. Returns the selected text from focused text field, or None. O(1) operation using stored handler.
Sourcepub fn on_cut(&mut self) -> Option<String>
pub fn on_cut(&mut self) -> Option<String>
Handles cut request from platform. Returns the cut text from focused text field, or None. O(1) operation using stored handler.
pub fn set_primary_selection(&mut self, _text: &str)
pub fn get_primary_selection(&mut self) -> Option<String>
Sourcepub fn sync_selection_to_primary(&mut self)
pub fn sync_selection_to_primary(&mut self)
Syncs the current text field selection to PRIMARY (Linux X11). Call this when selection changes in a text field.
Sourcepub fn on_ime_preedit(
&mut self,
text: &str,
cursor: Option<(usize, usize)>,
) -> bool
pub fn on_ime_preedit( &mut self, text: &str, cursor: Option<(usize, usize)>, ) -> bool
Handles IME preedit (composition) events. Called when the input method is composing text (e.g., typing CJK characters).
text: The current preedit text (empty to clear composition state)cursor: Optional cursor position within the preedit text (start, end)
Returns true if a text field consumed the event.
Sourcepub fn on_ime_finish_composing(&mut self) -> bool
pub fn on_ime_finish_composing(&mut self) -> bool
Finishes the active IME composition, keeping the composed text as
committed text (Android finishComposingText semantics).
Returns true if a text field consumed the event.
Sourcepub fn on_ime_set_composing_region(
&mut self,
start_bytes: usize,
end_bytes: usize,
) -> bool
pub fn on_ime_set_composing_region( &mut self, start_bytes: usize, end_bytes: usize, ) -> bool
Marks existing text in the focused field as the composing region
without changing it (Android setComposingRegion semantics). Offsets
are UTF-8 bytes. Returns true if a text field consumed the event.
Sourcepub fn on_ime_set_selection(
&mut self,
start_bytes: usize,
end_bytes: usize,
) -> bool
pub fn on_ime_set_selection( &mut self, start_bytes: usize, end_bytes: usize, ) -> bool
Moves the focused field’s selection/caret to [start_bytes, end_bytes)
without editing text (Android InputConnection.setSelection; the path
Gboard’s spacebar-swipe uses to scrub the cursor). Offsets are UTF-8
bytes. Returns true if a text field consumed the event.
Sourcepub fn ime_editor_state(&mut self) -> Option<ImeEditorState>
pub fn ime_editor_state(&mut self) -> Option<ImeEditorState>
Returns a snapshot of the focused text field’s editable state for
platform IMEs (text, selection and composition in UTF-8 bytes), or
None when no text field is focused.
Sourcepub fn ime_caret_geometry(&mut self) -> Option<ImeCaretGeometry>
pub fn ime_caret_geometry(&mut self) -> Option<ImeCaretGeometry>
Window-space caret geometry of the focused field for coordinate-based
platform text input (iOS trackpad cursor + tap-to-position), or None
when no text field is focused.
Sourcepub fn clear_text_field_focus(&mut self)
pub fn clear_text_field_focus(&mut self)
Clears text-field focus (used by platform IME actions such as Android’s Done). The focus-loss notification hides the soft keyboard.
Sourcepub fn on_ime_delete_surrounding(
&mut self,
before_bytes: usize,
after_bytes: usize,
) -> bool
pub fn on_ime_delete_surrounding( &mut self, before_bytes: usize, after_bytes: usize, ) -> bool
Handles IME delete-surrounding events.
Returns true if a text field consumed the event.
Source§impl<R> AppShell<R>
impl<R> AppShell<R>
pub fn new(renderer: R, root_key: Key, content: impl FnMut() + 'static) -> Self
pub fn new_with_size( renderer: R, root_key: Key, content: impl FnMut() + 'static, buffer_size: (u32, u32), viewport: (f32, f32), ) -> Self
pub fn new_with_size_and_density( renderer: R, root_key: Key, content: impl FnMut() + 'static, buffer_size: (u32, u32), viewport: (f32, f32), density: f32, ) -> Self
Sourcepub fn app_context(&self) -> &Rc<AppContext>
pub fn app_context(&self) -> &Rc<AppContext>
The shell’s AppContext. Platform backends
use it to register per-context services (such as the OS clipboard) that
need UIKit/JNI access the shell itself does not have: enter the context
and call the relevant set_platform_* installer.
Sourcepub fn set_dev_options(&mut self, options: DevOptions)
pub fn set_dev_options(&mut self, options: DevOptions)
Set development options for debugging and performance monitoring.
The FPS counter and other overlays are rendered directly by the renderer (not via composition) to avoid affecting performance measurements.
Sourcepub fn dev_options(&self) -> &DevOptions
pub fn dev_options(&self) -> &DevOptions
Get a reference to the current dev options.
pub fn frame_pacing_mode(&self) -> FramePacingMode
pub fn current_fps(&self) -> f32
pub fn fps_stats(&self) -> FpsStats
pub fn reset_fps_stats(&mut self)
pub fn record_presented_frame( &mut self, frame_started_at: Instant, frame_finished_at: Instant, )
pub fn set_frame_pacing_mode(&mut self, mode: FramePacingMode)
pub fn handle_dev_overlay_click( &mut self, x: f32, y: f32, ) -> Option<FramePacingMode>
pub fn set_viewport(&mut self, width: f32, height: f32)
pub fn viewport_size(&self) -> (f32, f32)
pub fn set_buffer_size(&mut self, width: u32, height: u32)
pub fn buffer_size(&self) -> (u32, u32)
pub fn scene(&self) -> &R::Scene
pub fn renderer(&mut self) -> &mut R
pub fn set_frame_waker(&mut self, waker: impl Fn() + Send + Sync + 'static)
pub fn clear_frame_waker(&mut self)
pub fn should_render(&self) -> bool
pub fn needs_update(&self) -> bool
Sourcepub fn needs_redraw(&self) -> bool
pub fn needs_redraw(&self) -> bool
Returns true if the shell owes the display a frame: stale pixels, or a renderer that has not warmed its swapchain yet.
An app that merely holds an open next_frame() await - a game loop, a
polling effect - keeps Self::needs_update true forever without
changing a single pixel. Such an app must still be ticked every frame,
but the frame it produces is byte-identical to the last one, and
presenting it costs a full swapchain rotation and pins the panel at its
maximum refresh rate. Callers pair this with
FrameUpdateResult::visual_changed from the update they just ran,
which reports the work that update actually did.
Note: Cursor blink is now timer-based and uses WaitUntil scheduling, not continuous redraw.
Sourcepub fn mark_dirty(&mut self)
pub fn mark_dirty(&mut self)
Marks the shell as dirty, indicating a redraw is needed.
pub fn request_root_render(&mut self)
pub fn set_density(&mut self, density: f32)
Sourcepub fn has_active_animations(&self) -> bool
pub fn has_active_animations(&self) -> bool
Returns true if there are active animations or pending recompositions.
pub fn has_active_pointer_gesture(&self) -> bool
Sourcepub fn next_event_time(&self) -> Option<Instant>
pub fn next_event_time(&self) -> Option<Instant>
Returns the next scheduled event time for cursor blink.
Use this for ControlFlow::WaitUntil scheduling.
pub fn frame_schedule(&self) -> FrameSchedule
pub fn schedule_platform_frame<D>(&self, driver: &D) -> FrameSchedulewhere
D: PlatformFrameDriver + ?Sized,
pub fn frame_scheduler_snapshot(&self) -> FrameSchedule
Sourcepub fn realtime_pointer_event_time(
&self,
platform_time_ms: Option<i64>,
) -> PointerEventTime
pub fn realtime_pointer_event_time( &self, platform_time_ms: Option<i64>, ) -> PointerEventTime
Timestamp a live input sample against the current animation clock.
Sourcepub fn exact_pointer_event_time(
&self,
platform_time_ms: Option<i64>,
) -> PointerEventTime
pub fn exact_pointer_event_time( &self, platform_time_ms: Option<i64>, ) -> PointerEventTime
Timestamp deterministic input at the most recently processed frame.
pub fn update_after_frame_interval( &mut self, frame_interval: Duration, ) -> FrameUpdateResult
Sourcepub fn update_after_exact_interval(
&mut self,
frame_interval: Duration,
) -> FrameUpdateResult
pub fn update_after_exact_interval( &mut self, frame_interval: Duration, ) -> FrameUpdateResult
Advance the frame clock by EXACTLY frame_interval past the last
frame — no wall anchoring — and run one update there. Robot keyframe
captures ride this to sample animations deterministically: while the
advanced clock is ahead of wall time, interleaved wall-clocked
updates clamp to it (dt 0) instead of fast-forwarding animations.