Skip to content

damascene 0.4.3

Latest

Choose a tag to compare

@computer-whisperer computer-whisperer released this 11 Jun 13:29
· 4 commits to main since this release

The June consumer study release. Eleven downstream apps were surveyed for footguns and papercuts; this release lands the resulting fifty-plus fixes and features (#50#106), so most known workarounds in consumer code can now be deleted.

⚠️ Breaking (yes, in a point release — we're pre-1.0 and conserving version space)

  • Key-first controlled widgets (#71): select, toggle_group, radio_group, and friends now take their key as the first argument, matching button/text_input. Mechanical migration: move the key argument first.
  • UiEventKind gained a Resized variant (#106): exhaustive matches need a new arm.

Resizable panes

.user_resizable() (#106) makes a keyed pane edge-draggable with no divider widget and no app state — an echo of CSS resize. The runtime owns the drag (an invisible 8 px band on the pane's seam edge, axis and edge derived from the parent layout), clamps to min_width/max_width and the parent's extent, stores the result in UiState like a scroll offset, and emits Resized to the pane's key on release. user_size()/set_user_size() cover persistence. resize_handle remains for visible dividers, keyboard access, and weighted splits.

Multi-window and resident daemons

  • SharedText (#94): one glyph/MSDF atlas pool per device, shared across Runners via Runner::with_shared_text — font system, shaping cache, and atlas pages warm once per device instead of once per window. Cross-runner page recycling is made safe by an LRU protection window sized to the attached-runner count. A GPU test proves shared-pool output is byte-identical to private pools.
  • WindowGfx::with_surface_and_renderer (#105): inject a pre-built, pre-warmed Runner on the window-open path, skipping ~360 ms of pipeline build + glyph warmup for daemons that pool renderers.
  • Per-window hotkey scoping (#103): the convention (each window's Runner gets only its own hotkey list) is now documented on App::hotkeys and set_hotkeys.

Custom shaders: names are the contract

Registered WGSL is now introspected (#99) and uniforms route by WGSL field name.vec4("view_bounds", b) instead of comment-enforced vec_a..vec_e packing. A key matching no declared field warns once at first draw instead of rendering garbage; non-vec4<f32> free slots fail at registration with the field name attached. New ShaderBinding::mat3/vec2 marshaling helpers. Positional aliases stay valid; existing shaders are untouched.

Widgets and layout

  • grid / virtual_grid with 2D arrow navigation (#86); visible_range() exposes the realized rows of a virtual_list for cache eviction (#87)
  • scrollbar_gutter() reserves the thumb band CSS-style (#84); fit_contain / fit_cover / fit_contain_intrinsic (#89)
  • Indexed-key helpers key::indexed + UiEvent::route_index end hand-parsed format!("{prefix}:{i}") keys (#83)
  • Tabular numerals via real OpenType tnum (#88); arrow-key roving navigation for ARIA group widgets (#63)
  • EventCx gains viewport/diagnostics parity with BuildCx (#85)

Color, images, GPU

  • SDR transfer presets GAMMA22 / BT1886, GammaExponent::GAMMA_2_2, with_reference_luminance (#91); typed Image::from_rgba_f16_in / from_rgb8 constructors (#90)
  • Oversized images downscale to the device texture limit on all three backends (#78); tessellated vector-mesh colors convert into the working color space (#77); vulkano/ash mirror wgpu's working-color-space negotiation (#61)
  • StreamingTexture owns the per-frame upload lifecycle on wgpu (#95); vulkano validates target-image usage flags with actionable errors (#93) and batches image uploads into the frame command buffer (#60); ash evicts unused image textures (#54)
  • Adapter/device failures surface as errors instead of panics, and the Android manifest filters on Vulkan support (#68)

Custom hosts and web

  • host::{input, color, gfx} expose the winit host's input mappers, color-negotiation stack, and per-window GPU bring-up for custom hosts (#79#81), plus evdev button mapping and CSS cursor names for non-winit/non-wgpu hosts (#92)
  • Web: WebHandle::destroy() for SPA embedding (#76), install_logger + Mailbox utilities (#96), soft-keyboard Enter/arrows/Delete/Home/End forwarding (#67)
  • Scene3D pre-pass exposed to draw()-path hosts (#55); fresh-handle churn now warns with a documented caching contract (#98)

Text, HTML, markdown

  • Process-global font registry so registered fonts reach measurement (#56); page-LRU atlas recycling + whole-px size quantization (#58); selection offsets snap to UTF-8 boundaries (#50)
  • HTML: document whitespace collapses per CSS white-space: normal (#51), sanitize_styles actually drops inline styles (#52), every silent drop now works or lints (#70), fragmented inline-HTML styling + md_with_lints (#69)
  • MdCache keyed render memo for streaming/backlog markdown (#97)

Fixes and docs

Focus clears when clicking a non-focusable keyed node (#65); duplicate sibling keys warn at runtime (#64); toggle/radio gap clicks no longer act (#62); horizontal wheel/trackpad delta forwards (#66); persistent scroll side-maps are LRU-bounded (#57); intrinsic cache seeds from the dynamic-list measure pass (#59); emoji + RTL parity fixtures (#75). 100% rustdoc coverage on public core items (#73), custom-host checklist (#100), blessed app patterns guide (#102), dev-profile MSDF override snippet for consumer workspaces (#101), staleness pass (#72).