Commit graph

150 commits

Author SHA1 Message Date
99ca24dbbc Merge upstream origin/work 5f99533 into nigig fork alongside dev 2026-09-25 17:32:26 +03:00
a0f46b7d83 Merge upstream origin/dev fda40f56 into nigig fork - preserve nigig hub/web_server, take upstream dev updates 2026-09-25 17:25:35 +03:00
Admin
41fc2e3b0a builder: the Builder TUI matches the new terminal design, Windows executables carry app icons, and every app has one -- plain full-screen menu (SETUP / YOUR LICENSES / MAKEPAD EXPERIMENTS / CODING AGENTS) with one status line and one progress bar; log in with an email kept in the install folder (downloads are no longer personalized); consent screens list each license agreement (Return opens it) with Agree to all / Cancel; a GPU notice screen on Windows and Linux; optional CUDA for Makepad Amp on NVIDIA GPUs; Apple developer tools screen on macOS; updates save local edits as changes/<app>-<date>.diff for a coding agent to merge back; "clean build" runs cargo clean. libs/win_resource writes Windows icon and version resources without rc.exe from the same icon source as macOS bundles; cargo-makepad uses it. Apps get icon.svg + icon_1024.png (tools/app_icons/render.sh). makepad-mac.sh and makepad-windows-preview.sh are the simulated visual specs.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-24 13:48:33 +02:00
Admin
d15996efd9 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 built by cargo makepad -- cargo makepad desktop bundle -p <crate> [--install[=DIR]] builds a self-contained, signed macOS .app (MAKEPAD_PACKAGE_DIR=resources in its own target dir, every dependency's resources plus only the fonts the binary's manifest names, icon from [package.metadata.makepad.desktop], per-app usage strings, signed with the Apple Development identity so privacy grants survive rebuilds) and installs it outside target/ (default ~/.makepad/apps), replacing the per-app package-macos.sh scripts
- task: a right-click column chooser (sections as flyouts, Default Columns), every figure and graph its own sortable column, dragged order and widths saved; per-process network bytes/packets from the kernel's ntstat control socket (matches nettop, no root), disk bytes, footprint and idle wake-ups every tick; history journal v4
- widgets: data_grid_columns, one column helper (chooser, reorder, resize, fit, sort cycle, layout text) that task uses and other tables can reuse; the menu engine refreshes marks inside an open flyout; the segmented control centres its labels on the line height and no longer glides after a moved row
- svg: a stroke join never connects to the previous subpath (the diagonal through outline icons)
- platform: home::app_data_dir; script: ScriptIp body ids widened to 14 bits (16384 bodies, was 4096) with an index of 26 bits, and a clear stop instead of aliasing past the limit
- audio_route (new): tap an app's audio output through the Core Audio process tap into a host processor (equalizer, gain, limiter, analyzer) and play it; audio_picture owns the one FFT; audio_decode probes tags and length from a file's head and tail; search::fold_words; zip_file reads archives with a trailing comment

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 22:34:45 +02:00
Admin
5ac42f026d wm on Android: the shell follows the Pixel launcher's motion -- launching from an icon grows the window from an icon-sized circle over 500 ms on the emphasized curves while the icon crossfades out (25-75 ms) and home scales to 0.97; releasing an app to Home flies it into its icon or tile on Quickstep's three springs (dock-row circle fallback), gone by 85% while home reveals from 0.85 over 1 s; the lift subtracts the 11.3 dp slop, a motion pause opens Recents with a haptic click and neighbour cards sliding in over 300 ms, >= 36 dp goes Home; All Apps is a full-screen panel rising 300 dp with the launcher's fades, home at 0.97 and hidden at 40%, opening past 40% or on a > 1 dp/ms fling. Cx::haptic_feedback reaches the Activity's performHaptic. The status band keeps the app's last sampled colour while a Recents card opens. Latency: a finger move goes to a hosted child at once with its own tick and every batched MotionEvent sample reaches it (Mail scroll touch->present 22.1 -> 15.7 ms mean). Values from AOSP Launcher3/Quickstep
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 22:34:44 +02:00
Admin
e603d6ae84 wm on Android: apps build on the phone -- the multi-process WM's APK can now carry the toolchain, source tree and prebuilt target/ (proc-pack --proc-toolchain=<tc>, written as wm-proc-ondevice.apk), like wm-dyn's super-app, but without the engine dylib: each app is a small generated wrapper crate linking the engine statically, so an on-device cargo build reuses the shipped engine rlibs and compiles only the app. With debug.makepad.wm.ondevice=1 the launcher (--build) builds the app before loading it; builds take turns on a lock, each finished library is copied to its own file in files/run/ and loaded from there, and a build or lock wait past its deadline (300 s, 600 s for the first proc-macro bootstrap) is killed with its process group and the APK's prebuilt library runs instead. Provisioning, unpacking and the proc-macro bootstrap moved out of the WM's dylib host into libs/ondevice_build, shared with wm-dyn (streaming LZ4 parts, same stamps and paths); dyn-pack's staging was factored so proc-pack reuses it. The debuggable switch is opt-in and only for the on-device APK. Proven on a Pixel 11 Pro XL: calculator's source edited in the phone's copy rebuilt in 12.7 s and showed the change; four apps built in turn in about 6 s each
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 22:34:44 +02:00
Admin
9baf6d6854 platform, wm: hosted apps ask the WM for what they cannot do themselves -- a hosted child has no OS window and, on Android, no JVM, so the clipboard menu, opening a URL, permission prompts, file pickers and HTTP were unavailable to it (Weather sat on "Loading" as a phone child process). AppToStudio::Relay / StudioToApp::Relay (appended, tags 26/27, existing ordinals pinned) carry these requests (platform/studio/src/relay.rs); the child side routes them automatically from the ordinary Cx APIs (platform/src/hosted_relay.rs), the WM executes them and answers by a host request id mapped back to the child's. HTTP for Android children is relayed through the WM's own Java HTTPS (NDK code has no TLS and the repo takes no external TLS crate), arriving as the NetworkResponses apps already handle; a relayed request fails after 60 s without an answer. The WM serves relays only to clients it holds a live connection to; open_url allows http, https, mailto, tel and geo; picked documents are copied on a worker into a per-pick cache folder (older than a day deleted); Android save/folder pickers answer cancelled until children can write through SAF. open_url, which was unimplemented on Android, now opens the URL. linux_direct gets a clipboard of its own (platform/src/direct_clipboard.rs): the WM owns it, Ctrl/Logo+C/X/V work as on X11, and children reach it through the existing copy/paste messages
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 22:34:44 +02:00
Admin
a8bf0e4dcf wm on Android: every app is its own process -- the plain makepad-wm now ships as an Android APK (cargo makepad android ... proc-pack -p makepad-wm-android) whose phone apps run as real child processes instead of dylibs loaded into the WM. The interface between WM and app shrinks to what the desktop WM uses: shared GPU buffers and the StudioToApp/AppToStudio protocol. The WM allocates each app's swapchain as AHardwareBuffers and hands them over a unix socket (AHardwareBuffer_sendHandleToUnixSocket, API 26); the child, started through the libmakepad_launch.so launcher in nativeLibraryDir (W^X allows it there), imports them into a windowless Vulkan device and renders its window pass into them (android_hosted.rs). Each app library links the engine statically, so the engine-dylib identity handling of wm-dyn is not needed. Children have no JVM: assets are read from the APK file, audio device lookup no longer goes through Java, and the startup/resize extra draw of the Activity build is repeated so the first frame carries its text. On a phone the WM asks for the soft keyboard only while the child reports a focused text field. Proven on a Pixel 11 Pro XL: all twelve phone apps launch as processes (first frame 1.6-2.4 s cold), taps reach them. Not yet: HTTP in children (the Activity build borrows Java's), clipboard/permission/file-picker relays, idle-app reclaim, and on-device builds of app libraries
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 22:34:44 +02:00
Kevin Boos
ccb1041a90
cargo-makepad: keep the android SDK at a stable path (#1253)
The SDK came from `env!("CARGO_MANIFEST_DIR")`, so every copy of the binary had
its own NDK at its own path. Switching copies changes `CMAKE_C_COMPILER`, and
cmake then deletes its cache and re-configures *without* the `-D` flags, losing
`CMAKE_SYSTEM_NAME=Android`. Deps like `aws-lc-sys` then build for the host and
Darwin forces `-arch arm64` into the NDK clang.

* default to `~/.makepad/<host-dir>`, independent of which binary runs
* migrate an existing per-checkout SDK with a single `rename`
2026-09-21 23:03:57 +02:00
Kevin Boos
b05eae3a2c
cargo-makepad: find dependency crate dirs via cargo metadata (#1246)
`cargo tree` only prints a directory for path dependencies, so for a git
dependency we fell back to the `<crate>.path` file its build script drops
in the target dir. Any tool that prunes the target dir deletes that file,
and a warm cache means the build script never re-runs to recreate it, so
`add_resources` silently found no `resources` dir for `makepad-widgets`
and packaging failed with "font assets declared by makepad.font-assets.v1
are missing on disk". Ask cargo for each package's `manifest_path`
instead, keeping the `.path` file as a last resort.
2026-09-19 08:12:59 +02:00
Admin
68e1892585 platform: the Android desk swipes at 120 Hz — offscreen render passes and framebuffers cached, SVG meshes kept, font families that complete
Measured on the Pixel 11 Pro XL (PowerVR): a pane swipe presented at
~84 fps on the 120 Hz panel, a vsync dropped every three to six frames.
simpleperf showed 22% of the CPU in the driver's shader compiler and 24%
in its render-target teardown: the Vulkan backend created a VkRenderPass
and a VkFramebuffer for every offscreen pass on every frame and destroyed
them after the fence, and on this driver each render pass compiles a
load-op shader. Offscreen draw render passes now live for the device
(keyed by formats and load/store ops) and framebuffers are cached per
render pass, attachment views and storage extent, invalidated through
texture retirement so they die after the frame that used them.

The app icons were re-tessellated from SVG every frame: one DrawSvg kept
one scale and the desk draws each icon at two or three sizes. A DrawSvg
keeps up to four meshes per device scale; the geometry pool defers frees
and releases them once per frame against the geometry ids the live draw
lists still name, so a retained draw call never sees its slot reused.

A font member whose resource can never load (the WM referenced Inter and
its other faces through `self:../../widgets/...`, unmapped in a package)
kept its family incomplete, and an incomplete family is redefined every
frame: the layout cache cleared, every label laid out again, the asset
reopened. Such a member drops out of its family once, logged, keyed on
the resource registry's generation so a resource that appears later is
asked for again. The WM names its fonts through `makepad_widgets:` and
reads the clock in-process on the UI thread instead of forking `date`
twice a second.

Android gains a `frame.cpu` trace (events, next-frame, draw and repaint
milliseconds per drawn frame) and a profileable manifest so simpleperf
can sample a release build. The dyn-pack tile proof tolerates the app's
own Dirty line after an engine rebuild.

After: SurfaceFlinger presents every swipe frame at 8.3 ms, the render
thread runs at ~45% instead of 85–97%, and the frame is paced by the GPU.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-19 00:03:14 +02:00
Admin
d86cbfe23e cargo-makepad: the super-app APK is packed by android dyn-pack, in Rust
`cargo makepad android dyn-pack` stages the relocatable checkout,
cross-builds host + engine from it through the ordinary Android build,
proves every tile's on-device command against that target/, packs the
APK with the phone toolchain, the checkout and target/ as streamed LZ4
tar parts, and rehearses the phone's first tile open from the packed
APK; `dyn-rehearse` runs that last gate alone. This replaces the
Python and shell pipeline that lived outside the tree. The stage
directory is tool-owned, every cargo phase runs under one controlled
environment recorded in the target's marker, rustc runs through
cargo-makepad itself as the remapping wrapper, and the APK is renamed
into place only after signing and the rehearsal. The host package
names its engine and tiles in [package.metadata.makepad.dyn]. Only the
three /system/bin/sh templates that run on the phone stay shell.

libs/rmeta is the rustc metadata header reader apps/wm used, now shared
with cargo-makepad; libs/tar gains a streaming ustar writer with GNU
long names; the zip writer streams to any sink so a 900 MB APK never
sits in memory.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-18 19:02:50 +02:00
Admin
384d0e031c tools: the Builder replaces makepad_loader, the web server moves to makepad/webserver, fleet scripts, docs and the workspace members
tools/makepad_builder replaces tools/makepad_loader: one build target
shared across app builds, workspace package selection, checkout
progress on the public Git API, detached built apps with a completion
state, waits for Windows security scans, manual retry after compiler
locks, dedicated-folder installer checks, catalog and runtime fixes.
tools/web_server and its scripts leave for github.com/makepad/webserver.
Arch USB clone/restore scripts, the qwen38 box scripts and the G-belt
serial test join tools/. docs/agents records the agent workflow and the
remote-control handoff protocol; AGENTS.md forbids vendored sources and
bulk imports. Cargo.toml lists apps/wm-dyn, libs/code_language,
libs/search, libs/tar, libs/loader_bundle and tools/makepad_builder,
and drops the two removed crates.

Squashed from work:
- Share Builder target across Makepad app builds
- Fix Builder workspace package selection
- Align Builder checkout progress with public Git API
- Detach built apps and show completion state
- Wait for Windows security scans
- Offer manual retry after Windows compiler locks
- docs: the agent workflow of record and the remote-control handoff protocol
- builder: dedicated-folder installer checks, catalog and runtime fixes; Windows job objects hold c_void handles
- tools: Arch USB clone/restore scripts, the qwen38 box scripts, and the G-belt serial test
- tools: the web server moves to makepad/webserver
- AGENTS.md: no vendored sources or bulk imports in the tree

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-18 12:17:59 +02:00
Admin
12d223737a tools, arch, docs, workspace, examples, sqlite, wasm_bridge
Squash of 55 work commits (Sep 1–12):
  0fd356d  windows: the vendored bindings are generated from a checked-in filter
  79882b5  fabric: a photo or a live camera to a fitted sewing pattern
  1e93309  AGENTS.md: designs stay local; no OS screenshots; focus and hidden-window laws
  aa96dbd  cargo-makepad wasm: package the bin target's wasm and create dirs before minifying
  14d0723  cargo-makepad wasm: production packaging — strip, small profile LTO, optional binaryen, size report
  79e7526  sqlite: a page-store seam — the file backend as before, an in-memory backend, and open_memory / open_with
  60ee978  cargo-makepad: package artifacts carry a content hash so a re-upload is a new URL
  611c9eb  cargo-makepad: production packaging stays off fat LTO; script VM under LTO investigated
  ab8febc  cargo-makepad: fonts packaged from the app's font manifest
  f6bbee9  wasm bridge: shared memory asks for the 4 GiB wasm32 ceiling and steps down where the engine refuses
  fb1416d  cargo-makepad: the threaded wasm module is linked with the 4 GiB wasm32 memory ceiling
  fd5d70c  cargo-makepad: the app's own resources are packaged under its bin name, which is how self:// resolves
  f51ca07  workspace: the wasm interpreter's tests build at opt-level 1 — its own profile setting is ignored inside a workspace, and opt-level 0 overflowed the script eval stack
  942ff86  sqlite: the browser store has one owner — its locks never wait on a clock
  82d0cfa  web path: the trace helper keeps its doc, the journal nonce steps a counter where there is no clock or pid
  6f8c08f  web-server: POST /api/crash stores crash reports in a rotating log on both servers
  106b38c  wasm bridge: the imported memory honours the module's declared limits
  94b8726  dj-pack: tracks in, stems through the hub, a site store snapshot out
  d9f04fc  dj-pack: pack reads caches, never creates them; dry-run writes nothing
  e6a305c  ai-hub + dj-pack: a whole track fits a stems job; long tracks split into spans
  d1910b8  web-server: a store snapshot's extensionless routes are served with the types the exporter recorded
  c1f7b53  asset-client + dj-pack: a long description never rejects a snapshot; the packer writes one bounded line
  453197d  dj-pack: analyse produces the beat grid, overview and loop-splat caches the demo cache ships
  9b4a3ca  network: every completion raises the UI signal
  fad1c49  web server: audio and text files are served, and models/ is immutable like maps/
  569b4a7  dj-pack: every CC BY and CC BY-SA version and the public domain mark are redistributable licences
  dc9cce6  workspace: no std clock on the web in any crate the web apps link — the last start-up worker death is gone
  c7639f0  clippy: timed std waits (sleep, recv_timeout, wait_timeout, park_timeout) are disallowed — they read the std clock and panic on wasm workers
  d748753  wasm bridge: the page environment carries js_worker_wait so the module links — the pool landing added the import for workers only
  ec40fdb  vj + widgets: double-click a knob or fader to reset it to its default — the Slider handles tap_count 2 and emits its normal Slide action; the deck controls carry their neutral defaults (pitch 0, gain/EQ/stems 1, filter centre, crossfader centre)
  fe23e06  AGENTS.md: the execution policy — zero locking on the UI thread as one mechanism for native and wasm, no temporary threads (the pool), the standard operating flow (Codex codes, Fable designs and reviews, Grok tests), and the tweaker on Shift+F10
  e689aea  web_server + geodata + route: live radar, wind and weather on makepad.nl/api — one bounded poller per feed, hourly, disk-backed cache served from an Arc snapshot (a restart never re-polls early), 503 warming until the first result, health reports ok/warming/unavailable with timestamps; KNMI key from --knmi-key-file, the documented anonymous open-data key otherwise; libs/geodata fetches through the platform HTTP client instead of shelling out to curl; the client retries 503 after 30 s and disables a layer only on 404
  cd33943  web_server: radar and weather run on KNMI's documented anonymous key when no --knmi-key-file is given; without --live-cache the pollers keep an in-memory cache and say so once
  2f3e393  web_server: a directory path without its trailing slash (/score) redirects to /score/ instead of 404, query preserved
  9a31d21  flow-ui + widgets: a chosen model shows no node list, and a closed ComboBox shows the start of a long label
  22b2c78  docs: streamline agent runbook and extract reference guides
  6058284  terminal: add hostable session multiplexing via tools/screen
  8a9345b  tools: migrate Cargo.toml lookups to segment-path keys
  8749b91  counter: keep app state across Splash reloads
  3ffd485  tools: add agent launcher and AIHub node update and smoke scripts
  c33a9d3  screen: add bypass and resume menu options
  c40d234  AGENTS.md: current delegation hierarchy (Grok mechanical, Codex hard, Fable manages)
  4184455  Workspace: scope lives at apps/scope (clone of makepad/scope)
  27844c9  makepad arch usb builder
  dd967eb  Workspace: drop nine members that are not in the repository
  1961768  AGENTS.md: hierarchy 2026-09-11 — Fable builds, Codex reviews, Grok proves
  9cd9f94  AGENTS.md: rendering is verified on the real GPU backend, headless is for logic tests only
  5f53254  AGENTS.md: GPU proofs may run hidden; only the headless CPU backend is out
  e950b08  docs: app-remote — hidden GPU runs vs the simulated-GPU backend, measured grab cadence, remote hazards
  9c94a77  arch: the platform plan names the simulated-GPU backend gpusim
  3009257  micro_serde: serde_json-style JsonValue accessors, pretty printer, depth limit and strict parse
  134cd76  gitignore: alternate target directories, root scratch dirs and stray logs are never source
  60ba86e  arch: the render node refs name platform/src/os/gpusim/mod.rs
  1dc571a  tools/arch_usb: Wi-Fi, Intel GPU firmware, the AI hub service and game-hardware udev rules on the Arch image; the WM session script picks the saved compositor GPU
  cc3b05a  tools/arch_usb: a polkit rule lets the arch account start, stop and restart the WM service

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 13:40:33 +02:00
Kevin Boos
2be77caa39
Fix Escape and Back ownership across widget lifecycles (#1236)
* Event: trace cancel scopes, and gate StackNavigationView's Back on ownership

A scope held by a widget that has stopped being the active thing wedges
Escape and the back gesture for everything behind it, and the only symptom
is that the gesture silently stops working -- which is indistinguishable
from there being nothing to cancel. MAKEPAD_CANCEL_TRACE=1 now logs every
scope begun and ended, and which one each press was stamped to, each named
by the call site that began it.

That location comes from #[track_caller] on both Cx::begin_cancel_scope and
CxCancelScopes::begin: the attribute propagates through the chain, so
Location::caller() names the widget rather than either of makepad's own
frames. No signature changes, no caller passes anything new, and the
existing tests needed no edits. Releases are logged from Drop rather than
end(), so giving a scope up by dropping it -- including a widget being torn
down, the case most likely to leak -- is reported exactly once on either
route.

StackNavigationView called the consuming back_pressed() whenever it was
Active, with no ownership check. A modal or pane opened over a pushed stack
view owns that press, but the view could consume it first and pop: the
wrong thing acts and the owner is starved, on one gesture. It worked only
because children are dispatched before the closure request, which is
precedence by traversal order -- the thing cancel scopes exist to replace.

A pushed view genuinely is what Back should pop when nothing is in front,
so it now holds a scope while Active and acts only when it owns the press.
Its five state writes route through a single set_nav_state that moves the
state and the scope together, acquired at the transition because ownership
is stamped before dispatch. The left_button and mouse-back-button paths
stay ungated: those are unambiguous clicks on this view, matching Modal,
which gates only back_pressed().

* Fix Escape and Back ownership across widget lifecycles

Allow gesture-specific scopes, preserve held Escape ownership across Back and focus changes, and suppress repeated Android Back dispatch without invoking Activity fallback first.

Release popup, modal, drag, and navigation scopes on every exit; support suspended navigation, isolate Pop actions, and finalize wide-window hide animations. Add focused ownership and lifecycle regressions.

Validated with 14 platform cancellation tests, 14 widget cancellation tests, Android Rust and Java checks, and a release modal Escape smoke test.

* Resolve cancel ownership from the active widget hierarchy

Bind widget scopes to their owners and resolve visibility and descendant priority only when Escape or Back begins. Retained inactive pages, collapsed controls, and unfocused windows no longer require application activation callbacks.

Preserve press ownership through repeats and release, suppress scoped or repeated TextInput Escape actions, and remove the StackNavigation cancellation activation API. Cover hierarchy, container, wrapper, focus, and gesture ownership regressions.

* Simplify cancel traversal and remove unsafe root lookup

* Reuse validated widget paths for repeated activity queries

* Remove PR-added cancellation tests and tracing

* Arbitrate the mouse back button with cancel scopes

The mouse's back button is the same navigation gesture as Android Back, but it
never received a cancel owner: handle_event clears press_owner for every event
and only restores it for Escape and BackPressed. owns_cancel was therefore false
for every scope while a MouseUp was delivered, so a widget could not gate that
button on ownership at all. The ones that tried had to fall back on ad-hoc
conditions -- "is my tab the visible one" -- which cannot express the thing that
actually decides it, namely that something else is in front.

Stamp a Back press for Event::MouseUp with the back button: in
resolve_widget_owner so widget-bound scopes are resolved against the hierarchy,
and in handle_event so ownership is settled before dispatch, exactly as for the
gesture itself.

StackNavigationView's mouse-back path is gated on that ownership to match its
back_pressed(). A pane or modal opened over a pushed view now takes the first
click and the view stays put; the second pops it. The left_button path stays
ungated, being an explicit click on the view's own header rather than a gesture
something in front of it could have a better claim to.

* Close a Modal on the mouse's back button

The back button is the desktop equivalent of the back gesture, and is arbitrated
by the same cancel scope, but Modal acted only on Escape, BackPressed, and a
click on its backdrop. A back-click inside the content did nothing at all, and
one outside it closed the modal only incidentally, as a background click.

Gated on ownership like the other two, so a modal opened over another one keeps
its place, and left inside can_dismiss so a non-dismissible modal still ignores
it. This is what lets a full-screen modal's content -- an image viewer, say --
respond to the back button without handling the gesture itself.

* Fold Modal's Escape and mouse-back checks under one ownership test

Same behaviour with one ownership test instead of two, matching how the other
cancel-gesture handlers read. Back consumption stays outside can_dismiss, so a
non-dismissible modal still blocks back-navigation for the widgets behind it.
2026-09-15 06:55:18 +02:00
b9a083c26f fix(android): bundle robius secondary dex + wrap app_main binaries
- bundle_crate_secondary_dex: merge OUT_DIR/classes.dex from dependency
  build scripts (robius-sms/trigger/ussd javac+d8 Java for manifest
  receivers/services) into the APK as classesN.dex. Without it the
  manifest declares BootReceiver/SmsReceiver/AccessibilityService that
  are missing at runtime (ClassNotFoundException on boot).
- has_explicit_lib_target: a crate with src/main.rs containing app_main!
  is an app, not a lib — generate the android wrapper ([lib] path =
  src/main.rs) so the JNI entry (activityOnCreate) is linked. Fixes
  UnsatisfiedLinkError for app crates that also ship src/lib.rs.
2026-09-10 16:26:35 +03:00
Kevin Boos
4b25a1bf1e
cargo-makepad: support custom iOS and tvOS Info.plist entries (#1221)
* cargo-makepad: declare native speech recognition metadata

* cargo-makepad: make Apple plist customization opt-in

* cargo-makepad: use macOS tools for plist overlays
2026-09-10 07:53:29 +02:00
Arena Agent
fe5b75d92d Merge latest makepad work while preserving fork game crates and apps 2026-09-05 20:55:35 +00:00
Admin
ddc4709b32 map: touch gestures — one-finger pan and double-tap zoom, two-finger pinch zoom around the midpoint, rotate with a 5° dead zone, and a parallel vertical slide for tilt, one state machine native and web; the web page keeps browser pinch-zoom out (non-passive touch listeners, touch-action none, maximum-scale 1)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WV6BzHQiJEvvK9EPc1d4ks
2026-09-03 21:58:36 +02:00
5ec5b65e8d nigig: carry workspace.dependencies into android wrapper manifest
The generated android wrapper re-creates a standalone workspace and only
forwarded [patch.*] sections from the workspace root manifest, so deps
declared via [workspace.dependencies] + workspace = true failed to inherit
in wrapped crate builds. Extract the [workspace.dependencies] section the
same way patches are handled and inject it into the wrapper manifest.
2026-09-03 10:55:00 +03:00
477421e314 nigig: NIGIG test-mode forwarding, custom manifest hook, ortho camera support
- makepad_test/runtime.rs: forward NIGIG_TEST_MODE from host env to the
  Android app via 'am start' intent extra; add wait_timeout (60s) used by
  wait_visible/wait_hidden/wait_count; make query_widgets tolerant of
  snapshot timeouts; grant READ_CONTACTS during adb setup
- makepad-platform android_jni.rs: read makepad.NIGIG_TEST_MODE intent
  extra and surface it as the NIGIG_TEST_MODE env var via apply_studio_env
- cargo_makepad compile.rs: support verbatim custom AndroidManifest.xml in
  addition to the templated variant
- makepad-xr xr_root.rs: add ortho camera controls (ortho, ortho_height,
  min/max), derive Debug on XrCamera
- docs: ANDROID.md and DESKTOP_VISIBLE.md for makepad_test
2026-09-03 10:55:00 +03:00
Admin
6c32c88d1a web-server: ETags from size and mtime, deadlines from size, Allow per resource
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WV6BzHQiJEvvK9EPc1d4ks
2026-09-02 15:42:27 +02:00
Admin
9c9c72ba8d web-server: bodies land before workers, client keys normalized, verbs fail closed
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WV6BzHQiJEvvK9EPc1d4ks
2026-09-02 15:36:09 +02:00
Admin
fd5d70c108 cargo-makepad: the app's own resources are packaged under its bin name, which is how self:// resolves
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WV6BzHQiJEvvK9EPc1d4ks
2026-09-02 14:42:22 +02:00
Admin
6b661bf4c5 web: crashes report themselves — panic text, breadcrumbs, memory, workers; a dead instance stops pumping
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WV6BzHQiJEvvK9EPc1d4ks
2026-09-02 14:37:51 +02:00
Admin
dfe2087399 web-server: O(1) report admission, one connection deadline, shared route sampler, static fallbacks, cache policy
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WV6BzHQiJEvvK9EPc1d4ks
2026-09-02 14:37:36 +02:00
Admin
fb1416d8c0 cargo-makepad: the threaded wasm module is linked with the 4 GiB wasm32 memory ceiling
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WV6BzHQiJEvvK9EPc1d4ks
2026-09-02 14:37:26 +02:00
Admin
ab8febc66d cargo-makepad: fonts packaged from the app's font manifest
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WV6BzHQiJEvvK9EPc1d4ks
2026-09-02 14:14:14 +02:00
Admin
611c9ebd8c cargo-makepad: production packaging stays off fat LTO; script VM under LTO investigated
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WV6BzHQiJEvvK9EPc1d4ks
2026-09-02 14:12:33 +02:00
Admin
60ee97858c cargo-makepad: package artifacts carry a content hash so a re-upload is a new URL
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WV6BzHQiJEvvK9EPc1d4ks
2026-09-02 14:03:59 +02:00
Admin
4d75e65b13 web server: hardening after security review — worker-only parsing, FD-relative static opens, strict framing, bounded work, panic recovery, Cloudflare-aware limits
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WV6BzHQiJEvvK9EPc1d4ks
2026-09-02 13:34:33 +02:00
Admin
14d0723872 cargo-makepad wasm: production packaging — strip, small profile LTO, optional binaryen, size report
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WV6BzHQiJEvvK9EPc1d4ks
2026-09-02 12:24:41 +02:00
Admin
aa96dbd625 cargo-makepad wasm: package the bin target's wasm and create dirs before minifying
A package whose bin name differs from the package name (apps/finance: finance) no longer
fails at packaging; the bin is resolved from cargo metadata, default-run or --bin, and the
minified JS copies are written after their directories exist.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WV6BzHQiJEvvK9EPc1d4ks
2026-09-02 10:53:12 +02:00
Admin
97e9572f42 speech: one STT/TTS API on every platform, through the ai-hub
Apps ask the hub for a recognizer or a voice and get one; where it runs is
the hub's decision. AiHub::start_stt / start_tts return poll-driven
sessions shaped like the chat session. The Auto ladder is Whisper/Kokoro in
this process (weights present, machine election), on the machine node over
loopback, on a LAN node, else the OS engine; SpeechReach::Local is the
"don't reach out" knob. Audio always comes back as PCM: the app owns the
device.

Three layers:
- makepad-ai-speech is the whole speech model family, engines only.
  libs/voice (Whisper + Silero VAD) folds in as the `whisper` and `vad`
  modules next to kokoro and indextts, each a cargo feature; the Apple
  bridges and the Speaker/VoiceTranscriber selection leave it.
- makepad-system-speech (new) is the OS speech services as blocking fns:
  Apple SpeechAnalyzer/AVSpeechSynthesizer via Swift, Windows.Media.Speech*
  on the vendored bindings, Android SpeechRecognizer/TextToSpeech through
  MakepadSpeech.java (API 26 floor), espeak-ng on Linux. It models the two
  STT shapes honestly: PCM in (Whisper, Apple) versus an engine that owns
  the microphone (Android, Windows), with capabilities the caller reads.
- the hub grows speech sessions, in-process Whisper/Kokoro workers with the
  residency election, a `whisper` wire backend (stt domain, registry entry
  pinned to ggerganov/whisper.cpp) so a Mac can serve a Quest, and a
  `language` field on the generate request.

Consumers: the Window voice input runs on an STT session and switches to
engine-mic mode when the recognizer owns the microphone; converse's
SpeechOutput is a lazily started TTS session plus a pump thread; route
drops its private speech copy for converse; vj's lyrics fallback and the
alignment bakes call the engines directly.

Verified here: speech-roundtrip through the real sessions (Apple voice in,
in-process Whisper on Metal out, 4.3% WER); system-speech-test TTS->STT
verbatim; hub/converse/system-speech unit tests; msvc, aarch64-android and
linux-gnu cross-checks; Java against android-34. Windows, Android and Linux
bridges are compile-checked only.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-01 23:32:35 +02:00
Admin
7e6e87fa1a platform: native file and save dialogs, in-house on all three desktops plus Android and iOS
Squashed from work:
- platform: native file and save dialogs, in-house on all three desktops
- platform: file dialogs on Android and iOS, and unbreak the Android build
2026-09-01 16:46:28 +02:00
Admin
2a46d2a405 Land platform, studio, and widget infra from rik2.
HTTP progress, OS file drag, RunView controllers, DropDown2, video,
remote process helpers, and the Studio runbook.
2026-08-18 14:23:57 +02:00
Kevin Boos
d0fe5f2b74
cargo_makepad: link std statically for shippable android builds (#1177)
Android builds passed `-C prefer-dynamic` unconditionally, so Rust shipped
`std` as a separate `libstd-<hash>.so`. That library is a rustup prebuilt whose
LOAD segments are only 4 KB-page aligned (`p_align 0x1000`), so it can't be
mapped on the 16 KB-page devices Android 15 allows. Google Play requires apps
targeting API 35+ to run there, so release apks were failing that bar even
though `libmakepad.so` itself was already linked with 16 KB alignment.

Only debug builds keep `prefer-dynamic` now, where the faster incremental
relink is worth having and nothing ships. Everything else links `std`
statically, which drops the separate library entirely and leaves a single
NDK-linked, 16 KB-aligned `.so`. The aab path already did this.
2026-08-13 10:04:11 +02:00
Jason Yau
947f815181
Video playback fixes and improvements (#1155)
* android oes video zero-copy and gles shader fixes

* regenerate windows-rs by windows-strip

* fix windows video freezes with MF on an MTA worker

* regenerate windows-rs by windows-strip

* MTA MF video, COM notify, YUV texture reuse

* add local video file playback support to video-player example

* NV12 Metal present, seek warm-up gate, YUV full range

* fix Linux GStreamer video: A/V mute, HLS prepare, async teardown

* no-op SelectVideoTrack/SelectAudioTrack on non-Linux backends

* Linux ALSA/Pulse: bigger buffers, fix resample setup, report device rate

* fix some warnings

* Move XInput/DirectInput device discovery off the UI thread

* fix GLSL unpack4u8 for GLES 3.0 (#version 300 es)

* Linux GStreamer: DMA-Buf NV12 OES zero-copy, optional GLMemory path

* Linux MediaPlugin: DMA-Buf NV12 and GLMemory zero-copy present APIs

* Add Windows SourceReader DXGI NV12 zero-copy video path

* fix build error

* fix GLES: add highp precision for sampler2DArray in Linux shaders

* playback speed support for android

---------

Co-authored-by: jasonqiu <jasonqiuchen@outlook.com>
Co-authored-by: jasonqiu <jasonqiu@futunn.com>
2026-08-10 12:29:33 +02:00
admin2
943a5a2a77 Fix partial Android NDK DMG extraction 2026-08-02 18:29:14 +02:00
Admin
781dd2c83e Map: bucket ceiling 17 + bake buckets 14-17 (rz18+ magnifies bucket 17)
5-bucket streams priced at ~2.6x (=130GB archive) — clamped instead:
rz18 shows bucket-17 geometry like any mid-gesture frame, GPU strokes
re-derive widths, nav icons survive. Consumption window 10..=18 stays
(harmless; ceiling makes >17 unreachable).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 17:48:42 +02:00
Kevin Boos
d6c3d5c322 cargo_makepad: don't include resources/android/ios on every platform (#1157)
* TextFlow: fix inline `<code>` spans sagging below the baseline

finish_row_center centered every walk by its own height, so a code run's
shorter walk got a larger downward shift than the surrounding prose under
`RowAlign.Center`. That undid TextFlow's baseline_shift: inline `<code>`
spans sat a few px below the line's baseline, and their descenders poked
out of the bottom of the code box.

* FinishedWalk now carries an optional `align_height` that text runs set
  to their line style's height, so every text run on a row receives the
  same centering shift and stays on the baseline. Also fixes sub- and
  superscripts drifting under `RowAlign.Center`.
* The per-style metrics probe now caches descenders too, since we need
  the full line height (ascender + descender) to compute `align_height`.

* Html/Markdown: make the fixed/code font size scale configurable

Replaces the hardcoded 0.85 `FIXED_FONT_SIZE_SCALE` consts with a
`fixed_font_size_scale` live property on TextFlow (default 0.85), so
apps can tune how much smaller `<code>` text renders than the prose.

* cargo_makepad: don't include `resources/android`/`ios` on every platform

Runtime asset bundling copied each crate's entire `resources/` tree into
every package, so `resources/android/` (manifest template, launcher icon
mipmaps) shipped as dead weight inside APK assets and Apple bundles, and
any `resources/ios/` content would ship on Android too. Those dirs are
platform-specific, so only their own platform should bundle them.

* Add `cp_all_skip_top()` to `makepad-shell`: like `cp_all()`, but skips
  top-level entries by exact name.
* Android (APK and AAB staging): bundle `resources/android/` minus the
  packaging inputs `AndroidManifest.xml.template` and `res/`, which
  already reach the package via the generated manifest and the aapt
  `res/` pipeline; skip `resources/ios/` entirely.
* Apple bundles: skip `resources/android/`, keep `resources/ios/`.
2026-08-01 10:26:31 +02:00
Admin
676255dfc2 Land route app + platform geo/permission APIs, map nav layer, geodata radar
apps/route: AI trip planner on MapView — tool broker + local/cloud agent
dispatch, nav session + simulated drive, layers/theme state, DDG image
search, trip history, tilt-shift DOF layer (linear circle-of-confusion:
level = log2 of radius, constant growth rate, tilt raises only the
ceiling; tilt-shift on by default).

Platform: Cx geo location API (macOS/iOS/Android/web) + permission
plumbing, memory watchdog, headless build cfg. Map: nav layer M0 API,
landcover drape, bridge dz. Geodata: 250m dual-radar compositor
(radar_volume) + KNMI sync. Docs for the route/glass/blur/shiny work.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 00:10:52 +02:00
Kevin Boos
95b21e650a android: don't make the surface invisible, that destroys it (#1134)
Setting MakepadSurface to be `INVISIBLE` in the pause path will
destroy that surface and cause system overlays to flash/flicker for a moment.
2026-06-30 09:42:03 +02:00
Kevin Boos
7c7003774c Detect and support hardware keyboards, distinguish from soft/virtual kbd (#1106)
* Support standard keyboard navg shortcuts/keys in TextInput

Implement platform-standard TextInput navigation and deletion behavior,
including Home, End, PageUp, PageDown, word movement, line/document
boundaries, and Shift-based selection.

* Use Apple Option/Cmd conventions on Apple targets
* Use Ctrl conventions on non-Apple targets
* Web accepts both shortcut styles for now, since we don't have a way
  to query the host OS from within a makepad web env.

Also, be extremely careful to ensure that we respect Unicode grapheme boundaries
when doing all the selection/navigation logic.

Fix `Delete`, which was erroneously handled before.

Add lots of missing keys in Linux X11 & Wayland backends, e.g.,
Home, End, Delete, Insert, PageUp/PageDown, and arrow keys

* Add `CropToFill` image fit variant, improve ImageFit docs

This allows you to easily achieve the "centered cropped fit" that most apps
want for things like avatars or small thubmnails that get masked.

* Detect and support hardware keyboards, distinguish from soft/virtual kbd

Mimic desktop behavior on mobile systems as much as possible.
This is esp important for tablets like iPad OS where you're more likely
to have a real physical keyboard attached.

For iOS:
* Arrow keys and Home/End/PageUp/PageDown navigate and auto-repeat
  at the system-defined rate (connected via `UIKeyCommand`)
* Cmd+Enter to submit a `TextInput` and Cmd+C/X/V clipboard shortcuts now work.
* Ensure the pop-up diacritic/accent menu is properly placed using a hidden
  `UITextInput` native widget, which acts as a sort of "proxy"
* Proactively drain `ShowTextIME` after each draw so the IME position will be
  properly updated after each keystroke.
* Importnatly, don't mark the IME dismissed when a hardware keyboard is attached.

For both iOS & Android:
* Add a `has_physical_keyboard()` detection mechanism across both backends,
  and fix platform-specific key repeat behavior

For Android:
* Ensure clipboard cut/copy works using the same Ctrl shortcuts (API 26+)

Soft/virtual keyboard/IME changes:
* For multiline TExtInputs, a soft keyboard Enter/Return key will always just
  insert a new line, to avoid complexity with keyboard shortcut cfgs.
* CJK keyboard character selection should also be properly positioned now

* minor optimization to avoid re-setting IME pos if it didn't change
2026-06-09 00:09:14 +02:00
Kevin Boos
f22266ddb8 cargo_makepad: fix iOS icon behavior to not override app-specific icon bundles (#1099)
* Extend support for system bar appearance to iOS too

* cargo_makepad: fix default icon behavior for iOS

Icons need to not be modified by cargo_makepad if they're already
in the proper iOS-expected format, otherwise they'll end up with
some kind of extra black border around the icon, which looks bad.
2026-06-02 10:26:25 +02:00
admin
b94ab6e985 splash md for calculator 2026-05-27 07:39:41 +02:00
Kevin Boos
42cc776dd3 Overhaul android tooling and platform layers to support Android 8 (#1091)
* Dock: avoid ID collisions in drag/drop; never delete dock root in unsplit_tabs

* Clean up and further harden dock logic around splitting/dragging

* cargo_makepad: Android App Bundle builds, API 26 support, stable toolchain

Overhaul the Android build pipeline. Three related build-tooling
changes that share compile.rs/sdk.rs and so are committed together.

Android App Bundle (.aab) support — required for Google Play uploads:
- New `build-aab` command: compile resources with aapt2, link a
  proto-format APK, assemble the base module, run bundletool, and sign
  with jarsigner.
- New `keystore-create` command wrapping keytool, with a reusable
  keystore sidecar file; new `--keystore*`, `--no-sign`,
  `--version-code`, `--version-name` flags.
- Version codes may be explicit or auto-generated as a monotonic
  YYYYMMDDHH UTC integer.
- Read app id, version, and signing metadata from
  `[package.metadata.packager]` / `[package.metadata.makepad.android]`
  in Cargo.toml; support a custom AndroidManifest.xml template.
- Upgrade the bundled TOML parser for the dotted keys, inline tables,
  and multi-line strings those metadata sections use.
- Download bundletool and copy jarsigner/keytool/aapt2 into the SDK.

minSdkVersion 26:
- Lower the default Android minimum SDK from 33 to 26 and track the
  target SDK (35) separately, emitting minSdkVersion and
  targetSdkVersion independently in the generated manifest; add a
  `--min-sdk-version` override.

Stable Rust toolchain:
- Build Android and iOS on stable instead of nightly. tvOS still needs
  nightly for `-Z build-std`, so the channel is resolved per target.
- Add `ensure_rust_toolchain_installed` (install only when missing).

* Android: load newer NDK symbols at runtime to support API 26

With the minimum SDK lowered to 26, NDK entry points that only exist
on newer API levels can no longer be declared with `extern "C"` —
doing so breaks `dlopen`/startup on API 26-28. Resolve them at
runtime instead:

- amidi_sys: lazily `dlopen` libamidi.so (API 29+) into a cached
  vtable; the wrappers degrade to error/zero returns when the library
  is absent on older devices.
- android_jni: `dlsym` the AChoreographer vsync callbacks, gated on
  the running API level.
- ndk_sys: drop the `extern "C"` declarations for
  `ANativeWindow_setFrameRate` and the Choreographer callbacks;
  android.rs drops the now-unused frame-rate call.
- MakepadActivity: guard `setInitialSurroundingSubText` (API 30+) and
  `layoutInDisplayCutoutMode` (API 28+) behind version checks.
- android_jni: the fallback render-loop thread now exits cleanly when
  the app is torn down.

* Android: automatic and app-controlled system bar appearance

Add a way to control the tint of the status and navigation bar icons,
fixing white-on-white (invisible) icons when an app draws a light
background under a system dark-mode theme.

- New `Cx::set_system_bar_appearance(SystemBarAppearance)`. The default
  `Auto` mode picks dark or light icons from the window background
  luminance; `DarkIcons`/`LightIcons` force the choice.
- The `Window` widget resolves the setting each event cycle — for
  `Auto`, the Rec.709 luma of `pass.clear_color` — and emits
  `CxOsOp::SetSystemBarDarkIcons` only when the resolved value changes.
- On Android this drives `WindowInsetsController.setSystemBarsAppearance`
  (API 30+) or the `SYSTEM_UI_FLAG_LIGHT_*` flags (API 26-29). The tint
  is re-asserted after fullscreen toggles, since the legacy path
  rewrites the whole `systemUiVisibility` bitmask.

* Android: fix soft-keyboard handling and edge-to-edge insets

Several related window-inset and IME fixes, mostly affecting devices
that are not edge-to-edge (Android versions before 15).

- Report safe-area and IME insets as the overlap with the render
  surface, not the raw window-edge insets. On a non-edge-to-edge
  window the surface already sits inside the system bars, so the raw
  insets double-counted — leaving oversized gaps around content and
  above the keyboard.
- Also drive safe-area insets from `onGlobalLayout`, so the app is
  inset correctly from launch instead of drawing under the status bar
  until the first keyboard show or rotation.
- While the keyboard animates, treat the `WindowInsetsAnimation`
  callback as the authoritative per-frame inset source and have the
  layout-driven callbacks defer to it. Read target IME visibility from
  `getRootWindowInsets()` so a show animation is not misread as an
  instant dismissal.
- Only reconfigure the Java IME when the `TextInputConfig` actually
  changes, instead of on every show.
- `KeyboardView`: compute and apply the content shift at keyboard-show
  event time, removing a one-frame lag and a tail-end jump; only
  reconcile post-draw when the focused field actually redrew.
- `Modal::close()`: skip the focus revert when the modal is already
  closed — it was stealing focus from a just-tapped text input and
  causing a first-tap keyboard flicker.
- Hide the keyboard via `WindowInsetsController.hide(ime())` on API 30+.

* platform: don't panic posting actions during shutdown

post_action no longer unwraps the global action sender. It now
silently drops the action if the sender mutex is poisoned, no Cx
sender is installed, or the receiver has been dropped during app
teardown, and only raises the UI signal when the send succeeds.

(Also shortens an over-long field doc comment in cx.rs; no behavior
change.)

* cargo-makepad: link std statically in AAB builds (16 KB page-size fix)

`-C prefer-dynamic` ships std as a separate, 4 KB-aligned libstd.so that
fails Play's 16 KB page-size rule. AAB builds now link std statically;
APK/dev builds keep prefer-dynamic. Also documents {min_sdk_version} in help.
2026-05-22 01:40:29 +02:00
Kevin Boos
30342e4234 Improve mobile IME and soft keyboard handling (#1085)
* Support overriding the dpi factor at runtime, on all platforms

Add `Cx::set_window_dpi_override` for runtime UI zoom, but dispatch it
in a deferred manner so it's safe to call in an event handler.

For each platform, we connect the dpi override to the click/tap
coordinates to remap it properly, which was done on some platforms
but not most.

* Fix and restyle todo example

* cad

* Fix todo input styling and studio build env

* fix slides

* Don't apply UI scaling (dpi override) to safe inset areas / IME areas

Scaling those areas doesn't make sense, as it can lead to empty space
(extra unnecessary padding) on the border of the IME or the device inset area,
which looks bad and is basically objectively wrong

-------------

Centralize native/physical/layout DPI conversion on `CxWindow`, and use it at platform boundaries for window geometry, safe-area insets, input coordinates, soft keyboard spacing, clipboard and selection overlays, and camera preview rects.

Add runtime `set_window_dpi_override` support that rescales all window-local metrics and emits `WindowGeomChange`.

* Improve mobile IME and soft keyboard handling

- Add broader soft keyboard configuration for input modes, autocorrect, autocapitalization, return key types, multiline, and secure text entry.
- Improve iOS text input state handling, composition ranges, selection sync, and native/layout coordinate conversion.
- Improve Android InputConnection handling for composing text, selection updates, batch edits, editor actions, surrounding text, and programmatic text sync.
- Wire TextInput through the expanded IME configuration surface.
- Cover newer iOS and Android IME APIs while preserving fallbacks for older keyboard behavior.

* Fix iOS IME area DPI override scaling

* Remove Android-specific IME hack

* Further fix Android IME to avoid stale composition ranges being underlined

espeically after you tap elsewhere in the TextInput widget

---------

Co-authored-by: admin <info@makepad.nl>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 01:14:21 +02:00
Kevin Boos
5921c558ed Don't apply UI scaling (dpi override) to safe inset areas / IME areas (#1084)
* Don't apply UI scaling (dpi override) to safe inset areas / IME areas

Scaling those areas doesn't make sense, as it can lead to empty space
(extra unnecessary padding) on the border of the IME or the device inset area,
which looks bad and is basically objectively wrong

-------------

Centralize native/physical/layout DPI conversion on `CxWindow`, and use it at platform boundaries for window geometry, safe-area insets, input coordinates, soft keyboard spacing, clipboard and selection overlays, and camera preview rects.

Add runtime `set_window_dpi_override` support that rescales all window-local metrics and emits `WindowGeomChange`.

* Fix pre-existing iOS and Android build breaks

iOS (platform/src/os/apple/ios/ios.rs): five `CxOsOp` arms had edits
that landed one match-arm late, so each block referenced bindings only
in scope on the preceding arm. Re-home them:

- `WindowGeomChange` now applies `native_window_geom_to_layout` (the
  two stray lines previously sat inside the `Paint`/`prepared` arm).
- `ShowTextIME` now converts `pos` via `layout_vec2d_to_native_points`
  (previously lodged inside the `SyncImeState` destructure pattern).
- `ShowClipboardActions` now converts `rect` / `keyboard_shift` to
  native points (previously appended to `ShowSelectionHandles`).
- `ShowSelectionHandles` / `UpdateSelectionHandles` now convert `start`
  and `end` (the `Update` arm had no conversion, and the `Show` arm's
  conversion was actually the clipboard one).
- `FullscreenWindow` / `NormalizeWindow` drop the bogus `start` / `end`
  conversions that didn't belong there.

Android (platform/src/ime.rs): `android_jni::to_java_configure_keyboard`
matches on `InputMode::None` and `ReturnKeyType::{Next, None, Previous,
Google, Yahoo, Join, Route, Continue, EmergencyCall}` — variants that
exist on the `ime_improvements` branch (commit 3dc039f0a) but weren't
pulled into this branch. Add them to the enum definitions so the
android target compiles.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 00:32:21 +02:00
admin
444bc4f310 Fix todo input styling and studio build env 2026-05-05 07:50:38 +02:00