Skip to main content

AppShell

Struct AppShell 

Source
pub struct AppShell<R>
where R: Renderer,
{ /* private fields */ }

Implementations§

Source§

impl<R> AppShell<R>
where R: Renderer, R::Error: Debug,

Source

pub fn debug_info_report(&mut self) -> String

Source

pub fn log_debug_info(&mut self) -> String

Source

pub fn layout_tree(&mut self) -> Option<&LayoutTree>

Get the current layout tree (for robot/testing)

Source

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.

Source

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.

Source

pub fn semantics_tree(&mut self) -> Option<&SemanticsTree>

Get the current semantics tree (for robot/testing)

Source

pub fn root_layout_size(&mut self) -> Option<(f32, f32)>

Source

pub fn node_layout_bounds( &mut self, target: NodeId, ) -> Option<(f32, f32, f32, f32)>

Source§

impl<R> AppShell<R>
where R: Renderer, R::Error: Debug,

Source

pub fn set_semantics_enabled(&mut self, enabled: bool)

Source

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.

Source

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>
where R: Renderer, R::Error: Debug,

Source

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.

Source

pub fn pointer_source(&self) -> PointerSource

The device source of the most recent pointer sample.

Source

pub fn set_cursor(&mut self, x: f32, y: f32) -> bool

Source

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.

Source

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.

Source

pub fn pointer_pressed(&mut self) -> bool

Source

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.

Source

pub fn pointer_pressed_at_event_time( &mut self, event_time: PointerEventTime, ) -> bool

Dispatch primary-button down with an already resolved event timestamp.

Source

pub fn pointer_released(&mut self) -> bool

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn pointer_released_at_event_time( &mut self, event_time: PointerEventTime, ) -> bool

Dispatch primary-button up with an already resolved event timestamp.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn set_on_rotary_scroll<F>(&mut self, handler: F)
where F: Fn(RotaryScrollEvent) -> bool + 'static,

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.

Source

pub fn clear_on_rotary_scroll(&mut self)

Removes the window-level rotary handler, if one is installed.

Source

pub fn rotary_scroll_factor(&self) -> f32

Pixels per rotary detent used by rotary_scrolled_by_detents.

Source

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.

Source

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.

Source

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:

  1. 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.
  2. Capture pass, root to leaf, invoking on_pre_rotary_scroll_event handlers.
  3. Bubble pass, leaf to root, invoking on_rotary_scroll_event handlers.
  4. 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.

Source

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
Source

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.

Source

pub fn clear_platform_text_input(&mut self)

Removes the platform soft-keyboard handler, if one is installed.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn set_primary_selection(&mut self, _text: &str)

Source

pub fn get_primary_selection(&mut self) -> Option<String>

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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>
where R: Renderer, R::Error: Debug,

Source

pub fn new(renderer: R, root_key: Key, content: impl FnMut() + 'static) -> Self

Source

pub fn new_with_size( renderer: R, root_key: Key, content: impl FnMut() + 'static, buffer_size: (u32, u32), viewport: (f32, f32), ) -> Self

Source

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

Source

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.

Source

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.

Source

pub fn dev_options(&self) -> &DevOptions

Get a reference to the current dev options.

Source

pub fn frame_pacing_mode(&self) -> FramePacingMode

Source

pub fn current_fps(&self) -> f32

Source

pub fn fps_stats(&self) -> FpsStats

Source

pub fn reset_fps_stats(&mut self)

Source

pub fn record_presented_frame( &mut self, frame_started_at: Instant, frame_finished_at: Instant, )

Source

pub fn set_frame_pacing_mode(&mut self, mode: FramePacingMode)

Source

pub fn handle_dev_overlay_click( &mut self, x: f32, y: f32, ) -> Option<FramePacingMode>

Source

pub fn set_viewport(&mut self, width: f32, height: f32)

Source

pub fn viewport_size(&self) -> (f32, f32)

Source

pub fn set_buffer_size(&mut self, width: u32, height: u32)

Source

pub fn buffer_size(&self) -> (u32, u32)

Source

pub fn scene(&self) -> &R::Scene

Source

pub fn renderer(&mut self) -> &mut R

Source

pub fn set_frame_waker(&mut self, waker: impl Fn() + Send + Sync + 'static)

Source

pub fn clear_frame_waker(&mut self)

Source

pub fn should_render(&self) -> bool

Source

pub fn needs_update(&self) -> bool

Source

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.

Source

pub fn mark_dirty(&mut self)

Marks the shell as dirty, indicating a redraw is needed.

Source

pub fn request_root_render(&mut self)

Source

pub fn set_density(&mut self, density: f32)

Source

pub fn has_active_animations(&self) -> bool

Returns true if there are active animations or pending recompositions.

Source

pub fn has_active_pointer_gesture(&self) -> bool

Source

pub fn next_event_time(&self) -> Option<Instant>

Returns the next scheduled event time for cursor blink. Use this for ControlFlow::WaitUntil scheduling.

Source

pub fn frame_schedule(&self) -> FrameSchedule

Source

pub fn schedule_platform_frame<D>(&self, driver: &D) -> FrameSchedule

Source

pub fn frame_scheduler_snapshot(&self) -> FrameSchedule

Source

pub fn realtime_pointer_event_time( &self, platform_time_ms: Option<i64>, ) -> PointerEventTime

Timestamp a live input sample against the current animation clock.

Source

pub fn exact_pointer_event_time( &self, platform_time_ms: Option<i64>, ) -> PointerEventTime

Timestamp deterministic input at the most recently processed frame.

Source

pub fn update_after_frame_interval( &mut self, frame_interval: Duration, ) -> FrameUpdateResult

Source

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.

Source

pub fn update_at_frame_time_nanos( &mut self, frame_time: u64, ) -> FrameUpdateResult

Source

pub fn update(&mut self) -> FrameUpdateResult

Trait Implementations§

Source§

impl<R> Drop for AppShell<R>
where R: Renderer,

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

§

impl<R> !Freeze for AppShell<R>

§

impl<R> !RefUnwindSafe for AppShell<R>

§

impl<R> !Send for AppShell<R>

§

impl<R> !Sync for AppShell<R>

§

impl<R> !UnwindSafe for AppShell<R>

§

impl<R> Unpin for AppShell<R>
where R: Unpin,

§

impl<R> UnsafeUnpin for AppShell<R>
where R: UnsafeUnpin,

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> 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, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.