Skip to main content

Crate open_gpui_motion

Crate open_gpui_motion 

Source
Expand description

§Open GPUI Motion

open-gpui-motion contains renderer-neutral motion primitives for Open GPUI components and domain crates. It is a deterministic Rust foundation for layout-like UI motion; it is not a DOM animation runtime.

§What This Crate Owns

  • Motion preferences, duration tokens, easing tokens, and immediate reduced-motion semantics.
  • Timeline and spring scalar sampling from explicit elapsed time.
  • Policy-resolved execution plans for committed layout, continuity, affordance previews, and input-coupled paths.
  • Scalar controllers, retargeting, cancellation, explicit finish, terminal pruning, and adapter-owned frame demand.
  • MotionProgressExecution for policy-resolved normalized 0..1 adapter progress runs.
  • MotionSequence for composing many keyed scalar tracks with absolute starts, append, with-previous, after-previous, and staggered insertion while preserving renderer-neutral sampling.
  • MotionClockSample for mapping adapter Instant values into deterministic controller Duration samples with non-monotonic elapsed time clamped.
  • MotionFrameDemand::combine and MotionFrameDemand::combine_all for aggregating many motion sources into one adapter frame request.
  • MotionFrameHost for keeping adapter-owned frame request decisions consistent without depending on a GPUI window, browser scheduler, or renderer.
  • Neutral logical-pixel geometry plus projection, reveal, and clip helpers for final-size content.

Adapters keep authority over rendering, input, focus, accessibility, and frame scheduling. A Splitter, docking host, canvas, or application decides when to request a GPUI frame and how to map a motion sample into painted elements.

§First-Party Proof Scope

The v0.2.0 stable proof is intentionally small:

  • Splitter consumes scalar controller samples for programmatic panel layout transitions.
  • VirtualizedList consumes scalar controller samples for an active-descendant indicator that moves paint-only chrome by stable row key.
  • Docking consumes neutral motion geometry and projection helpers for presentation and affordance evidence.

These consumers prove deterministic clocks, normalized progress runs, retargeting, reduced-motion final state, cancellation, terminal pruning, sequence composition, and MotionFrameDemand aggregation. They do not prove row enter/exit animation, public presence, keyframes, repeat/reverse/speed controls, full shared-layout orchestration, WAAPI, or a global scheduler.

§Where To See It

Run the component gallery to inspect Splitter and VirtualizedList motion in a normal checkout:

cargo run -p open-gpui-ui-foundation-gallery

Run the docking example to inspect layout and affordance motion through the docking host:

cargo run -p open-gpui-docking-native

Both examples keep frame scheduling in their GPUI adapters. open-gpui-motion only publishes deterministic samples and frame demand.

§Boundaries

This crate deliberately does not provide React hooks, CSS parsing, DOM measurement, WAAPI behavior, browser-native acceleration, global animation loops, drag-and-drop policy, asset animation, or full shared-layout orchestration. MotionProgressExecution only owns a local 0..1 run lifecycle, and MotionSequence only owns deterministic keyed timing and sampling; neither mutates properties or schedules frames. Presence, keyframes, repeat/reverse/speed controls, public value subscriptions, and high-level builders are deferred until a first-party Open GPUI adapter proves the shape.

open-gpui-motion must stay below open-gpui-ui-core, open-gpui-ui-components, open-gpui-docking, open-gpui-platform, open-gpui-web, and renderer crates. Use conversion helpers in adapter crates to map MotionRect to renderer-specific geometry.

§Example

use open_gpui_motion::{
    MotionDuration, MotionEasing, MotionExecutionPlan, MotionFrameHost, MotionModel,
    MotionPolicyContext, MotionPolicyInput, MotionPreference, MotionScalarExecution, MotionSpec,
};
use std::time::Duration;

let spec = MotionSpec::new(
    MotionPreference::Animated,
    MotionDuration::Custom(Duration::from_millis(180)),
    MotionEasing::EaseOutStrong,
);
let plan = MotionExecutionPlan::resolve(
    MotionPolicyInput::new(MotionPolicyContext::CommittedLayout, MotionModel::timeline(spec))
        .with_spatial_motion(true)
        .with_reduced_motion_final_state(true),
);
let execution = MotionScalarExecution::start(plan, 0.0, 1.0, 0.0, Duration::ZERO);
let mut frame_host = MotionFrameHost::new();
let sample = frame_host.sample_elapsed(Duration::from_millis(90), |clock| {
    let sample = execution.sample_clock(clock);
    (sample.value(), sample.frame_demand())
});

