The platform part of work 5f9953350..163af41b7, as one step that builds (makepad-platform checks for macOS and wasm32):
- script: #[derive(Script)] emits one helper call per field, and ScriptNew's default methods keep their bodies out of every type
- platform: studio-protocol no longer waits for script, so platform starts ~0.5 s earlier
- platform: an app's package dir, icons and bundle name rebuild only that app
- script + wasm_bridge: no build script that reruns on every file
- 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 pick
- feedback: Send feedback, a caption icon and a small panel that shows exactly what is sent
- platform: MAKEPAD=gpusim builds again
- thiserror: RUSTC_BOOTSTRAP no longer turns on the unstable generic member access API
- platform (macos): a contained panic no longer frees the windows under AppKit or leaves an app that ignores quit
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The platform part of work 6941c0e86..90b6a0581, as one step that builds (makepad-platform checks for macOS and wasm32):
- platform, widgets, wm: a touch that is taken away is cancelled, never released
- wm on Android: every app is its own process
- platform, wm: hosted apps ask the WM for what they cannot do themselves
- wm on Android: app transitions and gestures feel like the phone's
- android: rotated Vulkan windows stop rebuilding their swapchain every frame, and hosted children get touch
- vulkan (android): a window released on suspend is not released again
- android: hosted children hand frames over with GPU fences and draw only when they have work
- wm on Android: the shell follows the Pixel launcher's motion
- wm on Android: the look switcher stays put, the iOS dock shows its icons, background apps follow a look change
- task, cargo-makepad, widgets, audio: the task manager chooses its columns, graphs every process' network and disk traffic and installs itself as a Dock app bu
- git: timings read a portable clock
- widgets, platform: a texture can light the relief buffer, menus take colour chips, and a style reload recompiles changed shader functions
- platform, widgets, audio_route, ai: window crossfades and whole-frame presents, caption controls that click, themed menus, a stereo-pair audio tap, and the AI
- platform: Android builds without Vulkan compile again, and the font-selection test counts the hosted entry point
- platform: the pipeline-skip repaint mark exists only on Apple, where Metal reads it
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The WM phone shell rides on it: the simulated finger in the desktop skin, time-based release velocity (80 ms window, stale after a 120 ms rest), one critically damped spring (k 900, c 60) seeded with that velocity for paging, drawer, recents and app open/close, an 8 pt / 1.2x axis lock latched through release, a drawer that tracks the finger 1:1 and draws opaque over the home tiles, hold-to-Recents precedence, launches that zoom from the icon actually drawn with an opaque launch card, no ghost card on close, and one cancel/reset path for rotation, resize, focus loss, style switch and keyboard navigation.
Co-Authored-By: Claude Opus 5.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 7 work commits (Sep 2–12):
95fd7d6 platform: a hosted window with a dpi override lays out in its own points and gets the host's pointer remapped
c2c7f51 platform: a hosted window on Windows draws again — the depth buffer matches the shared target's allocation
3b1a8c2 platform: an in-app drag works without an OS drag session (web, Linux) — effect tiles drop into the channels on the web platform: an in-app drag works without an OS drag session, so effect tiles drop into the channels on the web
5ff7397 platform: typed geometry uploads on OpenGL; the typed gate names only the backend that still lacks it
80bf3d3 platform: Linux hosted GPU transport and routing, hosted tick pacing, WGSL packed vertex members, Vulkan typed geometry
e2d8a0a platform: the Linux GL and gpusim cfgs build warning-free again
c8c757a vulkan: honor tile draw inputs and retire submitted frames correctly
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Squash of 10 work commits (Sep 2–12):
3389475 trace: one switch — MAKEPAD_TRACE=<topics>, trace!(topic, …), and /trace on the bridge
c55a315 platform: monotonic clock beside the wall clock, trap-safe dispatch, studio worker only with a studio
89fe453 platform: wheels and flight sticks are game inputs, with an output-report handle
e5d37e0 platform: a web file picker and file drop that hand apps bytes
19cf377 platform: the thread runtime contract — spawner, tasks, pools, scheduler, UI waker
cf2b8ca platform: no std::time on web — clippy guard and the platform clock everywhere a web build runs
c527cd8 vj: the web thumbnail pipeline never blocks the main thread
2a064d3 workspace: add loader, haptics, voice, and runtime fixes
541c886 platform: name heavy pool jobs over 250 ms; headless Startup sent once per Cx
d476e52 Fix Linux worker sizing and screen recording defaults
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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>
IOHIDManager claims known wheels and joystick-class devices, parses
them by HID usage (steering, pedals, twist, throttle, hat, buttons) and
hands out an IOHIDDeviceSetReport handle so an app can drive force
feedback from userspace — no kext, no DriverKit. The studio wire learns
RemoteJoystick.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A game was playable standalone and completely dead under Studio — which is
exactly where it gets developed. The cause is structural, not a binding: an
app hosted by Studio is a child process with no window of its own, so the
OS hands controller input to Studio and never to it. On macOS the child
never even reaches `init_cx_os`, so `apple_game_input` is None and
`game_input_states()` returns an empty slice forever.
So controllers now travel the same road mouse and key events already do.
`StudioToApp::GameInput` carries the whole controller set; the run view
polls its own `game_input_states` on the tick it already uses to batch
messages, and the app lands them in `Cx::game_input_remote`, which
`game_input_states()` reads whenever `in_makepad_studio` is set.
Details worth knowing:
- Sent on change only. A pad at rest reports identical level state every
tick, and that is not worth the wire. The memo drops on focus loss so
regaining focus resends rather than assuming the app still holds it.
- Only the focused run view forwards, so two open run views cannot both be
driven by one stick. That is the rule the keyboard already follows.
- The set is replaced wholesale rather than merged, so a pad that unplugs
disappears by being absent instead of freezing at its last state.
- Wheels ride along with gamepads. Forwarding only pads would have left a
wheel silently dead under Studio while a pad worked, which is a worse
failure than both being dead.
- Linux gains controllers under Studio that it does not have standalone:
its native backend is a stub, but the forwarded path is platform-neutral.
The 21-field mapping lives in ONE place with both directions together.
Written per-side it would have drifted the first time a button was added —
one end gaining a field and the other quietly reporting zero for it. The
round-trip tests give every field a distinct value, because a fixture of
uniform numbers cannot detect two crossed wires, and the sticks are pinned
separately since flattening a Vec2 to scalars is where a swap would hide.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* ft makepad_test
* Improve run handling, manifest parsing, and stdout newline
Replace dynamic free-port lookup with an ephemeral localhost SocketAddr in test runtime and remove the unused find_free_listen_address helper. Ensure headless stdout messages end with a newline. Simplify send_to_app error handling and add a test that queued bootstrap messages are delivered once an app socket connects. Substantially enhance process_manager: unify cargo flag parsing, parse Cargo.toml to determine package/bin targets, resolve the correct binary name for direct stdio runs, and build the cargo/build+exec script from the resolved args. Add unit tests for manifest parsing and script generation and adjust related call sites.
* test harness
* Preserve test attrs; return Vec for gateway binds
In the test macro (libs/makepad_test/macros/src/lib.rs) preserve wrapper-only attributes (ignore and should_panic) on the generated wrapper test while removing them from the inner function. Added Attribute import, is_wrapper_only_test_attr helper, adjusted attribute filtering and emission, and added unit tests to verify attribute placement and expansion.
In the hub (studio/hub/src/hub.rs) change gateway_bind_candidates to return a Vec<SocketAddr> instead of an iterator and special-case ephemeral port 0 to preserve ephemeral binding; otherwise collect the range of candidate ports into a Vec. Added tests to validate candidate behavior. Also minor formatting/whitespace tweaks and a small IPv6 formatting adjustment.
* Add visible Studio mode and remote client
Enable running UI tests visibly through a running Makepad Studio. Adds a new makepad-network dependency and studio_remote client (libs/makepad_test/src/studio_remote.rs) and integrates it into the runtime via a TestConnection enum. Introduces visible-mode tooling: env vars (MAKEPAD_TEST_VISIBLE, MAKEPAD_TEST_STUDIO, MAKEPAD_TEST_STUDIO_MOUNT, MAKEPAD_TEST_STARTUP_DELAY_MS, MAKEPAD_TEST_ACTION_DELAY_MS, MAKEPAD_TEST_KEEP_OPEN_MS), pacing/delays after actions, and pause-before-shutdown. Splits startup into start_headless_app/start_visible_app, clears existing visible builds before launching, and updates tests, docs (GUIDE.md, README.md), and selector/runtime minor cleanups/formatting.
Add a wasm32-specific branch in KeyModifiers::is_primary so the primary modifier is treated as true when either `logo` or `control` is set on WebAssembly targets. This preserves expected web behavior where Meta/Command or Control can act as the primary key. Also tighten the non-Apple cfg to exclude wasm32 explicitly to avoid overlapping cfg matches.