Skip to content

Integrate Blitz DOM and Shell patches; add UI framework scaffolding#8

Merged
kevincarlson merged 13 commits into
mainfrom
claude/iris-phase-2-layout-ez2AW
May 19, 2026
Merged

Integrate Blitz DOM and Shell patches; add UI framework scaffolding#8
kevincarlson merged 13 commits into
mainfrom
claude/iris-phase-2-layout-ez2AW

Conversation

@kevincarlson

Copy link
Copy Markdown
Member

Summary

This PR integrates the Blitz DOM and Shell rendering engine patches into the AppThere Iris codebase, establishes the UI framework foundation, and restructures the application entry point to use the new rendering pipeline.

Key Changes

Blitz DOM Integration (crates/patches/blitz-dom/)

  • Added complete DOM implementation with styling (Stylo integration), layout (Taffy), and event handling
  • Implemented document model with node tree, element data, and attribute management
  • Added layout construction and damage tracking for incremental rendering
  • Integrated font metrics provider and inline/block layout computation
  • Added form handling, query selectors, and accessibility support
  • Included comprehensive default CSS stylesheet for HTML elements

Blitz Shell Integration (crates/patches/blitz-shell/)

  • Added windowing and event loop integration via Winit
  • Implemented event conversion layer (keyboard, mouse, IME events)
  • Added application handler and window management
  • Integrated network and accessibility support

UI Framework Scaffolding (crates/iris-app/)

  • Restructured main.rs to use Dioxus-based application architecture
  • Added modular UI components: app.rs, layout.rs, ribbon.rs, home_tab.rs, status_bar.rs, canvas_area.rs, tool_palette.rs, layers_panel.rs
  • Added application state management (state.rs)
  • Updated dependencies to include appthere-ui framework

Supporting Infrastructure

  • Added Dioxus native DOM patch (crates/patches/dioxus-native-dom/)
  • Added Fontique font library patch (crates/patches/fontique/)
  • Updated workspace root Cargo.toml to include appthere-ui
  • Modified canvas compositor to support layer rendering with tile-based blending

Dependency Updates

  • iris-app: Replaced direct canvas/pixel/vector dependencies with appthere-ui integration
  • appthere-canvas: Updated Dioxus dependency
  • appthere-ui: Removed unused thiserror dependency
  • iris-canvas: Enhanced compositor with tile data and blend mode support

Implementation Details

  • All Blitz patches follow the existing codebase conventions (300-line file limit, typed errors, no unsafe code)
  • Event handling is split across keyboard, mouse, and IME modules with a central driver
  • Layout system uses damage tracking to enable incremental rendering
  • DOM styling integrates Servo's Stylo engine for CSS computation
  • Application structure uses Dioxus components for reactive UI updates
  • Canvas rendering pipeline extended to support layer composition with opacity and blend modes

Notes

  • Blitz DOM and Shell are vendored patches from upstream projects, integrated as-is
  • The application now uses a component-based UI architecture instead of direct canvas manipulation
  • Event flow: Winit → BlitzShell → BlitzDOM → Application handlers

https://claude.ai/code/session_0124A4b3rVSawFEMkb2cUmcn

claude and others added 13 commits May 19, 2026 05:49
- Add appthere-ui to workspace members and workspace.dependencies
- Remove thiserror from appthere-ui (unused dep, OQ-F)
- Add pick_error_prefix and viewport_width_px props to AtHomeTabProps (OQ-A, OQ-D)
- Update iris-app/Cargo.toml with Phase 2 dependencies (appthere-ui, tracing-subscriber)

https://claude.ai/code/session_0124A4b3rVSawFEMkb2cUmcn
Implements the full iris-app shell using appthere_ui components:

- state.rs: AppState, OpenDocument, ToolMode, detect_platform()
- app.rs: root App component with AtThemeContext injection
- layout.rs: AppLayout composing AtTitleBar, AtTabBar, and body panels
- home_tab.rs: IrisHomeTab wrapping AtHomeTab with Iris templates
- ribbon.rs: IrisRibbon with Edit/Adjustments/Export tabs (text label placeholders)
- tool_palette.rs: ToolPalette left sidebar with Pixel/Vector mode toggle
- canvas_area.rs: CanvasArea mounting IrisCanvas with viewport sync
- layers_panel.rs: LayersPanel right sidebar with add/remove/visibility controls
- status_bar.rs: IrisStatusBar repurposing AtStatusBar for layer count + canvas dims
- main.rs: tracing init + dioxus::launch(App)

