makepad/widgets/themes/README.md
Admin 874374635f widgets: glass, dock, tweaker, themes, code_editor, phone shell
Squash of 36 work commits (Sep 1–12):
  176433a  tweaker: click-again climbs the pick — the container under the children is reachable
  97e9572  speech: one STT/TTS API on every platform, through the ai-hub
  8ea3684  widgets: EventOrder reachable from the DSL; DataGrid hit-tests where it was drawn
  0fd1ea2  route: demo profile — native/demo features, side-panel and provisioning seams, hosted tiles, HTTP nav client
  cf4c84c  keys: F10 is the assistant — the exploded-view debugger moves to Shift+F10, the screen recorder to Ctrl+F10
  126d8c9  route: the demo profile runs in the browser — merged panel draw, platform clock, unavailable backends tolerated
  e21db96  route: demo review fixes — route origin, rain lifecycle, hosted route validation, request context, provisioning
  c24c206  aichat: the Window overlay — F10 in every standalone app, the in-process port, the /ai bridge routes, sheets as the pilot
  dbe43bd  wm + widgets: the AI panel on the left, pushing the body in
  5184340  platform + vj + map + files + widgets + image_tiles: the runtime owns one warm two-lane task pool — jobs never spawn threads
  697215e  route + converse + example-map: every worker comes from the runtime pool or a start-up worker
  862f3bd  asset widgets + chat ui + render: fan-outs and jobs on the runtime pool, the transcript read without a lock on draw
  976ea0e  tweaker: Shift+F10 toggles it on every platform (KeyEvent::is_tweaker_toggle, one call site; the web page swallows exactly Shift+F10 so the browser never sees it); the exploded z-layer view has no keyboard shortcut any more — it is a button in the tweaker
  4e8e4cd  flow-ui: the design pass — menu bar and toolbar with the total run bar, continuous zoom through the draw-list view transform with pointer remapping, dark checker canvas with grid steps, shadowed cards with icon labels and port icons, glowing wires, per-node progress bars, full-bleed image cards, palette cards you drag out, the fab edit controls in the inspector, a template picker behind New, model pickers from the hub; MenuBar widget in the shared crate
  075e1a7  flow-ui: pickers filled from the hub for image and text nodes, popups anchored through the canvas transform, labelled face controls, add_style explains itself, cards resize from a grip with size: vec2 kept in the file, full-bleed pictures, a click anywhere on a card selects it and still reaches the face, no remount on layout-only edits, panels float over the canvas
  a50750f  flow-ui: Flows, Running and Palette as their own rounded panels with splitters, the inspector and source pane likewise, columns resizable; gaussian frame shadows; keys and IME reach the focused face field through the canvas transform
  43302a6  flow-ui: every card owns a draw list and draws in z order, selection brings it to the front; and the design review's findings — every event kind remapped through the camera, run events keyed by run id, no remount mid-run, an input journal that survives a failed PUT, terminal states reconciled, the total bar from the planned node set, isolate ownership on instance change, popups retired before an isolate is freed, the Ask face answers on a button, the menu bar navigates by keyboard, no per-frame allocation in the canvas draw
  4ee4f4c  flow-ui: the resize path sets walks and fits through typed setters, never a script apply from the main VM on an isolate's widget — a failed apply had left a freed script object behind and wedged every frame; a resized card fills its picture box, clips its face and lets the last flexible element take the height
  cff15ac  widgets: a fab number field drops a label that cannot fit instead of crushing it to a dot
  24c927a  flow-ui + widgets: every dropdown is the searchable ComboBox
  a6c5f15  widgets: FabValueInput honours visible, so the seed picker's random mode hides the number field
  1181a3b  flow + flow-ui + widgets: every creator pipeline is a template — 55 templates in six groups (Image, Video, Audio, 3D, Vision & text, Utilities), all evaluated and engine-exercised in tests; the New picker, the flows.templates tool and the palette group the same way; the Templates menu shows them under group headings, and a menu taller than the window scrolls
  f8b9a67  widgets: preserve numeric edit completion and menu focus
  ed5f2e2  Add hotloadable OS themes and preserve widget state across style changes
  f1d3b39  Center resized app recordings on a fixed black canvas
  915fcae  Remove icon rim highlights and align compact home tile contents
  bfa7805  Keep terminal palettes theme-aware and resize above mobile keyboards
  7535ce8  Fix workspace build regressions (#1220)
  2233cbc  Replace legacy Studio with docked and canvas agent workspace
  708aa9f  code_editor: range views, anchors, prepared documents, read-only, tab stops
  0eae276  widgets: capture Studio evaluation feedback and recordings
  487c602  widgets: let Studio pump dock bodies across presentations
  c5adb93  Studio code atlas: settle-line diagnostics, index progress, chrome fades, exact search budget
  ee9ab46  widgets: every screen capture lands in the repo's local/screencap, named by app
  dcc9673  draw, widgets: the phone shell's glass, hosted-view and overlay support, app icons for the new apps
  2fbc679  wm: preserve app caption controls and add Scope to the launcher

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 13:38:48 +02:00

122 lines
7.4 KiB
Markdown

# Application styles
These Splash files define the shared widget styles used by the window manager:
`omarchy`, `macos`, `macos-dark`, `windows`, `windows-dark`, `windows-2000`,
`nextstep`, `ios`, `ios-dark`, `android`, and `android-dark`.
Each style has two phases:
- `theme.splash` installs semantic roles, typography, spacing, radii, and bevels
before stock widgets are registered.
- `widgets.splash` applies component geometry and materials after registration.
It can replace a widget's shader as well as its properties. Windows 2000's
raised buttons and sunken edit fields are examples.
The loader embeds both files for installed/wasm builds. In a native source
checkout it reads `widgets/themes/<style>/` on each selection. Edit either file
and choose the same style again from the WM's style picker to hotload it.
End a generated assignment-only Splash module with `true` so its last
assignment is evaluated as a statement.
The WM keeps its Omarchy top bar. Click the current style name to open the
dropdown. Modern desktop and mobile styles also have a Light/Dark button. Its Applications
launcher, Windows Start menus, window chrome, and hosted apps use the selected
appearance.
`desktop_style::StyleSheet` carries both phases to existing process clients
through `StudioToApp::Custom`. `Window` receives the message and requests an
application Splash reload with `Apply::ScriptReapply`. Module clients re-evaluate
their registrations in their existing isolates with the same apply mode.
Widget identities, editable text, and application Rust state are retained.
Initialize persistent script models only when `!vm.is_reload()`; read the existing
`mod.state` from application Splash. See `examples/counter/src/main.rs`. Dynamic
`View.on_render` children and embedded Splash isolates reapply the style too.
Embedded `Splash` widgets inherit the stylesheet and reapply their existing
widget tree in their own isolate.
Applications should inherit the stock component styles and read `theme.*` for
custom drawing. Apps using the older WM palette adapter can read
`makepad_wm_theme::current_for_vm` during registration, or from their owning VM
through `Cx::with_vm`. Avoid process-wide immutable palette caches: appearances
can change while an app is open. Explicit app overrides still take precedence.
The framebuffer crossfade lives in `apps/wm/src/scene.rs`. It freezes the old
GPU render target while the live scene renders the new style; it does not take
screenshots, rebuild app instances, or put transitions in the widget system.
Shell geometry interpolates over the same 650 ms interval. Floating desktop
rectangles are stored separately from the Omarchy tiling tree, so switching back
restores the tiling arrangement.
The macOS dock overlays the desktop; dragging keeps the title bar reachable but
allows window bodies behind the dock or partly offscreen. Terminals render only
their background with opacity (`MAKEPAD_WM_TERM_OPACITY`, default `0.78 0.70` for
focused/unfocused); text and ANSI cell colors remain crisp. Their foreground and
background follow the active light/dark stylesheet without restarting the PTY.
`color_terminal_bg` and `color_terminal_text` are separate semantic roles:
Windows 2000 and Android use opaque black consoles, while NeXTSTEP uses white.
The palette adapter exports them as `term.background` and `term.foreground`.
Declare both in each style so a reload resets the previous console palette.
The terminal opts into `Window.body.keyboard_resize: true`; this KeyboardView
mode reflows content above the animated keyboard instead of panning the whole
terminal out of view. Its grid and PTY resize with the available space.
`widgets/src/backdrop.rs` supplies ordered compositor checkpoints. Windows are
composited from back to front, and a glass surface samples a checkpoint below it.
Disjoint sampling footprints share a Gaussian stack, including the kernel's
support outside the visible surface. Intervening opaque or translucent content
that overlaps the footprint starts a new checkpoint. The dock is the final
consumer. Requested blur levels are combined before drawing the pyramid, so
unused deeper passes are skipped. Explicit producer/consumer links preserve GPU
ordering when pass IDs are recycled. `MAKEPAD_WM_TRACE_BLUR=1` logs stack and pass
counts when they change; normal operation does not log each frame.
In a checkout, build with `cargo build --release -p makepad-wm`, then launch
`./target/release/wm --remote` from the checkout root.
Applications launch on demand with `cargo run --release -p <package>`; there is
no binary collection to prepare. The app's window shows Cargo's compiling or
build-wait stage before the process connects, then fades into its first frame.
Installed distributions without a source checkout use sibling executables.
NeXTSTEP uses black focused title bars, gray beveled window controls, square
widgets, a right-hand vertical application dock, and its own icon family. Its
launcher opens a draggable Workspace palette with attached submenu columns.
Hold the secondary mouse button on the desktop or a window title bar, drag
through the menu and release to choose a command. The popup follows the pointer
and opens submenus to the left near the screen edge. The Omarchy top bar
and shared application state remain in place while switching styles.
Application icons use `AppIcon{name: "files" width: 32 height: 32}`. The default
`style: "auto"` follows the application's Splash stylesheet; standalone apps use
the host OS family. An explicit style ID is available for galleries. `color`
retints the Omarchy artwork; `opacity` preserves the other families' own colors.
Window captions derive their icon name from `window.app_id` (or the binary name),
and the WM's dock/taskbar/launcher use the same `AppIconDraw` renderer.
Each family has editable `icons/<app-id>.svg` assets. macOS dark and light share
app artwork, as on the OS. Unknown IDs use that family's `app.svg`. Add or edit
an SVG and reselect the style to hotload it; the complete icon sources travel in
the stylesheet to existing process and module apps. Unchanged sources keep their
parsed geometry cache. `python3 widgets/themes/build_icons.py` rebuilds the
bundled artwork families using only Python's standard library.
Use original application symbols within each OS's visual style. Files uses a
folder with documents, and Browser uses a web window with a globe; do not use
the Finder face or Safari compass artwork.
Application surfaces should use the shared `theme` roles (or app-specific aliases
that resolve to those roles), including `corner_radius` and
`container_corner_radius`. Keep content colors such as chart series and model
axes separate. Filled accent actions use `color_text_on_accent`.
Mark live fields that contain runtime UI state with `#[apply_state]` alongside
`#[live]`: stylesheet `ScriptReapply` preserves these values, while explicit
`Eval` edits and ordinary source reloads still apply. Standard panel visibility,
checkbox state, and dropdown selection use this path.
On macOS, the WM captures the complete window into a GPU texture and warps
that surface into its application icon in the dock. Minimize and restore share
the same reversible progress, without resizing or relaying out the application
during the animation. A style change invalidates minimized snapshots so the
restored window uses the current theme. `MAKEPAD_WM_TRACE_WARP=1` enables the
capture diagnostics using ordinary logs. For frame inspection,
`MAKEPAD_WM_WARP_SECONDS=5` slows the default 0.62-second animation.