if sample.should_request_frame() {
    // Ask the owning adapter to request a GPUI frame.
}

Reduced motion uses the same APIs and publishes the final semantic state immediately:

use open_gpui_motion::{MotionPreference, MotionSpec};

let spec = MotionSpec::committed_layout(MotionPreference::Reduced);
assert!(spec.is_immediate());

Lifecycle ordering is intentionally small: start or retarget creates active sampled state, each sample returns a frame demand, cancel freezes the sampled value and goes idle without reaching the semantic final state, finish publishes the target value as completed, reduced motion publishes the final state immediately, and adapters may prune terminal tracks after observing idle demand.

§Testing

For focused changes in this crate, run:

cargo check -p open-gpui-motion --tests --locked
cargo nextest run -p open-gpui-motion --no-fail-fast
cargo test -p open-gpui-motion --doc

When changing geometry or policy used by first-party adapters, also run the focused Splitter and docking gates documented in docs/verification.md. Renderer-neutral motion primitives for Open GPUI.

This crate owns deterministic motion specifications, sampling, policy, projection helpers, and frame-demand contracts without depending on GPUI windows, component state, docking state, or platform renderers.

Re-exports§

pub use controller::MotionClockSample;
pub use controller::MotionExecutionPlan;
pub use controller::MotionExecutionState;
pub use controller::MotionFrameDemand;
pub use controller::MotionFrameReason;
pub use controller::MotionProgressExecution;
pub use controller::MotionProgressSample;
pub use controller::MotionScalarController;
pub use controller::MotionScalarControllerSample;
pub use controller::MotionScalarExecution;
pub use controller::MotionScalarExecutionSample;
pub use controller::MotionScalarTrack;
pub use controller::MotionScalarTrackSample;
pub use frame_host::MotionFrameHost;
pub use frame_host::MotionFrameHostSample;
pub use frame_host::MotionFrameHostUpdate;
pub use geometry::MotionEdges;
pub use geometry::MotionPoint;
pub use geometry::MotionPx;
pub use geometry::MotionRect;
pub use geometry::MotionSize;
pub use geometry::motion_edges;
pub use geometry::motion_point;
pub use geometry::motion_px;
pub use geometry::motion_rect;
pub use geometry::motion_size;
pub use motion::MotionDuration;
pub use motion::MotionEasing;
pub use motion::MotionPreference;
pub use motion::MotionSpec;
pub use policy::MOTION_POLICY_MAX_UI_DURATION;
pub use policy::MotionPolicyContext;
pub use policy::MotionPolicyInput;
pub use policy::MotionPolicyIssue;
pub use policy::MotionPolicyReport;
pub use policy::MotionPreviewTargetPolicy;
pub use policy::validate_motion_policy;
pub use projection::MotionProjection;
pub use projection::MotionProjectionClip;
pub use runtime::MotionEdge;
pub use runtime::MotionRetargetItem;
pub use runtime::MotionRetargetSet;
pub use runtime::MotionRunState;
pub use runtime::MotionSnapshot;
pub use runtime::MotionTimeline;
pub use runtime::MotionTimelineSample;
pub use runtime::lerp_rect;
pub use runtime::motion_source_rect;
pub use runtime::preferred_motion_edge;
pub use runtime::retarget_motion_snapshots;
pub use runtime::reveal_rect_from_edge;
pub use sequence::MotionSequence;
pub use sequence::MotionSequenceSample;
pub use sequence::MotionSequenceStep;
pub use sequence::MotionSequenceStepSample;
pub use sequence::MotionSequenceStepState;
pub use spring::MotionModel;
pub use spring::MotionPreset;
pub use spring::MotionScalarSample;
pub use spring::MotionSpring;
pub use spring::MotionSpringPhysics;
pub use spring::MotionSpringPreset;
pub use spring::MotionSpringSpec;

Modules§

controller
Renderer-neutral motion controller contracts.
frame_host
Adapter-owned frame request helpers.
geometry
Renderer-neutral geometry values for UI component state.
motion
Renderer-neutral motion descriptors.
policy
Renderer-neutral motion policy validation.
projection
Renderer-neutral layout projection primitives.
runtime
Renderer-neutral runtime helpers for deterministic UI motion.
sequence
Renderer-neutral sequence plans for composing many motion tracks.
spring
Renderer-neutral spring sampling for layout-like UI motion.