Commit graph

2,205 commits

Author SHA1 Message Date
Admin
6fc86ec986 box3d: README — junkyard floor mapped by recycle-disabled isolation
Pure full-update pipeline is +38% vs C (both engines, recycling forced
off), diluted to +17% by the at-parity recycle path. Gap is diffuse
(1.3-1.5x per pipeline function); all concentrated hypotheses measured
~zero, including a staging rewrite that halved build_face_a_contact's
instruction count with zero wall-clock effect (the bloat was cold code).
Note: sample attribution unreliable on PGO binaries (hot/cold splits).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 21:26:04 +02:00
Admin
2ea97f8118 box3d: README — junkyard footnote updated with post-fix verification (+17%)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 21:02:46 +02:00
Admin
26544b5944 box3d: junkyard pass — restore manifold-pipeline function boundaries (-3.6%), unchecked-hulls demoted to neutral
Disassembly attribution on current binaries: junkyard's +23% sits
entirely in the NON-SAT narrow phase (2.06x C) — the edge SAT is now
FASTER than C. Cause: LLVM+PGO mega-inlining (third occurrence) —
update_contact compiled to 5.5x C's instruction count, collide_hulls had
no symbol at all. inline(never) on collide_hulls /
compute_convex_manifold / query_face_directions restores C's layout:
junkyard -3.6% paired (retrained profile), washer neutral, others
untouched.

hull_at coverage extended to build_face_a_contact / build_polygon /
clip_segment_to_hull_face / find_incident_face for contract completeness
— measured NEUTRAL beyond the boundary fix, and the feature's earlier
-3.6% is now captured by the safe attribute instead. README documents
the demotion honestly (the safe fix superseded the unsafe one).

Gates: 179/179/185/179 tests (default/unchecked-hulls/dp/nosimd), hash
0x61E35C31 everywhere, zero warnings. PGO profile retrained.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 20:40:33 +02:00
Admin
87becc49d5 box3d: README — unchecked-hulls deltas noted in the matrix, idea review moved to bottom section
Matrix cells stay default-build (cold-window run); the hull scenes'
opt-in feature gains are annotated as paired deltas rather than absolute
cross-session numbers (thermal windows differ ~10%, mixing them would
misstate both). Algebraic-float-ops evaluation moved to a dedicated
'Evaluated ideas' section at the bottom.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 20:06:00 +02:00
Admin
76881df6be box3d: unchecked-hulls opt-in feature + algebraic-float-ops evaluation
unchecked-hulls (off by default): elides bounds checks on hull-topology
indexing in the three SAT hot loops via a cfg'd accessor. Safety contract
= hull connectivity invariants validated at construction (hull.rs
is_valid_hull_impl + create_hull asserts), immutable behind Arc; debug
builds always assert, so every test run exercises the contract. Measured
(paired, retrained PGO): junkyard -3.6%, washer -2%, nothing elsewhere —
documented honestly that the checks were NOT most of the hull residue.
Tests 179 green with and without the feature; hash 0x61E35C31 both.

README: evaluation of the newly-stabilized algebraic float ops idea —
incompatible with the determinism contract as a default (compiler-
version/ISA-dependent results break cross-arch equality and cross-build
replay), modest expected upside since hot paths are already hand-
contracted; possible future opt-in, not planned.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 19:55:41 +02:00
Admin
0e73adeded box3d: parallelize finalize-bodies + bullet passes — 8-worker geomean +28% -> +11% vs C
A sweep of every C b3ParallelFor/enqueue dispatch against the port found
the finalize-bodies pass (per-body transforms, AABB updates, sleep
accounting, continuous/TOI) and the bullet pass were left serial when
threading was ported — C runs both under b3ParallelFor. rain's w=8 gap
was almost entirely this serial fraction (Amdahl decomposition showed
its parallel portion already at C parity).

