widgetkit-runtime 0.1.0

Lifecycle-driven runtime, scheduler, and task model for WidgetKit.
Documentation

WidgetKit


language: English, Russian


Version Platform Renderer Status

WidgetKit is a modular Rust library for building desktop widgets.

The current implementation provides a working Windows host, a software 2D renderer, a stable Widget + Canvas + WindowsHost + WidgetApp public path, and a small runtime model centered on a single widget instance.

The project is intended to grow into a broader desktop widget framework with a stronger scheduler, a stabilized raw rendering API, layout primitives, declarative UI, desktop capabilities, and Tauri or hybrid integration. Some of that is already present in an early form, some is not implemented yet, and some remains internal or unstable in the current version.

Project Status

Implemented now

  • workspace
  • Windows host
  • software 2D renderer
  • stable Canvas drawing API
  • widget lifecycle with mount, start, update, render, stop, and dispose
  • instance-scoped scheduler API
  • instance-scoped task API
  • optional Tokio-backed task runtime
  • local clock example
  • demand-driven redraw model

Present but not stable yet

  • internal raw rendering foundation
  • internal scene and command model
  • internal frame and surface abstractions

These parts exist in the codebase, but they are not part of the stable top-level public API in v0.1.

Not implemented yet

  • transparent host window mode
  • frameless or overlay-style host window mode
  • placement and desktop work-area integration
  • multi-widget orchestration
  • stable public raw rendering API
  • declarative UI layer
  • advanced pointer input
  • keyboard input model
  • GPU renderer backends
  • Tauri integration
  • hybrid native/web widget composition

Intended End-State Direction

The long-term direction of the project includes the following capabilities.

Planned public architecture

  • Widget
  • Canvas
  • WindowsHost
  • WidgetApp
  • stable public raw rendering API
  • layout primitives
  • declarative UI layer
  • desktop capability modules
  • Tauri bridge
  • hybrid host model

Planned runtime direction

  • lifecycle-driven widget runtime
  • scheduler abstraction
  • task abstraction
  • optional Tokio adapter
  • stronger scheduler internals
  • stronger stale-instance protection
  • broader input model
  • multi-widget runtime model

Planned rendering direction

  • stable Canvas
  • software renderer
  • internal raw rendering layer
  • stable raw rendering API
  • richer text pipeline
  • image pipeline beyond placeholder commands
  • GPU rendering backend

Workspace Layout

widgetkit/
  crates/
    widgetkit
    widgetkit-core
    widgetkit-runtime
    widgetkit-render
    widgetkit-host-windows

widgetkit

Top-level facade crate. Re-exports the stable public API and feature-gated entry points.

widgetkit-core

Shared primitives and contracts:

  • error and result types
  • geometry
  • colors
  • ids
  • host events

widgetkit-runtime

Runtime orchestration:

  • widget lifecycle
  • WidgetApp
  • scheduler
  • task abstraction
  • event routing

widgetkit-render

Rendering stack:

  • stable Canvas
  • style types
  • software renderer
  • internal raw rendering foundation

widgetkit-host-windows

Windows-specific host implementation using winit and softbuffer.

Public API Model

The current stable public path is:

Widget + Canvas + WindowsHost + WidgetApp

Typical startup path:

use widgetkit::prelude::*;

fn main() -> widgetkit::Result<()> {
    WidgetApp::new()
        .widget("clock", ClockWidget)
        .host(WindowsHost::new())
        .renderer(SoftwareRenderer::new())
        .run()
}

Lifecycle

A widget implements the following lifecycle methods:

  • mount
  • start
  • update
  • render
  • stop
  • dispose

The current runtime model handles a single widget instance. Broader orchestration is not implemented yet.

Event Model

The public event model is intentionally small:

Event::Message(M)
Event::Host(HostEvent)

Scheduler deliveries and task completions are routed internally and surface to widgets as regular Message(M) values.

Rendering Model

Rendering is demand-driven. There is no permanent continuous render loop in the current version.

Canvas is the stable drawing surface for widgets. Internal raw rendering primitives already exist, but they remain crate-private and unstable in this version. A stable public raw rendering API is planned for a later stage.

Features

Top-level features:

  • canvas
  • windows
  • runtime-tokio

Example dependency setup:

[dependencies]
widgetkit = { version = "0.1.0", default-features = false, features = ["windows", "canvas"] }

To enable the optional Tokio-backed task runtime:

[dependencies]
widgetkit = { version = "0.1.0", default-features = false, features = ["windows", "canvas", "runtime-tokio"] }

Example

The workspace includes a local clock example.

Run it with:

cargo run --example clock --features "windows canvas"

Or with the optional Tokio task backend enabled:

cargo run --example clock --features "windows canvas runtime-tokio"

Writing a Widget

A widget defines a state type and a message type, then implements Widget.

use widgetkit::prelude::*;

struct MyWidget;

struct MyState {
    text: String,
}

#[derive(Clone, Debug)]
enum Msg {
    Tick,
}

impl Widget for MyWidget {
    type State = MyState;
    type Message = Msg;

    fn mount(&mut self, _ctx: &mut MountCtx<Self>) -> Self::State {
        MyState {
            text: "Initial".to_string(),
        }
    }

    fn start(&mut self, _state: &mut Self::State, ctx: &mut StartCtx<Self>) {
        ctx.scheduler().every(Duration::from_secs(1), Msg::Tick);
    }

    fn update(
        &mut self,
        state: &mut Self::State,
        event: Event<Self::Message>,
        ctx: &mut UpdateCtx<Self>,
    ) {
        match event {
            Event::Message(Msg::Tick) => {
                state.text = "Updated".to_string();
                ctx.request_render();
            }
            Event::Host(_) => {}
        }
    }

    fn render(&self, state: &Self::State, canvas: &mut Canvas, _ctx: &RenderCtx<Self>) {
        canvas.clear(Color::BLACK);
        canvas.text(
            Point::new(16.0, 16.0),
            &state.text,
            TextStyle::new().size(16.0),
            Color::WHITE,
        );
    }

    fn stop(&mut self, _state: &mut Self::State, ctx: &mut StopCtx<Self>) {
        ctx.scheduler().clear();
        ctx.tasks().cancel_all();
    }
}

Stability Notes

Stable in v0.1

  • Widget
  • WidgetApp
  • Canvas
  • WindowsHost
  • SoftwareRenderer
  • lifecycle method order
  • scheduler and task access through widget contexts

Internal or unstable in v0.1

  • raw render internals
  • scene and command structures
  • frame and surface internals
  • task backend implementation details
  • host internals

Current Implementation Notes

Current implementation details:

  • Windows host
  • normal decorated debug window
  • software 2D rendering
  • single-widget runtime
  • demand-driven redraw
  • raw rendering internals kept unstable

License

MIT