Library changes outside the platform's own dependencies (those came with the platform commits above). libs/asset and libs/flow move to the Stage repository with the apps that use them.
Covers work 6f1e44649..2b1a41df4 for libs:
- wm: the Android super-app compiles tiles on the phone against the host engine
- cargo-makepad: the super-app APK is packed by `android dyn-pack`, in Rust
- cef: a page's audio can be captured instead of played
- flow: the flow-ui app and the flowgraph canvas return to the workspace, with staged progress in libs/flow
- svg: a stroke that bends tighter than its half width collapses its inner edge to the corner
- the accent a name is written with stops deciding whether search finds it
- ai stems: LaneDemixer, VocalsModel and the platform Stage origin/main needs
- The regex engine accepts \b and \B, reports the earliest match so a scan can resume after it, and can decide word boundaries on ASCII so a code sear
- workspace: Scope's settings carry the code map's tab width and the directories each prepared project hides from its map
- cef, video, platform: what Stage's browser needs from the shared layers
- platform, wm: work builds again on iOS, tvOS and wasm, and the window manager is warning-free on Windows
- ci: tools/ci, a Splash runtime that watches a branch and runs every ci.splash it finds
- stitch: the crate says what the rest of the repository says about its license
- ci: a run is one target dir and one cargo batch per target, and the wall draws
- apps: what the CI box found
- Remove Flow, asset and VJ applications moved into Stage
- tests: the workspace suite, run as a whole for the first time, passes outside the example UI tests
- libs: no warnings in the workspace check on any row
- tests: the last three failures of the CI box's night
- gif: the crate's doc examples compile
- cef: a hosted browser survives its host's exit
- tests: the three binaries over ten seconds in release come under it
- git: the memory ledger can take what it is asked for
- script: re-entrant dispatch, thread index validation, Any-based handle downcasts, UTF-8 previews; regex: never_loop fix
- fix(text): enable ttf-parser gvar-alloc for many-tuple variable fonts
- platform, widgets, wm: a touch that is taken away is cancelled, never released
- platform, wm: hosted apps ask the WM for what they cannot do themselves
- wm on Android: apps build on the phone
- task, cargo-makepad, widgets, audio: the task manager chooses its columns, graphs every process' network and disk traffic and installs itself as a D
- flowgraph: ordered ports take many wires, sockets can override their icon, and the canvas embeds as a viewport
- cef: captured frames and audio carry callback clocks and a navigation epoch
- git: timings read a portable clock
- ai: the hub's rig-fixture tests find the asset library without the asset client
- ai llm: a Metal main buffer is filled in 32 MB chunks
- diskmap: a scan lists each macOS directory in one getattrlistbulk call and classifies files without allocating or locking
- platform, widgets, audio_route, ai: window crossfades and whole-frame presents, caption controls that click, themed menus, a stereo-pair audio tap,
- builder: the Builder TUI matches the new terminal design, Windows executables carry app icons, and every app has one
- sheets, score, git, home: saves cannot cut a file short or overwrite another one, and checkouts cannot write outside the repository
- git: worktree status matches git on real repositories and can be cancelled
- cuda: builds link only the CUDA toolkit they are given, never a system install
- audio_route: one API on macOS, Windows and Linux, monitoring by default and processing only when asked, plus shaders that discard a value compile to
- platform, widgets, ai: a restyle recompiles nothing it already has, shows only complete frames, and a window can own its caption
- audio_route example: print the samples that reached the processor each second
- widgets, builder: the big widget families are features, all on by default, and the Builder takes none of them
- ai hub: a local chat with no model says so once, plainly
- ai: Claude Desktop drives any app with the F10 panel
- wm: children open no console windows on Windows
- ai: Connect hands the .mcpb to Claude Desktop itself
- civil-time: one local wall clock for every app, and it knows the zone on Windows
- ai-speech: makepad-ai-sfx (and with it ai-h3) is built only for IndexTTS
- script + wasm_bridge: no build script that reruns on every file
- build: the AI stack, csg, Scope and Source Library join the one workspace
- ai chat: the chat's backends are the CLI, MCP and cloud providers; the local model is the `localai` feature
- widgets: every widget family is a crate of its own under widgets/families, and makepad-widgets links, re-exports and registers the ones its features
- apps, examples, libs: each crate builds only the widget families it uses, and the design overlay is each app's own default feature
- livepipe: takes makepad-widgets without its default families, now that the AI stack is in the one workspace
- ai chat: a build without local AI starts on the first provider that answers here, not on "No model"
- thiserror: RUSTC_BOOTSTRAP no longer turns on the unstable generic member access API
- builder: makepad-builder.exe declares itself like a well-formed Windows program and stops a stalled build through a job object instead of taskkill
- builder + ai-cuda: the CUDA kernel progress shows in the Builder's Compile row, not scribbled over its screen
- repo: no third-party comic archive, generated models or sample asset in the tree
- builder: the Windows Builder ships as source, runs in its own console, and apps compile with Rust's GNU toolchain or Microsoft's
- win_resource: PNG decode and encode on makepad-fast-inflate instead of zune-png
- builder: one folder layout everywhere, makepad-builder.zip with only the files a Windows build reads, a Rust download over parallel connections, and
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
libs/sqlite_query reads WITHOUT ROWID tables through the index cursor,
refuses to write them, and the pager releases its process write slot on
drop. libs/tar is an in-repo tar reader with gzip through fast_inflate.
libs/git imports packed objects with bounded checkout writers and its
HTTP file responses carry a trailer. libs/code_language gains a Haskell lexer with literate (Bird) dialect
detection. libs/loader_bundle and libs/search are new;
libs/app_module carries the super-app module surface; libs/workspace
adds Settings.infinite_zoom and RendererChoice::gpu_env_value; libs/ai
builds without warnings across the hub, llm, metal and model crates;
windows-rs job object handles are c_void.
Squashed from work (the libs parts of each):
- Restore retained renderer support for Scope (libs/search)
- Share Builder target across Makepad app builds (libs/loader_bundle)
- Index local Apple Mail with Gmail labels, attachments and reimport (libs/sqlite_query)
- libs/ai: warning cleanup across the hub, llm, metal and model crates
- code_language: a Haskell lexer with literate (Bird) dialect detection
- git: packed imports and bounded checkout writers; HTTP file responses carry a trailer
- builder: dedicated-folder installer checks, catalog and runtime fixes; Windows job objects hold c_void handles (libs/windows)
- workspace: Settings.infinite_zoom, the experimental prepared map inside the glyph
- wm: the Android super-app hosts apps as on-demand dylibs (libs/app_module)
- libs/tar: an in-repo tar reader; the super-app unpacks its archives with it
- workspace: RendererChoice::gpu_env_value follows the platform's runtime GPU choice
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* Choose the Linux GPU backend at runtime and pace Wayland frames adaptively
A Vulkan-capable desktop Linux build (the `vulkan` feature, or
`MAKEPAD=vulkan`) now carries OpenGL ES as well and picks between them
when its event loop starts: Vulkan on Wayland when a hardware device
answers, OpenGL ES when none does (no driver, only a software rasterizer,
or an X11 session). `MAKEPAD_GPU=auto|gl|vulkan` overrides the choice, and
`MAKEPAD=gl` still produces an OpenGL-only binary. The feature stays
opt-in: the hosted (`--stdin-loop`) and direct renderers of such a build
are Vulkan-only, and Vulkan has no video texture import yet.
Wayland frame pacing
- Pace presents by what the backend and the session can actually do,
rather than by a fixed number (new `wayland/frame_pacer.rs`). Vulkan
runs two presents in flight only when the compositor offers `fifo-v1`
and the driver uses it; otherwise a second present would block inside
`vkQueuePresentKHR` on a callback an occluded window never receives.
OpenGL starts the next frame early only when its measured cost says the
swap would land after the outstanding callback is due, so cheap frames
are not committed twice per refresh. One present in flight, which is
what this did before, left a heavy scene at half the display rate.
- Bound the pacing gate at 250 ms so an occluded window cannot freeze the
app's clocks, and let pending screenshot requests through it.
- Treat WouldBlock on the display flush as transient.
Vulkan
- Bound the frame fence wait and the swapchain acquire on Linux instead of
waiting forever.
- Keep the per-frame packet arena mapped, recycle completed frame
resources on the window path, and ask for one more swapchain image on
Linux, where the pacing can keep two presents queued.
- Skip CPU devices unless `MAKEPAD_GPU=vulkan` asks for Vulkan explicitly.
OpenGL
- Stop repainting forever at rest: poll the texture lifetime fence once
per frame, and check for time-driven shaders only after the
zero-instance skip, as Vulkan does. The explicit
`Cx::frame_completion_serial` poll still always arms a fence.
- Upload draw-call uniforms only when they changed; they were uploaded
twice per draw call per frame. A zbias shift now marks them dirty, so a
call skipped that frame still uploads when it next draws.
- Compute the retained-instance upload plan once per buffer per frame; it
was computed three times.
- Target remote screenshot requests at the presenting window. Every
`--remote` grab timed out on OpenGL before this.
- Emit the `gpu.present` trace with render and swap timings.
Retained instances
- `upload_plan` settles segments that kept their slot and offset by `Arc`
identity, scans for the first few that moved, and only then builds a
pointer-keyed map. On a large map this took a plan from 0.3-1.5 ms to
about 0.07 ms. Results are identical to the previous planner.
- Add `collect_backlog` so a renderer can drain retirements once a frame.
Runtime backend consistency
- `CxOs::vulkan_active()` replaces the compile-time branches that decided
between the two renderers, so a build that fell back to OpenGL releases
its uniform buffers, shares host swapchains and retires textures the way
an OpenGL build does.
Wayland teardown
- Drop windows before the `Connection`, and destroy a window's EGL surface
and `wl_egl_window` before its `wl_surface`. Every OpenGL exit on
Wayland segfaulted inside NVIDIA's egl-wayland.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Make Vulkan the default on desktop Linux, with mipmaps and hosted fallback
Every desktop Linux binary now carries both renderers and picks at startup,
instead of only the apps that asked for Vulkan by name. Three things had to
be true first.
Gate the feature where the fallback exists. build.rs derived `use_vulkan`
from `target_os == "linux"` alone, which also matches OpenHarmony and every
other Linux triple, none of which carry `naga`, and it ignored
`MAKEPAD=linux_direct`, whose DRM/KMS renderer has no OpenGL fallback of its
own. The feature now only reaches x86_64/aarch64 gnu windowed builds;
`MAKEPAD=linux_direct+vulkan` remains the way to ask for direct Vulkan.
Give Vulkan a mip chain. `image_cache_use_mipmaps` was off for Vulkan
because the uploader only ever filled level 0, so every minified image
aliased. Images now allocate their full chain and fill levels below the
first with `vkCmdBlitImage`, the way `glGenerateMipmap` does, skipping
formats the device cannot linearly blit. On Robrix's sign-in icons this
takes Vulkan from 2153 pixels differing from the OpenGL render by more than
8, to 400.
Choose the hosted renderer at runtime too. `--stdin-loop` mode was
Vulkan-only in a Vulkan-capable build and panicked when no device answered,
while its host, on an X11 session, had already fallen back to OpenGL: with
the feature on by default that combination would have killed every child the
wm launches. The hosted path now selects the way the windowed one does, its
import follows the renderer the process actually started, and a hosted child
rejects software devices for the same reason a window does.
Video and `Texture::read_back` are still OpenGL-only; the video error now
names `MAKEPAD_GPU=gl`, and the feature comment says so.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* workspace: drop the renderer-routing argument and its build-time wording
One desktop Linux binary now carries both GPU backends and picks at startup,
so an app honouring a saved renderer choice passes it to the platform as
MAKEPAD_GPU and restarts itself. Nothing produces `--renderer-routed` any
more; an argument this parser does not know was already ignored, so dropping
its arm changes nothing for anyone still passing it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Keep the shared Android and direct-display paths as they were
An audit of what this branch reaches on platforms that share these files
found five places where it changed behaviour it was never meant to touch.
All of them come from code this branch made runtime-selected or relaxed.
Mipmaps are desktop Linux only, matching `image_cache_use_mipmaps`, which
is what asks for the format. An Android or Quest Vulkan build shared the
new chain code and would have allocated levels and recorded blits that
nothing there requests and nothing measured.
The mip chain also needs more of the format than it asked for. It checked
only that the format samples linearly, while `record_mip_chain` blits
between levels, so it now requires BLIT_SRC and BLIT_DST too and keeps a
single level otherwise.
Shader compilation stays a compile-time answer off desktop Linux. Whether
a draw shader is compiled to SPIR-V became a runtime `vulkan_active()`
test, which on Quest would follow an Android Vulkan init failure instead
of the build. Only desktop Linux has that fallback.
The hosted loop compiles GLSL only when OpenGL is the renderer. Losing its
cfg left it calling `gl()` in a Vulkan hosted child, which has no EGL
context, so it panicked. Its Wayland sibling already guards this way.
The direct display build keeps its software-buffer upload. `texture_for_draw`
gained a `not(linux_direct)` that was never needed: `MAKEPAD=linux_direct`
without Vulkan has its own `upload_presentable_image_software_buffer` in
os/linux/presentable.rs, and the outer gate already excludes the direct
Vulkan build.
Also: `gpu_preference` is now gated exactly where its caller is compiled,
since `vulkan_linux.rs` builds for every `target_os = "linux"` under
`use_vulkan`, and the hosted loop's imports follow the block that uses
them, which the direct Vulkan build does not compile.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Retained renderer support is back for Scope on Metal, Vulkan, OpenGL,
WebGL and the simulated GPU. A `vulkan` cargo feature picks Vulkan on
desktop Linux, Cx::gpu_backend() names the compiled GPU API, and the
direct WM builds again. Settings.renderer in libs/workspace keeps the
saved GPU API choice (Vulkan | OpenGL) behind the --renderer-routed
argument. The Android build keeps the texture alloc types imported for
OES adoption, and that import stays off the web build. The simulated
GPU builds on Linux again.
Squashed from work, without the cargo vendor snapshot the retained
renderer commit carried there:
- platform: a `vulkan` cargo feature picks Vulkan on desktop Linux; Cx::gpu_backend() names the compiled GPU API; the direct WM builds again
- workspace: Settings.renderer — the saved GPU API choice (Vulkan | OpenGL) and the --renderer-routed argument
- Restore retained renderer support for Scope
- platform: Android builds again — the texture alloc types stay imported for OES adoption
- platform: the Android texture-adoption import stays off the web build
- platform: the simulated GPU builds on Linux again
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Squash of 8 work commits (Sep 2–10):
7b9ed2c aichat: the assistant as an app — the panel owns the engine, the bus client, settings with the local-only lock
e0c6e74 aichat: the progress bar and system lines use the theme's highlight colour
8b46ce0 aichat: the composer's hint is a dark grey Ask AI, not the typed colour
b99a631 toml_parser, rust_tokenizer: rewrite both for the code analyser
3bbcea2 aichat: add Studio evaluation-feedback widget
b61845f studio: Architecture view, the third workspace mode
d7a76cf studio: add bounded code context and source APIs
524142a Split Studio into makepad director (public) and makepad scope (private)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>