FinalizeCtx mirrors the collide pass's pattern: taken arrays + SyncSlice
disjoint per-body access, per-worker task contexts, deterministic merges
(bitset OR, split-candidate max like C), bullet list via atomic cursor
(C's b3AtomicFetchAddInt mirror). No new unsafe primitives. Pre-solve/
custom-filter callbacks force single-worker like collide.

w=8: rain +42% -> +8%, joint_grid +36% -> +11%, large_pyramid and
many_pyramids and trees25 at parity; geomean +11%. Serial geomean +5%
(Rust wins joint_grid/large_pyramid/many_pyramids outright). PGO profile
retrained; README tables + narrative updated. Remaining known
serial-vs-C difference: the split-island enqueue overlap (documented).

Hash 0x61E35C31 bit-identical (runs, workers 1/2/4, external tasks);
179/185/179 tests, zero warnings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 19:24:46 +02:00
Admin
b1ed1da285 box3d: PGO trains on all 10 scenes; small-stage fast path tested and dropped
Training set was missing washer and trees50/25 (washer -1.5% with
coverage, large_pyramid unchanged — no dilution). Profile refreshed.

Small-stage main-only fast path (generalizing C's single-block
shortcut): swept cutoffs 32/64/256 at w=8 — only large_world benefited
(-8% of ~11ms); rain regressed at every cutoff (its small-count stages
are mesh-contact stages with heavy per-item cost — serializing them
starves real parallelism) and joint_grid has few fat stages (grid
coloring = 2-4 colors), so its w=8 gap is NOT thin-stage sync. Reverted
per the measurable-win rule; negative result documented in the README.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 18:39:18 +02:00
Admin
5cdc70be06 box3d: narrow joint write-backs — joint_grid at C parity, serial geomean +7%
Disassembly census showed the joint solvers at exact FMA parity with C
but +110 loads/+54 stores per joint: the full 56-byte BodyState get/set
round trip keeps untouched fields live across the ~1000-instruction
solve bodies. StateAccess::set_velocities (same unsafe contract as set,
velocities only, like C's in-place stores) + get_ref field extraction
across all 16 warm-start/solve functions in the 8 joint types.

joint_grid: 817 vs C 801 ms (was -11%). Full fresh matrix in README:
serial geomean +7% vs C with Rust WINNING large_pyramid (-6%) and
many_pyramids (-3%); w=8 geomean +28%. Checked-in PGO profile retrained
for the new code (stale profile cost ~13% on joint scenes).

Same change was measured neutral for contact scatter and correctly
dropped there (state live ~40 instrs vs ~1000) — both verdicts in the
README as a paired case study.

Hash 0x61E35C31 bit-identical everywhere; 179/185/179 tests, zero
warnings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 18:29:55 +02:00
Admin
cfbc70ee77 box3d: README — percentage deltas in the comparison table
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 17:03:35 +02:00
Admin
b061e1ad8c box3d: check in PGO profile, apply by default via workspace .cargo/config.toml
cargo build --release on anything in the workspace now gets the PGO'd
box3d automatically (-Cprofile-use=libs/box3d/box3d.profdata; verified:
default build runs at the explicit-PGO binary's speed). The profile is
target-independent — x86_64 cross-build with the ARM-trained profile
compiles clean — and degrades gracefully when stale (unmatched functions
keep normal heuristics). Retrain with libs/box3d/pgo.sh.

Fresh four-way interleaved matrix in the README: default box3d is now
faster than or equal to rapier-simd on all three scenes (1118 vs 1451,
1510 vs 1690, 912 vs 914 ms) and faster than non-PGO C on two of three
(C keeps joint_grid 816 vs 912). 179/185/179 tests green with the
config active.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 16:59:17 +02:00
Admin
913dfd4562 box3d: PGO build recipe — 11-19% over plain fat-LTO, hash bit-identical
pgo.sh: instrument -> train on the benchmark scenes -> merge -> rebuild.
Paired same-machine runs: large_pyramid 1177 vs 1457 ms (-19%, now 15%
faster than the non-PGO C build), junkyard -14%, many_pyramids -11%.
Determinism hash unchanged under the PGO binary (0x61E35C31 across
runs/workers/task systems) — PGO changes layout/inlining, never
arithmetic. README notes the C-reference fairness caveat.

Also documented as tried-and-dropped (noise-floor in paired A/B, per
the keep-only-measurable-wins rule): cache-line padding of stage-sync
atomics, narrow velocity-only scatter writes, compound child Arc clone
(already eliminated by the earlier scratch fix).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 15:37:51 +02:00
Admin
79b5e2925b box3d: README — add C box3d column to the rapier comparison table
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 15:17:23 +02:00
Admin
56b1df8435 box3d: README — drop rapier-without-simd references (not a realistic comparison)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 15:16:48 +02:00
Admin
f934256b84 box3d: perf round 3 — many_pyramids 1.28x -> 1.06x vs C, now within 5% of rapier-simd
Disassembly-driven (fork agents confirmed the stalls, killed the
bounds-check and recycle-rate hypotheses with instruction-level and
runtime-counter evidence — recycle counts are bit-identical to C):

- Manifolds inline-when-single store: Contact.manifolds Vec<Manifold> ->
  enum { None, One(Manifold), Many(Vec) } with deref-as-slice. Convex
  contacts keep their manifold inline (the Rust equivalent of C's block-
  allocator arena locality — the per-contact heap chase was the main
  stall in collide/prepare/store). Contact is #[repr(C)] with manifolds
  last so hot header fields stay on the leading cache lines. Public
  ContactData API unchanged via Deref; contact_solver.rs needed zero
  changes. Pure storage change: determinism hash identical (0x61E35C31).
- #[inline(never)] on update_contact + the four convex stage functions:
  C compiles these standalone; LLVM had inlined all of them into one
  13.6 KB execute_block paying constant register-spill traffic.

Definitive cold-machine matrix: serial geomean 1.15x -> 1.12x vs C
(many_pyramids 2071 vs 1949 ms, large_pyramid 1501 vs 1392); 8-worker
geomean 1.35x -> 1.30x. vs rapier-simd (adjacent runs): box3d ahead 16%
on large_pyramid and 3% on joint_grid, behind 5% on many_pyramids (was
21%). README grids updated.

179/185/179 tests green, zero warnings, hash unchanged across workers/
arch/task systems.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 15:14:52 +02:00
Admin
2a0b1e803d rapier: restore simd-stable (vendor wide + safe_arch), retest vs box3d
Re-vendors wide 0.7 + safe_arch, restores the upstream simd-stable
wiring in rapier3d/parry3d manifests and the cfg-simd source, and drops
the added 'stripped build does not support SIMD' guards (upstream's
simd-vs-enhanced-determinism exclusivity guard kept).

Interleaved single-thread retest (min of 4): SIMD buys rapier 1.8-2.2x;
box3d vs rapier-simd is now near parity — large_pyramid 1579 vs 1638 ms,
joint_grid 957 vs 1008 ms (box3d ahead), many_pyramids 2389 vs 1970 ms
(rapier ahead). box3d README grid updated with the honest three-column
table; box3d keeps cross-arch determinism + zero deps at that speed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 14:17:26 +02:00
Admin
5457e55c4b box3d: rapier comparison — ~2x faster single-threaded, bench in libs/rapier/crates/bench
Same scenes/geometry/materials/dt, matched solver budget (4 substeps vs
4 solver iterations), interleaved min-of-4 runs: large_pyramid 2.23x,
many_pyramids 1.82x, joint_grid 1.88x (geomean ~1.97x). Table + fairness
notes at the top of the box3d README (vendored rapier has no SIMD;
enhanced-determinism measured free on these scenes).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 13:54:05 +02:00
Admin
e3a8b51b07 box3d: perf round 2 — 8-worker geomean 1.47x -> 1.35x vs C, serial 1.15x
- joint prepare: read BodySim through references (was deref-copying
  220 bytes twice per joint per step; prepare_joint now at C parity)
- FMA contraction extended to joint solvers (32 sites; hash re-baselined
  to 0x61E35C31, still bit-identical across workers/arch/task systems)
- scheduler: workers spin ~tens of us before committing to a kernel
  sleep (semaphore try_acquire spin phase; A/B: large_world w=8
  24 -> 11.5 ms, joint_grid w=8 1.58x -> 1.49x, other scenes neutral;
  intentional deviation from C documented in README)
- tried and reverted: chunks_exact twin-pair edge SAT (won 5% on
  junkyard compounds, cost box-box scenes 4-8%; keeps C 1:1 loop shape)
- README: fresh benchmark matrix, second-round notes, stale external
  task-hook claim fixed

179/185/179 tests green, zero warnings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 11:09:25 +02:00
Admin
1904e5bd89 box3d: performance pass — serial geomean 1.30x -> 1.13x vs C, 8-worker 1.6x -> 1.47x
Profiling-driven (sample + disasm comparison vs clang -O3). All changes
safe Rust except one debug_assert-guarded extension of the existing
SyncSlice unsafe contract. Determinism preserved: hash bit-identical
across workers 1/2/4, NEON/SSE2/scalar, internal/external task systems
(new baseline 0x9018E2D8 after approved FMA contraction).

- f32/f64::mul_add contraction in hot scalar math (= C's -ffp-contract=on;
  89 sites; wide SIMD ops untouched like C intrinsics). large_pyramid
  now at parity with C (1387 vs 1373 ms serial)
- FloatW::get/set: direct lane load/store instead of vector-through-stack
  round trip; layout asserted at compile time
- gather_bodies by reference (removes 20-register spill storm)
- per-worker capacity-preserving scratch for convex + mesh collide paths
  (C-arena equivalent; mesh path allocated per triangle and serialized
  the parallel collide pass on allocator locks)
- update_contact: borrow shapes instead of cloning (deep compound
  geometry clones + cross-worker Arc traffic; junkyard w=8 -39%)
- scheduler semaphore: two-level atomic fast path (C uses
  dispatch_semaphore_t; old Mutex+Condvar locked every enqueue)
- SyncSlice::get_ref/get_mut unchecked indexing under the existing
  unsafe contract, debug_assert-guarded (-6% serial)
- README/PORTING: new numbers, FMA sync conventions, known remainders

179/185/179 tests green (default/double-precision/disable-simd), zero
warnings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 09:10:44 +02:00
Admin
2f792a5a19 box3d: recording replay player + test_recording port
Full op-stream player in recording_replay.rs (b3RecPlayer port):
opcode dispatch for ~150 ops, StateHash verification at every step
marker, query replay with bitwise comparison, keyframe ring with
budget-driven interval doubling, seek/restart/scrub, validate_replay.

tests/test_recording.rs ports test_recording.c (17 tests incl.
record-at-4-workers/replay-at-1-and-4 hash equality). 179/185/179
tests green across default/double-precision/disable-simd, zero
warnings, determinism hash unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 16:06:18 +02:00
Admin
bcbf0c815c box3d: recording op stream (capture side)
All ~140 opcodes from recording_ops.inl with exact C values, capture hooks
in every mutator and query (~137 sites across body/shape/joint/world),
48-byte header with registry locator backpatch, snapshot seed, query tag
interning, state-hash anchors per step. Recording is observer-only
(bit-identical world state with and without a recording attached).
Replay/player side lands separately.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 16:06:18 +02:00
Admin
0878f5fe2f box3d: external task-system hooks + makepad 3D example
- WorldDef enqueue_task/finish_task/user_task_context (C contract incl.
  null-return-means-inline); TaskSystem dispatch (Serial/Internal/External)
  replaces the bare scheduler; determinism hash bit-identical through an
  external thread-per-task system.
- examples/box3d: makepad app rendering the live simulation (offscreen 3D
  pass with depth, orbit/zoom camera, instanced lit boxes/spheres, 204-box
  pyramid + spheres, 4-worker solver, Space to reset).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 16:06:18 +02:00
Admin
f5a9fb45a0 box3d: multithreading — scheduler, parallel_for, atomic solver stages
Port of the C threading design: worker threads with a fixed task ring and
help-while-waiting finish (scheduler.rs), atomic block-claiming parallel_for,
and the solver's stage machinery (per-block syncIndex CAS, sync-bits stage
advancement, mainClaimed race). Parallel narrow phase, broad-phase pairs,
sensors, finalize. Shared access goes through documented disjointness
primitives (sync.rs: SyncPtr/SyncSlice/AtomicIndex); worker_count 1 keeps the
serial path bit-identically. Results are bit-identical at any worker count
(determinism hash 0x7A796F4F asserted at 1/2/4 workers). 8 workers: 3.4-5.7x
over serial on heavy scenes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 16:06:18 +02:00
Admin
cd0c151111 box3d: reuse per-step solver and broad-phase scratch allocations
Persist solver constraint arrays/spans/stage blocks and broad-phase pair
query buffers across steps instead of reallocating each world_step.
Bit-identical results (determinism hash unchanged); washer -7.6%, small
wins on trees/rain, pairs stage -6% on junkyard. A contact-manifold
reuse attempt regressed pyramid scenes and was dropped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 16:06:18 +02:00
Admin
1193ab7bbd box3d: SIMD (SSE2/NEON), double-precision large world, snapshots, benchmarks
- contact solver wide ops + V32 now have real SSE2 and NEON paths selected
  by target arch; scalar fallback behind the disable-simd feature. All three
  paths are bit-identical (cross-arch determinism verified: same ragdoll
  hash on NEON, SSE2 under Rosetta, and scalar).
- double-precision feature (C BOX3D_DOUBLE_PRECISION): f64 world positions
  with the exact C boundary-function semantics; enables the far-from-origin
  test halves (157 tests in DP mode, 151 default).
- world snapshots: recording substrate subset (buffer/writers/geometry
  registry/readers) + world_snapshot.c port; bit-identical continuation
  after restore, corrupt-image rejection.
- examples/benchmark.rs: all 10 C benchmark scenarios; serial Rust runs
  1.05-1.55x slower than C -O2 at one worker (geomean ~1.3x with fat LTO).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 16:06:18 +02:00
Admin
c01706e6fd box3d: pure Rust port of Box3D (erincatto/box3d @ 29bf523)
Full engine port in libs/box3d: math, geometry, GJK/TOI, hull builder,
dynamic tree, manifolds, constraint graph, solver (serial, scalar SIMD
path), all 8 joint types, sensors, mover, world API. 147 ported C unit
tests green in debug and release. See libs/box3d/README.md for the
upstream revision and sync notes, PORTING.md for conventions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 16:06:18 +02:00
Kevin Boos
61fd059786 View: add fn for toggling optimize and force texture caching (#1136)
* TextInput: expose the location of the caret/cursor

in absolute window-relative coordinates.

THis allows, for ex, a widget to be placed relative to the
current location of the text being inputted by the user.

* View: add fn for toggling `optimize` and force texture caching

Add CachedView fns that make it easier to control its parameters:
* set_optimize(cx, ViewOptimize): switch optimize mode at runtime and
  allocate the draw_list on demand. Previously `optimize` was set once from
  `texture_caching` and never reset, so a view couldn't toggle between direct
  and texture-cached rendering per frame.
* set_texture_max_height(Option<f64>): cap the Texture-mode render turtle's
  height so a tall Fit-height cached view can't allocate a render target past
  the GPU's max texture size (was a hard MTLTextureDescriptor abort once
  content exceeded 16384px). None (default) leaves it uncapped; content past
  the cap is clipped. Only affects Texture mode.
* redraw_texture_cache() / force_texture_redraw: force one offscreen
  re-render after a content repopulate or an optimize-mode flip. The
  rect-based will_redraw check can't see a content change on a recycled or
  toggled view, so without this it would composite a stale texture.
* view_size is now updated in every optimize mode, not just draw-list modes.
  The None (direct-render) path previously left it stale, so a view toggled
  None<->Texture sized its next offscreen turtle from an old height and
  clipped/mis-positioned its content.
2026-07-02 08:34:19 +02:00
Kevin Boos
ca684774f7 TextInput: expose the location of the caret/cursor (#1132)
in absolute window-relative coordinates.

THis allows, for ex, a widget to be placed relative to the
current location of the text being inputted by the user.
2026-07-02 08:34:04 +02:00
Admin
ef0514a9aa hypothetical heap access fix 2026-07-01 14:04:23 +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
Admin
daacb601d9 history 2026-06-26 16:47:13 +02:00
Admin
80a7992294 animating buttons 2026-06-26 16:46:24 +02:00
Admin
68118217b6 animating bg 2026-06-26 15:49:25 +02:00
Admin
82fbe1aa46 animating bg 2026-06-26 15:34:54 +02:00
Admin
c855d14409 glass style 2026-06-26 14:06:57 +02:00
Admin
29932cb008 parse {}{} as {},{} 2026-06-26 13:37:17 +02:00
Admin
1a0dfec58e glass centering 2026-06-26 13:07:21 +02:00
Admin
a61ec8eca3 cargo 2026-06-26 10:29:06 +02:00
Admin
56cf3bc2e6 aichat 2026-06-25 18:52:10 +02:00
Admin
4966882eee aichat: track glass splash.md doc & fix runtime path
- Rename splash2.md -> splash.md so the tracked doc matches what aichat
  references via include_str!/read_to_string (a clean clone now builds).
- Fix the live-read path (CARGO_MANIFEST_DIR was ../../../ = one dir above
  the repo, loading a stale doc); now ../../splash.md -> repo-root glass doc.
- Full repaint (cx.redraw_all) on Clear/remove so self-managed glass overlay
  draw lists aren't left composited stale.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 16:41:49 +02:00
Admin
62863b343f splash: replace splash2.md with updated Splash DSL guide
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 16:13:11 +02:00
Admin
0af21f2737 aichat 2026-06-25 16:11:42 +02:00
Admin
6ab335fd80 aichat otw 2026-06-25 16:11:42 +02:00
Admin
ae7853338e glass kit more 2026-06-25 16:11:42 +02:00
Admin
3848a1ab29 glass kit more 2026-06-25 16:11:42 +02:00
Admin
57595b1b40 gloop glass radio 2026-06-25 16:11:42 +02:00
Admin
434aa59e7c gloop glass radio 2026-06-25 16:11:42 +02:00
Admin
bafb396921 gloop glass radio 2026-06-25 16:11:42 +02:00
Admin
612996c038 Add glass_panel widget example; restore rustfmt guard
- New GlassPanel widget (widgets/src/glass_panel.rs) + lib export
- gauss_view: honor surface_alpha for translucent glass surfaces
- examples/glass: standalone demo (wired into Cargo workspace + makepad.splash)
- rustfmt.toml: re-enable disable_all_formatting to stop rustfmt from
  reformatting the whole tree on save

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 16:11:42 +02:00
Kevin Boos
e444804344 parse and use orientation info for all supported image formats (#1130) 2026-06-23 09:08:45 +02:00
Kevin Boos
a3a5cad05b code editor: support proper Fit size bound with max height value (#1128) 2026-06-22 19:54:30 +02:00