All files under 300 lines. cargo check --workspace clean. All tests pass.

https://claude.ai/code/session_0124A4b3rVSawFEMkb2cUmcn
WGSL `vec3<f32>` has 16-byte alignment, which forced `_pad` to start
at offset 48 and bloated the struct to 64 bytes. The Rust `[f32; 3]`
counterpart has 4-byte alignment, making the Rust struct 48 bytes.
wgpu validation rejected the draw call because the uploaded buffer
was 48 bytes but the shader expected 64.

Replace `_pad: vec3<f32>` with three separate `f32` scalars (_pad0,
_pad1, _pad2). All three have align=4, so they pack immediately after
opacity at offsets 36/40/44, giving a 48-byte struct on both sides.
48 is already a multiple of 16, so no struct-level padding is added.

https://claude.ai/code/session_0124A4b3rVSawFEMkb2cUmcn
…omPaintSource

Calling queue.submit() inside CustomPaintSource::render() corrupts Vello's
in-progress CommandEncoder, causing the "Encoder is invalid" crash.

Add Compositor::composite_to_texture(), which composites all visible pixel
tiles in CPU RAM (Porter-Duff over, f16→f32→sRGB u8) and uploads the result
via queue.write_texture(). This is safe to call mid-frame because it never
creates or submits a CommandEncoder.

Switch IrisCanvasPaintSource::render() to call composite_to_texture() instead
of composite(). For Phase 2 (blank document, no tile data), the CPU loop body
is never entered and the result is a transparent Rgba8Unorm texture.

The GPU BlendPass in pass.rs is retained for the Phase 4 compute path, which
will need to route through render_to_texture() rather than queue.submit().

https://claude.ai/code/session_0124A4b3rVSawFEMkb2cUmcn
"0.7.4" is a semver range (>=0.7.4 <0.8.0) and was resolving to 0.7.9.
"=0.7.4" forces the exact version so Loki-borrowed patches apply correctly.

https://claude.ai/code/session_0124A4b3rVSawFEMkb2cUmcn
The workspace pinned dioxus to =0.7.4, but dioxus's internal dep on
dioxus-native-dom is a semver range that resolves to 0.7.9 on crates.io.
The patch declared version 0.7.4, so Cargo flagged it unused.

Update the patch Cargo.toml to declare version 0.7.9 so Cargo applies the
vendored event-converter fixes (composition, touch, scroll) at the correct
resolved version.

fontique: patch remains at 0.8.0 — the crate graph uses fontique 0.6.0
(parley 0.6.0 + blitz-dom), so the 0.8.0 alias fix is correctly unused.

https://claude.ai/code/session_0124A4b3rVSawFEMkb2cUmcn
Vello's register_texture() requires COPY_SRC so it can copy the texture
into its image atlas each frame (wgpu copy operation).

The texture was created with TEXTURE_BINDING | COPY_DST, missing COPY_SRC.
When Vello attempted the atlas copy, wgpu rejected it mid-encoder with a
validation error, invalidating the encoder. Every subsequent begin_render_pass
on that encoder then failed with "Encoder is invalid".

Fix: replace TEXTURE_BINDING with COPY_SRC. COPY_DST is still needed for
the initial queue.write_texture() upload.

https://claude.ai/code/session_0124A4b3rVSawFEMkb2cUmcn
Blitz applies default browser-style body margin (~8px). Wrapping
AppLayout in a zero-margin/padding div that fills 100vw × 100vh
removes the gap around the shell chrome.

https://claude.ai/code/session_0124A4b3rVSawFEMkb2cUmcn
Blitz's UA stylesheet sets body { margin: 8px } which a div-level
margin:0 cannot override (UA vs author specificity). Inject a <style>
element at the root so blitz processes it via Origin::Author, which
beats the UA stylesheet in the cascade.

Resets html and body to: margin/padding 0, 100% × 100% fill,
overflow hidden, border-box sizing.

https://claude.ai/code/session_0124A4b3rVSawFEMkb2cUmcn
@kevincarlson kevincarlson self-assigned this May 19, 2026
@kevincarlson kevincarlson merged commit 4814969 into main May 19, 2026
1 check failed
@kevincarlson kevincarlson deleted the claude/iris-phase-2-layout-ez2AW branch May 19, 2026 11:01
@AppThere AppThere locked as resolved and limited conversation to collaborators May 19, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants