Skip to content

Existing Rust GUI apps on ToyOS: iced on one winit backend, paced redraws, forks on one branch per base - #528

Merged
Japabu merged 28 commits into
mainfrom
wt/toyos-guiplat
Sep 26, 2026
Merged

Japabu merged 28 commits into
mainfrom
wt/toyos-guiplat

Conversation

@Japabu

@Japabu Japabu commented Sep 26, 2026 •

Copy link
Copy Markdown
Collaborator

Stage 1 of issues/design-debt/toyos-has-a-desktop.md, the platform, under the owner's ruling of 2026-09-26 that the platform carries iced only, for now. An unmodified iced app opens a window under the real compositor, draws its text in a system font, presents only what it has to, and leaves with code 0 when the compositor closes it. snake, calc and doom move to the same winit backend.

What changed, per decision

iced only. The slint and egui test apps, the slint and parley/fontique forks, and their 16 [patch] rows are gone. issues/design-debt/slint-and-egui-are-not-supported-by-the-owners-choice.md records the choice, with the exit "revisit once the Rust target is upstream". The ruling says "for now", so it is a deferral: the entry is kind: defect, status: open, as issues/README.md rules for a deferral. This also settles the review's slint-default-features BLOCKER, since slint is not supported.

One ToyOS winit backend. snake, calc and doom are ported to winit 0.30:

  • can_create_surfaces becomes resumed, and SurfaceResized becomes Resized.
  • calc's pointer events become CursorMoved/CursorLeft/MouseInput, with the position kept from the last move.

The tree pins only ToyOSOrg/winit toyos-0.30.13. Nothing pins the 0.31 line any more (winit-toyos, +1249 over its tag as main pins it).

On that backend (winit toyos-0.30.13 at f58e1f3b, +1246/−1 over v0.30.13):

  • Redraws are paced, Wayland's way. A redraw asked for after pre_present_notify is held until the window's next frame event. One asked without it goes at once. iced calls pre_present_notify before every present, so RedrawRequest::NextFrame and any animation run at the compositor's rate.
  • A frame event is not a redraw (the previous head's fix, kept).
  • A window dropped before the loop takes it never becomes live. Window::drop takes the window out of the loop's creation queue. Take a window created and dropped in a handler that runs after the loop's creation step, a Destroyed handler for example. Its compositor window now closes at the drop, and it hears only its Destroyed. Before, it got Resized and RedrawRequested after its Destroyed, and its compositor window stayed open until the app left.
  • A window dropped while its own events are polled hears none of the rest. The loop stops polling a dropped window and sends nothing more for it. A Resized queues its redraw before the handler runs, so a drop inside the handler forgets that redraw too.
  • Wakes only from other threads. A window can only be created from a handler, on the loop's thread, where the loop finds it before it waits, so creation raises no wake. A redraw or a drop raises one only off the loop's thread. EventLoopProxy::send_event always wakes.

The wake pipe is the SDK's.

  • toyos::wake (Waker, Bell) sits beside Poller.
  • window::Waiter holds a Bell and hands out Arc<Waker>.
  • logd's bell and soundd's line-writer wake are swapped onto it.
  • mio's waker could not take it as a swap: nothing in mio's ToyOS selector reads its pipe, and draining is the selector's step to add (filed).

SDK versions, after #525. #525 took toyos-abi 0.13.0, toyos 0.14.0 and toyos-window 0.15.0. The last two were this branch's versions. This branch merged origin/main and moved on:

Every tracked lockfile is re-locked on the merged manifests. tests/iced-counter is among them.

The compositor counts. Each window's close line gives its MSG_PRESENTs and the MSG_FRAMEs sent back (… presents=P frames=F). The tests below judge by that line.

Forks: one branch per upstream base, SDK crates by range.

  • A fix or repin is a commit appended to the base's branch, never a new branch.
  • Every fork names toyos-abi, toyos and toyos-window as >=<first version whose API it uses>, <1.
  • [patch.crates-io]'s path answers that range at whatever version the tree is on. Measured: a patch at 0.11.0 is chosen over the registry's 0.12.0 for >=0.10, <1.
  • The bump to 0.15/0.16 above therefore needed no fork commit.

sdkversion::judge (the abi-split lane and --pr) refuses any tracked lockfile holding two versions of a PUBLISHED crate.

On the merge:

getrandom 0.2/0.3 and libloading keep their -sdk-0.12 branch beside the base branch. rust/Cargo.lock pins the base branch one commit back, and fast-forwarding it would put the toolchain behind in --check-forks (filed, with the exit).

memmap2 (toyos-0.9.11): make_exec answers Unsupported, as map_exec does. The fix is not on the toyos branch the toolchain pins:

  • appending it there alone leaves rust/Cargo.lock (87ae85a1) one commit behind, which --check-forks reports;
  • re-locking rust/Cargo.lock changes the compiler's own dependency graph.

Filed as issues/build/the-toolchains-memmap2-branch-answers-ok-from-make-exec.md. Nothing in the toolchain calls make_exec, and rustc_data_structures gates ToyOS away from memmap2.

wgpu (toyos-27.0.4, +10/−3): the native Vulkan/GL platform set is one alias, and vulkan, gles and target_has_backend are written in terms of it. The prepared upstream branch does the same for trunk's three sets (Vulkan, DRM, GL).

The OFL ships. assets/fonts/OFL.txt moved from licenses/ with the same digest and has its own COMMITTED_FILES row. It ships beside the fonts as /system/share/fonts/ofl.txt, and NOTICE says so instead of claiming the name table is the licence.

One scratch helper. a_system_font_ships_as_it_is_and_the_console_font_as_its_raster takes a toyos_tmpdir::TempDir. sourcegate::every_host_scratch_is_the_guard refuses temp_dir() in host code outside three counted exceptions:

  • the guard itself;
  • the keymap golden's dump, left for its reader on purpose;
  • src/release.rs, filed.

iced's app is a package of its own. tests/iced-counter holds upstream's examples/counter/src/main.rs byte for byte, as src/bin/iced-counter.rs, with its own lock and patches. toolkit_iced builds it and carries it into the toolkit desktop.

  • No image and no userland/ resolve pays for iced's tree. userland no longer patches wgpu, fontdb or memmap2.
  • The iced_test dev-dependency is gone, so upstream's it_counts is never built.

Tests

The four toolkit_ tests are Nightly, in tests/toolkitcase.

toolkit_iced

  • The window opens.
  • Both labels are found at two disjoint places on the panel. Each word is rendered here by fontdue from assets/fonts/OpenSans-Regular.ttf at 16 px and matched by normalised cross-correlation. The label that matches best claims its place, and the other is matched only away from that place. Each needs ≥ 0.6.
  • The window presents at most once while nothing happens to it.
  • GUI+Q closes that client, and the app exits 0.
  • It now launches through toolkit_launch, which takes the line to type.

toolkit_winit_pace: an animation draws 60 frames (pre_present_notify, present, then request_redraw inside RedrawRequested). The compositor must count all 60 presents, and no more than frames + 1.

toolkit_winit_loop runs through winit's API. The app fails on any event delivered for a window after the app dropped it, other than its one Destroyed. The stages:

  1. A user event is sent from AboutToWait with no window open.
  2. 100 events come from another thread, each sent only after the previous one was delivered.
  3. 20 windows are each asked for a redraw and then dropped on another thread as the loop goes to wait.
  4. A window is created, asked for a redraw and dropped in stage 3's last Destroyed handler. The stage ends at the second AboutToWait after its Destroyed; the iteration in between is forced by ControlFlow::Poll.
  5. A window is asked for a redraw and dropped in a user_event.
  6. A window whose close the app ignores wakes the idle loop at most once in 1 s: the deadline's iteration.

The harness then reads the compositor's close lines up to the kept window's GUI+Q close. Every window the app dropped (22) has to be closed "by the client itself" before that line.

toolkit_window_wake

  • Four windows, past a new waiter's room, so the poller must grow.
  • 200 rounds, alternating between a wake already pending when the wait starts and one raised after the wait is told to begin.
  • Then one wait after more wakes than the pipe holds. The capacity is measured on a fresh pipe: 2 097 088 bytes, so the flood is 2 097 089 wakes, raised in 7.5–8.8 s. The wait must end, one take must take it all, and a second take must find nothing.

Also:

  • memmap_exec_refused (shared boot);
  • assets::tests::the_system_fonts_ship_with_their_licence;
  • sdkversion's a_lockfile_holding_two_versions_of_a_published_crate_is_refused_by_name;
  • sourcegate::every_host_scratch_is_the_guard.

Negative controls

Each one is a checked patch, shown to build, run, and reverted, and the tree is clean after each. Winit mutations are commits on scratch branches of a local clone, consumed as file:// git sources. The head arm of each is the same clone at f58e1f3b, the commit pushed, and it is EXIT=0.

Round 3, at this branch's heads 2d0739e…254ea746:

review finding mutation run result
zombie window (BLOCKER 1) Window::drop leaves creates alone (the fix's one line deleted) --nightly toolkit_winit_loop EXIT=1: "WINIT-LOOP-FAIL Resized(PhysicalSize { width: 200, height: 120 }) after Destroyed", wide and alone
(same, harness oracle) the same, and the app's dropped-window check disabled --nightly toolkit_winit_loop EXIT=1: "window 20 … of the 22 the winit loop dropped was not closed by its drop before the kept one was closed, but by None", wide and alone
surviving forget (BLOCKER 2) self.redraws.lock().unwrap().forget(self.id); deleted from Window::drop --nightly toolkit_winit_loop EXIT=1: stage 4 passes, then "WINIT-LOOP-FAIL RedrawRequested for a window its application already dropped", wide and alone
second temp-dir helper (BLOCKER 3) src/assets.rs's fix reverted to std::env::temp_dir() cargo test --lib every_host_scratch_is_the_guard … EXIT=101: left: {"src/assets.rs": 1, …}
wake's WouldBlock Err(SyscallError::WouldBlock) dropped from Waker::wake's Ok arm --nightly toolkit_window_wake EXIT=1: panic at toyos/src/wake.rs:32, wide and alone
two labels, one place iced-counter's view is column![button("Decrement")…] only --nightly toolkit_iced EXIT=1: "Increment" 0.349 away from "Decrement" (0.866), under 0.6, wide and alone

Without the disjoint rule, "Increment"'s best place at head was on "Decrement": 0.787 at (486, 279) against "Decrement"'s 0.866 at (479, 279). Away from it, on its own button, "Increment" scores 0.781.

The unexplained idle wake, measured. I instrumented window::Waiter to name each completion's handle and ran the test with IDLE_WAKES = 1:

  • On the zombie arm, the spurious WaitCancelled straight after the close came in 2 of 6 runs. In each, the wait watched only the leaked stage-4 window, and the completion was that window's. It was not a leftover registration.
  • At head, 10 instrumented runs plus 3 plain ones saw no second iteration.

So IDLE_WAKES is now 1, and the allowance is gone.

Rounds 1–2, measured at 42059f5 or earlier and not re-run:

review finding mutation run result
frame-event fix untested Event::Frame => { r.frame(id); r.request(id); } (a frame event redraws) --nightly toolkit_iced EXIT=1: "presented 49 times (49 frame events back)"; alone 74
redraws unpaced pre_present_notify does nothing --nightly toolkit_winit_pace EXIT=1: "60 presents against 16 frame events", alone the same
proxy wake, A take_wake() moved after AboutToWait --nightly toolkit_winit_loop EXIT=1: "LOST: … the user event sent from AboutToWait", wide and alone
proxy wake, B the off-thread wake in Window::drop deleted --nightly toolkit_winit_loop EXIT=1: "LOST: … round 0's window dropped on the helper", wide and alone
(same, redraw) the off-thread wake in request_redraw deleted --nightly toolkit_winit_loop EXIT=1: "LOST: … round 0's redraw asked from the helper"
closed-window filter .filter(|live| !live.closed) deleted --nightly toolkit_winit_loop EXIT=1: "woke the loop 16647 times in 1s"; alone 6871
waiter growth the growth block replaced by let _ = watched; --nightly toolkit_window_wake EXIT=1: Poller: … capacity is 4 panic at poller.rs:269
memmap2 make_exec make_exec → Ok(()) -- memmap_exec_refused EXIT=1: "make_exec answered Ok on a heap buffer"
OFL not shipped add_dir skips .txt cargo test --lib the_system_fonts_ship_with_their_licence EXIT=101
lockfile gate getrandom 0.4 pinned at e05f79d (names toyos-abi = "0.1") --ci abi-split EXIT=1: "userland/Cargo.lock holds toyos-abi at 0.1.0 and 0.12.0"
text check: no fonts src/assets.rs: let system_font = false; --nightly toolkit_iced EXIT=1: "Increment" 0.349, under 0.6
text check: gradient the view replaced by a full-window linear gradient --nightly toolkit_iced EXIT=1: 0.156, under 0.6

Independent oracles:

  • the compositor's own present/frame counts and close lines, and QEMU's screendump, rather than anything the app or winit reports;
  • the labels, judged against a second rasteriser (fontdue) reading the committed font file;
  • the pacing rule, which is Wayland's frame-callback model as winit's own pre_present_notify documentation describes it.

Gates (exit codes), at 254ea74 (merged with origin/main at 7345e3f, #525)

  • cargo run -- --ci host → EXIT=0, "Host: 43 step(s), all green", including "nothing left in $TMPDIR".
  • cargo run -- --ci abi-split → EXIT=0, "bumped: toyos 0.14.0 -> 0.15.0, toyos-window 0.15.0 -> 0.16.0".
  • cargo run -- --check-forks → EXIT=0, "23 branches asked, all current".
  • cargo test --test toyos-build -- --nightly toolkit_ → EXIT=0, 4 of 4.
  • snake: -- --nightly desktop_window_child → EXIT=0. It PASSes, quarantined and green.
  • doom: -- --nightly doom_ → EXIT=0. doom_music PASSes; doom_sound_flood PASSes, quarantined and green.
  • the fast tier, cargo test --test toyos-build → EXIT=1: 395 passed, 4 failed. Each is settled below.

The fast tier was run twice on the head and once on main, in the same session.

Head, first run. EXIT=1: 395 passed, 4 failed.

  • lan_mdns_answer fails on "path must be shorter than SUN_LEN", wide and alone. That is main's defect, filed.
  • handle_kill_policy and handle_transfer fail on a SharedMem census one over. Both are ALONE GREEN.
  • partition_claim_gives_up fails twice, on two different assertions.

Head, second run. EXIT=1: 395 passed, 4 failed.

  • lan_mdns_answer, the same as above.
  • partition_claim_departure, quiesce_wakes_on_the_last_park and metal_job_reboot fail. Each is ALONE GREEN.

main (7345e3f), full fast tier. EXIT=1: 397 passed, 1 failed. The failure is lan_mdns_answer, with the same message.

Each of the four first-run reds, alone, on both sides.

  • On the head: partition_claim_gives_up EXIT=0, handle_kill_policy EXIT=0, handle_transfer EXIT=0, lan_mdns_answer EXIT=1.
  • On main: the same four exits, in the same order.

--known-red: NO for every one of these except handle_transfer, whose row does not cover the census message.

The wide-only reds are filed as beside-other-guests defects:

  • issues/boot-media/partition-claim-gives-up-reds-beside-other-guests-and-is-green-alone.md
  • issues/boot-media/partition-claim-departure-told-no-flush-beside-other-guests.md
  • issues/build/quiesce-wakes-on-the-last-park-lost-its-serial-ready-beside-other-guests.md
  • issues/build/metal-job-reboot-drained-no-kernel-output-beside-other-guests.md

handle_kill_policy's and handle_transfer's census reds are the class issues/kernel/deferred-release-outlives-its-syscall.md names, which cites handle_kill_policy.

What I cannot rule out. Two wide head runs had three non-lan reds each, a different three each time. The one wide main run had none. That is a difference between the two sides, and I have not shown it to be noise. Nothing in this diff touches shared memory, block storage or the quiesce path. The runtime code every boot runs that this branch changes is logd's wake, now toyos::wake, and soundd's.

What I am unsure of

  • The label bar (0.6) sits between 0.349 (no fonts, or no second word) and 0.781 (text), measured on this host's QEMU. A different iced theme or text size would move both.
  • The wake flood prints nothing for its 7.5–8.8 s here, against toolkit_window_wake's 30 s quiet bound (which the harness scales by host speed). A much slower host could meet that bound first; I have not measured one.
  • pump_events with a finite timeout is compiled but not exercised: every client here enters through run.
  • The compositor once reported the animation's client as "its connection is gone", rather than closed by the client, when the app dropped its window and exited at once. The pace test now closes with GUI+Q. I have not investigated this.
  • [profile.toyos] is not shared. Cargo reads a profile only from a workspace root or from a config, so sharing it means moving every copy (root, kernel, bootloader, userland, toyos-rust-tests and its four TLS crates, iced-counter) into one --config that src/build.rs passes. That is a build-system change past this brief.

Filed

  • issues/build/the-release-path-stages-in-tmpdir-outside-the-scratch-guard.md (tooling)
  • issues/build/the-toolchains-memmap2-branch-answers-ok-from-make-exec.md (defect)
  • issues/design-debt/slint-and-egui-are-not-supported-by-the-owners-choice.md (defect: the deferral)
  • issues/build/the-toolchain-pins-an-older-commit-of-three-userland-forks.md (tooling)
  • issues/design-debt/mio-s-toyos-waker-never-drains-its-pipe.md (finding)
  • issues/design-debt/toyos-ships-no-monospace-or-serif-system-font.md (finding)
  • issues/build/a-lane-s-tap-socket-path-outgrows-sun-len-on-the-dev-host.md (defect, main's: the fast tier's lan_mdns_answer red)
  • Updated:
    • issues/build/metal-job-reboot-drained-no-kernel-output-beside-other-guests.md
    • issues/design-debt/softbuffer-reads-a-toyos-window-behind-its-lock.md
    • the desktop track (iced only)
  • Closed:
    • issues/build/fork-tier-crates-still-pin-toyos-abi-at-0.1.md
    • issues/build/an-sdk-bump-leaves-every-fork-on-the-last-sdk.md
    • issues/design-debt/a-toyos-winit-window-redraws-unpaced.md
    • the slint/eframe defects

Fork branches (consumed)

fork branch head compare
winit toyos-0.30.13 f58e1f3b rust-windowing/winit@v0.30.13...ToyOSOrg:winit:toyos-0.30.13
softbuffer toyos-0.4.8 b36854df rust-windowing/softbuffer@v0.4.8...ToyOSOrg:softbuffer:toyos-0.4.8
wgpu toyos-27.0.4 e8a91805 gfx-rs/wgpu@v27.0.4...ToyOSOrg:wgpu:toyos-27.0.4
fontdb toyos-0.23.0 2e445cf5 RazrFalcon/fontdb@v0.23.0...ToyOSOrg:fontdb:toyos-0.23.0
memmap2 toyos-0.9.11 ad0d8905 RazrFalcon/memmap2-rs@v0.9.11...ToyOSOrg:memmap2-rs:toyos-0.9.11
cpal toyos-0.18.0 7e9775d5 RustAudio/cpal@v0.18.0...ToyOSOrg:cpal:toyos-0.18.0
getrandom toyos-0.2-sdk-0.12, toyos-0.3-sdk-0.12, toyos-0.4 2092d1cc, 67c17e0a, f0286c8b ToyOSOrg/getrandom@toyos-0.2...toyos-0.2-sdk-0.12 · …/compare/toyos-0.3...toyos-0.3-sdk-0.12 · rust-random/getrandom@v0.4.2...ToyOSOrg:getrandom:toyos-0.4
mio toyos 271eb006 ToyOSOrg/mio@c84d7e3...toyos
socket2 toyos 2b67e7bd ToyOSOrg/socket2@19eb798...toyos
libloading toyos-sdk-0.12 bad8d494 ToyOSOrg/rust_libloading@toyos...toyos-sdk-0.12

Nothing consumes the per-SDK branches the previous heads minted:

  • winit toyos-0.30.13-sdk-0.15;
  • softbuffer toyos-0.4.8-sdk-0.15;
  • cpal toyos-0.18.0-sdk-0.13;
  • getrandom toyos-0.4-sdk-0.12;
  • mio and socket2 toyos-sdk-0.13.

The owner can delete them. main's -sdk-0.2 branches stay until #530 has merged.

Prepared upstream branches (none opened)

upstream branch standing
fontdb add-toyos-system-fonts (+7) on hold until the owner decides where fonts and other resources live: it names /system/share/fonts.
wgpu instance-no-backend-target (+14/−4 on trunk) upstreamable: it names no ToyOS.
winit, softbuffer — blocked on rust-windowing/raw-window-handle#223.
memmap2 — not prepared (forks.toml).

Net lines (git diff --shortstat origin/main...HEAD)

56 files, +7681/−642. About +540/−95 of that is production and manifests, +1330/−3 tests, +5489/−481 lockfiles, and +322/−63 records.

🤖 Generated with Claude Code

https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK

Japabu and others added 6 commits September 26, 2026 14:16
Work in progress on the branch; the pull request body is the record.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
The committed-files table moved to src/licence.rs with a licence column; the
four Open Sans rows follow it as Terms::Font("OFL-1.1"), and each new NOTICE
section carries its SPDX line.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
@Japabu
Japabu marked this pull request as ready for review September 26, 2026 13:27
@Japabu

Japabu commented Sep 26, 2026

Copy link
Copy Markdown
Collaborator Author

Review of #528 at 4ad645a

Ready for review: abi-split is SUCCESS at 4ad645a (run 36245184698). host is SKIPPED, which ci.yml does on purpose for a pull request. The added nightly tests are EXIT=0 in the body. Nothing here targets hardware.

Net lines (git diff --shortstat origin/main...HEAD): 37 files, +7865/−1885.

  • Production in the tree: about +206/−13. That is wait.rs +157, compositor +16/−2, userland/Cargo.toml +32/−9, src/assets.rs about +6/−2 and toyos-window +5/−1.
  • Tests: about +540.
  • Lockfiles: +6751/−1834.
  • Fork production: about +1.5k net, of which +1145 is a second winit backend.

Fork heads were checked against the body: winit 6767a595/d857ac16, softbuffer 41ad75f, fontdb 2e445cf, memmap2 eb6cce2, wgpu 6aafc3a9, the repins as listed, fontique and slint through gh api …/compare.

BLOCKER

  • winit toyos-0.30.13-sdk-0.15 event_loop.rs:340, and winit-toyos/src/event_loop.rs:501 on 0.31. The headline fix has no test that fails when it is reverted.
    • Surviving patch: toyos_window::Event::Frame => queue_redraw(redraws, self.id),. With it, toolkit_iced, toolkit_slint and toolkit_egui all stay green, because tests/toyos.rs:8838 prints the CPU and asserts nothing about it.
    • Required: assert a count that does not depend on load. For example, the compositor reports presents per client on its close line, and an idle window must stay under a small bound. The patch above must turn toolkit_iced red.
  • winit 0.30 window.rs:93 (pre_present_notify does nothing) and event_loop.rs:340. Redraws are now unpaced. The branch removed the only thing that paced them and put nothing in its place.
    • An app that calls request_redraw from RedrawRequested now spins at CPU speed and floods the compositor. That covers iced RedrawRequest::NextFrame, egui continuous repaint and any animation. Before this branch such apps were held to the compositor's frame rate.
    • issues/design-debt/a-toyos-winit-window-redraws-unpaced.md is a "finding" with no measurement and no exit condition.
    • Required: hold a redraw requested after pre_present_notify until that window's next Frame, which is Wayland's model and the hook the issue itself names, in both branches. Add a guest test with an app that animates, and bound its presents against the compositor's frames.
  • winit 0.30 event_loop.rs:499, 0.31 event_loop.rs:532, and 0.30 window.rs:39/window.rs:310, 0.31 window.rs:57/window.rs:329. No test exercises EventLoopProxy or a wake from another thread through winit. This is stage 1's fourth deliverable. toolkit_window_wake tests toyos-window only.
    • Surviving patch A: move self.waiter.take_wake(); from event_loop.rs:499 to after callback(event::Event::AboutToWait, target); at :561. On 0.31, move it from :532 to after app.about_to_wait at :585. A send_event or wake_up raised in AboutToWait is then eaten and the loop sleeps with a user event queued.
    • Surviving patch B: delete el.waker.wake(); in Window::new and self.waker.wake(); in Drop. A window created or dropped off the loop's thread is then never seen.
    • Required: a guest winit app that (1) sends a user event from AboutToWait and exits on receiving it, and (2) has a helper thread send N events, each needing its own delivery under a ceiling. A turns (1) red, and B needs its own arm with a window created from the helper thread.
  • winit 0.30 event_loop.rs:529, 0.31 event_loop.rs:555. RedrawRequested is delivered for a window after its Destroyed. A window that is created and dropped in one handler, or redrawn and then dropped, leaves its id in redraws: the create path queues one at :547, and request_redraw queues one. No other backend does this. An app that indexes its windows by id panics.
    • Fix: purge the id from redraws in the destroy loop, with a guest case that does create, request_redraw, drop and must see no RedrawRequested after Destroyed.
  • userland/toyos-window/src/wait.rs:108. The claim "the poller grows its declared capacity" is never exercised.
    • Surviving patch: delete the if watched > self.capacity { … } block. window_wake.rs watches one window, so nothing turns red; the result is a watch_raw capacity panic at 4 windows.
    • Required: window_wake opens at least 4 windows before its rounds. The patch must turn toolkit_window_wake red.
  • memmap2 toyos-0.9.11 src/toyos.rs:136. make_exec answers Ok(()) on a heap buffer. Its own header says an executable view is refused with Unsupported, and this branch newly patches the module into every userland crate.
    • Fix: pub fn make_exec(&mut self) -> io::Result<()> { unsupported() }.
  • NOTICE:220 and src/assets.rs:339. The OFL text does not ship with the fonts.
    • OFL §2 needs each copy to carry "this license". Name ID 13 in OpenSans-Regular.ttf reads "This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is available with a FAQ at: https://scripts.sil.org/OFL". That points to the licence; it is not the licence.
    • Fix: ship licenses/OFL-1.1-OpenSans.txt beside the fonts in /system/share/fonts/, or wherever the image keeps licences, with its own row.
  • forks.toml repins against Storage stage 3, steps 1–4: toyos-blockring, SYS_DEVICE_DMA_MAP, blockd and partition sessions #525. The closed fork-pin issue comes back silently at the next landing, which is already open.
    • Storage stage 3, steps 1–4: toyos-blockring, SYS_DEVICE_DMA_MAP, blockd and partition sessions #525 moves toyos-abi to 0.13, toyos to 0.14 and toyos-window to 0.15. This branch moves toyos-window 0.14→0.15 and pins every fork at abi 0.12, toyos 0.13 and window 0.15.
    • What must happen: whichever lands second takes toyos-window 0.16. Its abi-split reds on the reused 0.15, which is loud. In the same PR it must also cut new repin branches for all 13 fork branches and both lockfiles.
    • Without that, getrandom ×3, mio, socket2, libloading and cpal silently resolve the published abi 0.12 and toyos 0.13 beside the tree's. That is exactly issues/build/fork-tier-crates-still-pin-toyos-abi-at-0.1.md, which this PR closes.
    • Required here: land the exit condition of issues/build/an-sdk-bump-leaves-every-fork-on-the-last-sdk.md, a gate that reds when a lockfile holds two versions of a sdkversion::PUBLISHED crate. The second lander is then refused instead of silently resolving the old versions.
  • userland/slint-hello/Cargo.toml:12. The owner ruling "existing Rust just works" is not met for slint.
    • The fixture is not upstream code. It names default-features = false plus four features, so slint = "1.18" as every slint template writes it does not build.
    • The cause is cfg gates of the same kind the slint fork already carries: glutin/femtovg, Qt, and accesskit's zbus. They need native toyos arms in ToyOSOrg/slint toyos-1.18.1, not an issue file.
    • Required: slint with default features builds and runs under toolkit_slint. Use an upstream slint example byte for byte, as iced and egui do.

NOTE

  • Fork versioning. The -sdk-N scheme is a debt generator. sdkversion bumps a minor on every change to a published crate, so every change mints up to 13 new fork branches and leaves 13 behind; forks.toml already lists them as "left behind, unrewritten". A better scheme:
    • one branch per upstream base (toyos-0.30.13), with repins appended as commits (appending is not rewriting, and lockfiles pin the hash);
    • SDK dependencies written as a range (toyos-abi = ">=0.12, <1"), so [patch.crates-io] takes the tree's version with no fork commit at all;
    • an API break shows up as a compile error, and the lockfile gate above covers the rest.
  • winit 0.30 event_loop.rs:473. Deleting .filter(|live| !live.closed) survives every test. A window that received Close but is kept open by its app then spins the loop on a connection that stays readable.
  • winit 0.30 window.rs:87 and window.rs:39/:310 when called on the loop's own thread: each wake is a pipe write plus an extra NewEvents/AboutToWait round that has_pending already made unnecessary. Wake only when off the loop thread.
  • Two ToyOS winit backends, 0.30 platform_impl/toyos (+1145) and 0.31 winit-toyos. This branch fixed the same loop defect twice. Porting snake, calc and doom to 0.30 and retiring the 0.31 branch deletes one copy; no toolkit uses 0.31.
  • userland/toyos-window/src/wait.rs:34. Waker/take_wake is the fourth wake pipe in the tree, after logd's bell (userland/logd/src/main.rs:213), userland/soundd/src/say.rs:109 and mio's src/sys/toyos/waker.rs. Nothing about it is window-specific, so it belongs beside Poller in toyos. Moving it later costs another SDK bump.
  • Size: slint-hello and egui-hello are third-party test apps only, and they bring slint's and egui's trees, 12 i-slint-* and 3 parley [patch] rows and most of the +6737 lock lines into the shipping workspace. Every userland resolve then fetches the slint (88 MB) and wgpu (71 MB) forks. Move them to a separate test workspace, as tests/toyos-rust-tests is, and carry them through CARRIES.
  • userland/iced-counter's it_counts joins the macOS host lane. It compiles iced and wgpu there to test iced's own simulator, which exercises nothing of ToyOS.
  • tests/toyos.rs:8721. 64 distinct colours means "the window is not flat", not "text was drawn": a gradient, a shadow or an image passes. Only iced has a measured red arm (14 colours). slint's no-font arm panics before it draws, so no slint window without text was ever counted, and egui has no red arm at all.
  • wgpu wgpu/build.rs:34. target_has_backend is a third hand copy of the platform lists in the vulkan and gles aliases. Name the platform set once and derive all three, or a platform added upstream will panic again or stop panicking.
  • /system/share/fonts is declared three times: fontdb, fontique and src/assets.rs. fontique's DEFAULT_GENERIC_FAMILIES maps no monospace or serif family, and cosmic-text asks for "Noto Sans Mono", so monospace text silently gets Open Sans.
  • issues/design-debt/softbuffer-reads-a-toyos-window-behind-its-lock.md is a race, and the new 0.30 backend reproduces it: raw_window_handle_rwh_06 lets the pointer escape the lock. It is recorded, and it stays a present weakness.
  • metal_job_reboot: the body's new evidence (red alone with 0 bytes, 1/5 on the branch against 2/5 on main) belongs in issues/build/metal-job-reboot-drained-no-kernel-output-beside-other-guests.md, which still says the rerun alone was green. --known-red answers NO.
  • window_wake.rs claims that across the rounds a wake lands both before the wait blocks and while it is blocked. Nothing measures which of the two happened.
  • eframe with default features does not run. It is filed, and it is still short of "existing Rust just works" for egui.

REMOVE

  • PR body, "the host lane is Linux": false. ci.yml's host runs on macos-latest.
  • PR body, "Independent oracle … iced_test's simulator runs upstream's own test": that test checks no claim this change makes.
  • NOTICE:220, "which is the machine-readable place the OFL's second condition names": name ID 13 is a URL, not the licence.
  • forks.toml:239, from "It answers dead_code below" to "third objection": a discussion that will rot.
  • tests/toyos.rs TEXT_SHADES doc: "three words leave hundreds", "adds a score or so" and "A window with no text in it is far under this". These are counts, and the last is unmeasured for slint and egui.

SEND BACK

Japabu and others added 12 commits September 26, 2026 15:39
Owner ruling: the platform supports iced alone for now. The slint and
egui test apps, the slint and parley/fontique forks and their `[patch]`
rows are gone, and an issue records the choice with its exit.

winit: the 0.31 fork line is retired and snake, calc and doom run on the
0.30 backend iced uses, so one ToyOS winit backend exists. On it, a redraw
asked for after `pre_present_notify` waits for the window's frame event;
a dropped window's redraws are forgotten; creating a window wakes nothing,
and redrawing or dropping one wakes the loop only from another thread.

The wake pipe is `toyos::wake` (`Waker` and `Bell`) beside `Poller`, and
`window::Waiter`, logd's bell and soundd's line writer use it; `toyos`
0.13 -> 0.14. mio's waker could not take it as a swap and is filed.

Forks: one branch per upstream base, with each fix appended; every fork
names the SDK crates by a range, so the tree's patched version answers it
and an SDK bump owes no fork a commit. `sdkversion::judge` refuses a
lockfile holding two versions of a published crate. getrandom 0.2/0.3 and
libloading keep a second branch until the toolchain re-locks (filed).
memmap2 refuses `make_exec`; wgpu names its native platforms once.

The compositor counts each window's presents and frame events and says
both when it closes the window. Tests: toolkit_iced proves its label is
Open Sans at 16 px by correlating the panel with the word rendered here by
fontdue, and bounds its idle presents; toolkit_winit_loop drives the loop
through winit's API (a proxy event from AboutToWait, cross-thread events,
redraws and drops, a drop in the creating handler, a kept closed window);
toolkit_winit_pace holds an animation to the frame events; window_wake
watches four windows. The OFL text ships beside the fonts.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
iced's counter example leaves the userland workspace for
tests/iced-counter, a package with its own lock and patches that
toolkit_iced builds and carries into the toolkit desktop. No image and no
userland resolve pays for iced's tree any more (wgpu, fontdb and memmap2
leave userland's patches and 2334 lines leave its lock), and upstream's
it_counts, a test of iced's own simulator, joins no host lane.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Each of the counter's two labels must correlate with the word as Open
Sans draws it at 16 px. With no system fonts iced draws its buttons flat
and "Increment" correlated at 0.349 at best; a gradient in place of the
widgets reached 0.156; the labels at head reach 0.787 and 0.866. The bar
is 0.6.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
@Japabu Japabu changed the title Toolkits run unchanged: winit 0.30, one wait for windows and wakes, system fonts, and iced, slint and egui as guest tests Existing Rust GUI apps on ToyOS: iced on one winit backend, paced redraws, forks on one branch per base Sep 26, 2026
@Japabu

Japabu commented Sep 26, 2026

Copy link
Copy Markdown
Collaborator Author

Answer to the review of 4ad645a — head 42059f5

Under the owner's ruling of 2026-09-26 (iced only, for now). Every mutation below was a checked patch, shown to build (no cargo build failed in its log), run, and reverted; the tree was clean after each. winit and memmap2 mutations were committed on scratch branches of local clones and consumed as file:// git sources.

BLOCKERs

  1. Frame-event fix untested — fixed. The compositor now says each window's presents=P frames=F when it closes it; toolkit_iced requires ≤ 1 present while nothing happens to the window. Mutation Event::Frame => { r.frame(id); r.request(id); } (a frame event redraws): --nightly toolkit_iced EXIT=1, "presented 49 times (49 frame events back)", alone 74. Head: 1 present, 1 frame, EXIT=0.
  2. Redraws unpaced — fixed. A redraw asked for after pre_present_notify is held until the window's next frame event (winit toyos-0.30.13, 9dc6848f). toolkit_winit_pace: an animation draws 60 frames; presents must be 60 and ≤ frames + 1. Mutation pre_present_notify does nothing: EXIT=1, "60 presents against 16 frame events", wide and alone. Head: 60 against 60, EXIT=0. a-toyos-winit-window-redraws-unpaced.md is deleted.
  3. No proxy / cross-thread test — fixed. toolkit_winit_loop (winit_loop.rs) drives the loop through winit's API. Patch A (take_wake() after AboutToWait): EXIT=1, "LOST: … the user event sent from AboutToWait", wide and alone. Patch B: Window::new raises no wake any more (a window is created only on the loop's thread, from a handler, where has_pending finds it), so B is the off-thread wake in Window::drop deleted: EXIT=1, "LOST: … round 0's window dropped on the helper", wide and alone. The same for request_redraw's wake: EXIT=1, "round 0's redraw asked from the helper". Head: EXIT=0.
  4. RedrawRequested after Destroyed — fixed. Window::drop and the loop's destroy step forget the window's queued and held redraws; stage 4 creates, redraws and drops in one handler. Mutation both forgets deleted: EXIT=1, "RedrawRequested after Destroyed", wide and alone.
  5. Waiter growth unexercised — fixed. window_wake watches 4 windows. Mutation the growth block → let _ = watched;: EXIT=1, Poller: … capacity is 4 panic at poller.rs:269. (The harness now also fails at once on a panicked line.)
  6. memmap2 make_exec — fixed (toyos-0.9.11 ad0d8905, unsupported()), tested by memmap_exec_refused in the shared boot. Mutation make_exec → Ok(()): -- memmap_exec_refused EXIT=1, "make_exec answered Ok on a heap buffer". Head: PASS in the fast tier.
  7. OFL text — fixed. assets/fonts/OFL.txt (moved from licenses/, same digest, its own COMMITTED_FILES row) ships as /system/share/fonts/ofl.txt; NOTICE no longer calls name ID 13 the licence. Mutation add_dir skips .txt: cargo test --lib the_system_fonts_ship_with_their_licence EXIT=101, "… ship without the licence text beside them".
  8. Storage stage 3, steps 1–4: toyos-blockring, SYS_DEVICE_DMA_MAP, blockd and partition sessions #525 collision and fork versioning — the reviewer's scheme adopted. One branch per upstream base with fixes appended; every fork names the SDK crates as >=<first used>, <1 (a patch at 0.11.0 was measured to win over the registry's 0.12.0 for >=0.10, <1); sdkversion::judge refuses a lockfile holding two versions of a published crate. Mutation getrandom 0.4 pinned at e05f79d (names toyos-abi = "0.1"), committed in a scratch clone: --ci abi-split EXIT=1, "userland/Cargo.lock holds toyos-abi at 0.1.0 and 0.12.0". an-sdk-bump-leaves-every-fork-on-the-last-sdk.md is deleted. getrandom 0.2/0.3 and libloading keep their -sdk-0.12 branch beside the base branch because rust/Cargo.lock pins the base branch a commit back (filed). Whoever of Storage stage 3, steps 1–4: toyos-blockring, SYS_DEVICE_DMA_MAP, blockd and partition sessions #525 and Existing Rust GUI apps on ToyOS: iced on one winit backend, paced redraws, forks on one branch per base #528 lands second bumps versions in-tree only.
  9. slint default features — settled by the ruling: slint and egui are removed, recorded in slint-and-egui-are-not-supported-by-the-owners-choice.md.

NOTEs

  • Fork versioning: the BLOCKER 8 scheme.
  • .filter(|live| !live.closed): stage 5 of toolkit_winit_loop. Mutation deleted: EXIT=1, "woke the loop 16647 times in 1s", alone 6871.
  • Wakes on the loop's own thread: redraw and drop wake only off the loop's thread; create never.
  • Two backends: snake, calc and doom ported to winit 0.30; nothing pins the 0.31 line (+1249 over its tag as main pins it). desktop_window_child (snake) EXIT=0, doom_ EXIT=0, calc's host tests in --ci host.
  • Waker: toyos::wake (Waker, Bell) beside Poller; window::Waiter, logd and soundd use it; toyos 0.13 → 0.14. mio: not a clean swap (nothing in its selector reads the pipe) — filed.
  • Size: iced's app moved to tests/iced-counter, a package of its own that toolkit_iced builds and carries; userland no longer patches wgpu, fontdb or memmap2, and its lock loses 2334 lines against the previous head.
  • it_counts on the host lane: gone with the move (host lane 38 steps before the merge of Every test's scratch goes with it, and a killed run's with the next #529).
  • Pixel test: both labels are matched by normalised cross-correlation against the words rendered by fontdue from the committed Open Sans at 16 px, bar 0.6. Head 0.787 / 0.866. Red arms: no system fonts EXIT=1, best 0.349; a full-window gradient in place of the widgets EXIT=1, best 0.156.
  • wgpu: one alias for the native Vulkan/GL platforms (toyos-27.0.4 e8a91805); the upstream branch names trunk's three sets once (418698e0).
  • /system/share/fonts: written in the fontdb fork and in the asset layout only; fontique is gone. Monospace/serif: filed.
  • softbuffer race: recorded, still true; the issue now says one backend.
  • metal_job_reboot evidence: moved into its issue.
  • window_wake's unmeasured claim: rounds now alternate a wake pending before the wait with one raised after the wait is entered; the doc says which of "before it blocks" and "while blocked" the second lands on is not observed.
  • eframe: unsupported by the ruling.

REMOVE

All five: the Linux host-lane sentence and the iced_test oracle are not in the new body; NOTICE's name-table sentence is replaced; forks.toml's dead_code/third-objection passage is gone; TEXT_SHADES and its doc are deleted.

Gates

  • --ci host EXIT=0 (39 steps at the merged head; 38, EXIT=0, before it). --ci abi-split EXIT=0 ("bumped: toyos 0.13.0 -> 0.14.0, toyos-window 0.14.0 -> 0.15.0"). --check-forks EXIT=0 (23 branches, all current). cargo test --lib EXIT=0 (377).
  • --nightly toolkit_ EXIT=0, 4 of 4, before and after the merge. desktop_window_child EXIT=0 and doom_ EXIT=0 at f6d7748.
  • Fast tier at the merged head: EXIT=1, 397 passed, 1 failed, lan_mdns_answer (socket path past SUN_LEN, wide and alone); main in the same session reds on it too (filed). At f6d7748: EXIT=1, 2 failed (quiesce_wakes_on_the_last_park, metal_job_reboot, "QEMU died before ===READY===", ALONE GREEN, --known-red NO) against main's same-session run: EXIT=1, 4 failed with the same boot-death shape among them.

Left for the owner: deleting the six per-SDK branches the previous head minted (each contained in its base branch, consumed by nothing) was refused by this session's permissions.

@Japabu

Japabu commented Sep 26, 2026

Copy link
Copy Markdown
Collaborator Author

Review of #528, round 2, at 42059f5

Ready for review: abi-split is SUCCESS on run 36254115990, whose headSha is 42059f5. host is SKIPPED, because it runs in the merge queue only. The body gives an exit code for each new nightly test and for each negative control.

Net lines (git diff --shortstat origin/main...HEAD): 54 files, +7615/−638.

  • Production: about +370/−95.
  • Tests: about +1210/−3, including the host unit tests in src/.
  • Lockfiles: +5666/−477.
  • Records: +368/−63.
  • Forks: winit 0.30 is +1221/−1 over v0.30.13 and replaces the 0.31 line (+1249). The growth in toyos::wake and window::Waiter is accepted: logd and soundd each lost their own copy of the pipe.

Round-1 BLOCKERs

  1. Frame-event/present bound: CLOSED. toolkit_iced requires presents ≤ 1. Under the mutation "frame event redraws" it is EXIT=1 with "presented 49 times", and 74 when run alone.
  2. Redraw pacing: CLOSED. toolkit_winit_pace requires 60 presents and presents ≤ frames + 1. With pre_present_notify made a no-op it is EXIT=1 with "60 presents against 16 frame events".
  3. Proxy and cross-thread wakes: CLOSED. Patch A, the drop wake and the redraw wake each go EXIT=1 with their own LOST line.
    • The claim that Window::new needs no wake holds under winit 0.30. The only ways to create a window are EventLoop::create_window/Window::new (src/event_loop.rs:307) and ActiveEventLoop::create_window (:378).
    • Both types carry PhantomData<*mut ()> (:45, :54), so neither is Send or Sync. Every creation therefore runs on the thread that built the loop, which is loop_thread, and has_pending sees creates before the next wait.
  4. Purge after Destroyed: OPEN. The first BLOCKER below explains why.
  5. Waiter growth: CLOSED. With the mutation, toolkit_window_wake is EXIT=1 on a capacity is 4 panic.
  6. make_exec: CLOSED on toyos-0.9.11 (ad0d8905). With the mutation, memmap_exec_refused is EXIT=1. A NOTE below covers the toolchain's branch.
  7. OFL text: CLOSED. The file ships as share/fonts/ofl.txt. With the mutation, the_system_fonts_ship_with_their_licence is EXIT=101.
  8. Fork versioning: CLOSED.
    • Every pinned fork manifest names the SDK by range. I read each one through gh api …/contents/Cargo.toml?ref=<sha>:
      • winit bd99e726 and softbuffer b36854df: toyos-window >=0.15, <1.
      • cpal, mio and socket2: abi >=0.12, toyos >=0.13.
      • getrandom ×3 and libloading: abi >=0.12.
    • split_versions refuses by name. It has a host test, and the getrandom mutation is measured EXIT=1.
  9. slint default features: CLOSED by the owner's ruling.

BLOCKER

  • winit toyos-0.30.13 src/platform_impl/toyos/event_loop.rs:568-602, and tests/toyos-rust-tests/src/bin/winit_loop.rs:208/:261. A window that is created and dropped inside a Destroyed handler becomes a zombie: it gets Resized and RedrawRequested after its Destroyed, and its compositor window leaks.
    • Stage 4 does exactly this, because stage_4 runs inside stage 3's Destroyed callback.
    • The creates loop has already run in that iteration. The drop's Destroyed is popped by the same destroys loop, and forget runs.
    • In the next iteration, creates still holds (Arc<Mutex<toyos_window::Window>>, W). W becomes a LiveWindow that is never removed. The loop delivers Resized(W), and :587 queues the RedrawRequested(W) that follows.
    • The app ignores both because it is already in stage 5, so the test prints "no redraw after it" while the bug happens.
    • Fix: a window dropped before the loop has taken its creation leaves creates too. For example, make creates an Arc and add this to Window::drop: self.creates.lock().unwrap().retain(|(_, c)| *c != self.id);.
    • Test: keep every dropped id in a gone list checked at the top of window_event, failing on any event for it after Destroyed. End stage 4 only at the second about_to_wait after destroyed. The harness must also find W's window closed client=… by the client itself line. Reverting the fix must turn toolkit_winit_loop red.
  • winit src/platform_impl/toyos/window.rs:317. Surviving mutation: delete self.redraws.lock().unwrap().forget(self.id); from Window::drop. Every test stays green.
    • Stage 4's queued redraw is purged by the destroy step's forget at event_loop.rs:601.
    • Stage 3 drops only after its redraw was delivered.
    • What this line guards is request_redraw(X); drop(X) in a handler that runs after the destroy step, such as a user_event or a polled window event. Without it, RedrawRequested(X) is delivered in the same iteration for a window the app has dropped.
    • Required arm in winit_loop: open X, and on its first RedrawRequested send a user event. In user_event, call X.request_redraw() and then drop(X). Fail on "RedrawRequested for a window its application already dropped". The patch above must turn toolkit_winit_loop red.
  • src/assets.rs:516. a_system_font_ships_as_it_is_and_the_console_font_as_its_raster builds its own scratch from std::env::temp_dir() and leaks it on a panic.

NOTE

  • winit event_loop.rs:335-338. A window dropped while the loop is polling its events still has events delivered to it until the next iteration.
    • A queued Resized goes through redraws.request(self.id) after Drop's forget, which queues a RedrawRequested before Destroyed.
    • Skip, in the poll loop, any LiveWindow whose id is in destroys. The same gone set as above then covers both paths.
  • memmap2 toyos branch at 87ae85a1, which rust/Cargo.lock pins: make_exec still returns Ok(()). The fix went onto toyos-0.9.11 only. Either append it, or file it beside the-toolchain-pins-an-older-commit-of-three-userland-forks.md.
  • toyos/src/wake.rs:41. Surviving mutation: drop Err(SyscallError::WouldBlock) from the arm that answers Ok. No test raises more wakes than the pipe holds, and logd, soundd and every winit proxy now depend on that arm. Add one window_wake round that raises 100 000 wakes before its wait.
  • tests/toyos.rs:8955. "Both labels" can pass with only one word on screen.
    • "Decrement" shares "crement" with "Increment", and the two best placements are never required to differ.
    • Patch to try: an iced view with only button("Decrement").
    • Require the two best placements to be disjoint.
    • To the brief's question: a blank but textured window does not realistically pass. Normalised cross-correlation (NCC) against a nine-letter template leaves texture near the gradient's 0.156, far under 0.6. Only word-shaped ink gets close.
  • tests/iced-counter/Cargo.toml:18-19. [dev-dependencies] iced_test is locked (nom, png, sha2, iced_selector) for a #[cfg(test)] that nothing runs. Delete it; the .rs file stays byte for byte.
  • tests/iced-counter/Cargo.toml:39. This is the tree's fifth hand copy of [profile.toyos].
  • issues/design-debt/slint-and-egui-are-not-supported-by-the-owners-choice.md. It is kind: rejected but has an Exit ("revisit once …"). issues/README.md says a deferral is not a decline, so the kind is wrong.
  • tests/toyos.rs toolkit_iced repeats the BootOptions and shell-launch code of toolkit_launch. Pass the iced bins into toolkit_launch instead.
  • The spurious WaitCancelled about 0.1 ms after the close ("What I am unsure of") is plausibly the leftover registration from the previous round that toyos/src/poller.rs's Poller doc names. Measure it before writing IDLE_WAKES = 2 down as winit's allowance.
  • Per-SDK branches: nothing consumes the six the previous head minted.
  • ABI collision with Storage stage 3, steps 1–4: toyos-blockring, SYS_DEVICE_DMA_MAP, blockd and partition sessions #525, and with Self-update, stage 1: signed A/B slots, ssh … update < image, swap over exec #530, which carries the same three versions. This head moves toyos 0.13→0.14 and toyos-window 0.14→0.15. Storage stage 3, steps 1–4: toyos-blockring, SYS_DEVICE_DMA_MAP, blockd and partition sessions #525 moves toyos-abi 0.12→0.13, toyos 0.13→0.14 and toyos-window 0.14→0.15. The toyos and toyos-window versions collide exactly.
    • The version lines are identical edits, so git merges them cleanly. Only abi-split refuses the collision, with "toyos changed and its version did not".
    • abi-split runs only on pull_request, and the main ruleset has strict_required_status_checks_policy: false. A second lander enqueued on its old green abi-split is judged by host alone. Here the lockfile conflicts almost certainly force a re-merge, but nothing guarantees it.
    • The second lander must:
      1. Merge origin/main.
      2. Take toyos 0.15.0 and toyos-window 0.16.0, including toyos-window's toyos pin. toyos-abi stays at Storage stage 3, steps 1–4: toyos-blockring, SYS_DEVICE_DMA_MAP, blockd and partition sessions #525's 0.13.0.
      3. Re-lock every tracked lock: userland/, userland/libc, toyos/, tests/toyos-rust-tests, tests/iced-counter.
      4. Push, see abi-split green on the PR, and only then enqueue.
    • Nothing needs a fork commit: winit and softbuffer's >=0.15, <1 takes 0.16.
    • If Storage stage 3, steps 1–4: toyos-blockring, SYS_DEVICE_DMA_MAP, blockd and partition sessions #525 lands second, its locks, which today hold toyos-abi 0.1, 0.2 and 0.13, are refused by this branch's split_versions until it takes the range branches.

REMOVE

  • PR body, "Nothing is delivered for a dropped window.": false. See the first BLOCKER and the first NOTE.
  • tests/iced-counter/Cargo.toml:24, "which the forks name by version": the forks name them by range.
  • tests/toyos-rust-tests/src/bin/winit_loop.rs:41, "one that lands after is certain": it is likely, not certain.

SEND BACK

Japabu added a commit that referenced this pull request Sep 26, 2026
…Arch64

The rust pin moves to 4874af48e26 (on toyos-inbox): the
aarch64-unknown-toyos target spec, and std's `_start` and TLS descriptor
resolver on AArch64 (variant I, `__toyos_tlsdesc_dynamic`). It is a
compiler change, so this worktree builds its own compiler
(src/compiler.rs) and the primary's is untouched.

- The build: `GUEST_TARGETS` gains aarch64-unknown-toyos, and every
  architecture has a userland, so `USERLAND_ARCHS` and the plan's
  `Userland` switch (whose `Absent` arm nothing could reach any more,
  and whose `without_userland` nothing called) are deleted. `cargo run --
  --arch aarch64 --build-only` builds std, libtoyos_c and the userland
  for AArch64 and puts them on ROOT.
- libc: `_start`, memcpy/memmove/memset and the square roots move into
  `userland/libc/src/arch/`, one module per architecture, and gain their
  AArch64 versions (pair loads and stores with a byte tail, fsqrt). The
  copies were checked on this AArch64 host against its own
  copy_within/fill over 360,000 cases (lengths 0..300, offsets 0..20,
  overlapping both ways); a copy_backward whose chunk test was 8 instead
  of 16 died on the same check (SIGBUS, exit 138).
- toyos-window's and metalprobe's scanout drain moves into an arch
  module (SFENCE; DSB ST on AArch64), and the ARCH_RULES rows for them
  and for libc become module places. toyos-window is published, so it
  bumps to 0.16.0: 0.15.0 is taken by #525 and #528.
- calc, snake and doom are left off an AArch64 ROOT, by name at build
  time (`NOT_YET_BUILT`): softbuffer's and winit's toyos forks resolve
  the published toyos-window 0.2.0, whose framebuffer is x86-64 only
  (issues/build/the-toolkit-forks-resolve-an-x86-only-toyos-window.md).
  Everything else in the userland workspace, and toyos-ld and toyos-cc
  as guest programs, builds and links for AArch64.

compiler.rs keys a compiler on the content of its sources alone:
keying on the git spelling of compiler/ made committing what had been
built as local changes a new compiler and a full rebuild.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Japabu and others added 4 commits September 26, 2026 18:25
…guard

The winit loop test fails on any event delivered for a window after its
application dropped it, other than its one `Destroyed`, in every stage. Stage
4 ends at the second `AboutToWait` after its `Destroyed`, with the iteration
between forced by `ControlFlow::Poll`, since that iteration is where a window
still queued for creation got its `Resized` and `RedrawRequested`. A new stage
5 asks a window for a redraw and drops it in a `user_event`, which runs after
the loop's destroy step, so only `Window::drop`'s own `forget` keeps the
redraw from reaching it. The harness then reads the compositor's close lines:
every window the app dropped has to be closed "by the client itself" before
the window it kept is closed by GUI+Q, which a window leaked until the app's
exit is not.

`a_system_font_ships_as_it_is_and_the_console_font_as_its_raster` takes its
scratch from `toyos_tmpdir::TempDir` rather than building one from
`temp_dir()` and leaking it on a panic. `every_host_scratch_is_the_guard`
refuses `temp_dir()` in host code outside three counted exceptions: the guard
itself, the keymap golden's dump, which is left for its reader on purpose,
and `src/release.rs`, filed.

The slint/egui entry is a deferral by the owner ("for now"), so its kind is
`defect` and it stays open, as `issues/README.md` rules for a deferral.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
…ept one's

A window the app still held when it left is closed by its exit, and that
close says "by the client itself" too. Read up to the kept window's GUI+Q
close, which comes before the exit, a leaked window is still open.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Upstream's `it_counts` is a `#[cfg(test)]` no lane builds, so its
dev-dependency locked nom, png, sha2 and iced_selector for nothing. The
example's source stays byte for byte.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Pins `toyos-0.30.13` at f58e1f3b. `Window::drop` takes the window out of the
loop's creation queue, so one created and dropped in a handler that runs
after the loop's creation step, a `Destroyed` handler among them, closes its
compositor window at the drop and hears only its `Destroyed`; before, the
loop took it in its next iteration, delivered `Resized` and
`RedrawRequested` after the `Destroyed`, and kept it open until the app
left. A window dropped in the handler of one of its own polled events hears
none of the rest, and a `Resized` queues its redraw before the handler runs,
so a drop inside it forgets that too.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Japabu added a commit that referenced this pull request Sep 26, 2026
… is asked over ssh

The review of 1b8d459 found four blockers and a fast-tier question.

HOME on the direct path. std's direct spawn handed a child the parent's
whole environment, so an ssh exec of an undeclared binary ran with
HOME=/state/sshd. init now answers a launch of an undeclared program with
the session's HOME (MSG_NOT_DECLARED carries it; toyos::launch's
Outcome::NotDeclared has it), and std's direct spawn carries only a HOME
its caller named or init answered, never its own (fork commit 957f1426,
merged with toyos-inbox at 7a809b75, #520's pin, in 80ea645f).

The layout, asked over the cable. layout_fresh_boot boots
tests/layoutcase (sshdcase plus a declared shell and the locale applet)
with a staged key, then over ssh: `shell -c 'echo $HOME'` must print
/home/toy (a launched row's HOME is init's, over sshd's); `locale de` and
an interactive shell write /config/keyboard-layout and the shell's
history; and test_rs_layout_paths, declared nowhere so sshd spawns it
directly, asserts its HOME, both files by literal path, and the exact
listings of /home/toy and /state.

An empty directory is listed. Vfs::list names the directories the VFS
carries in created_dirs, so an empty dot-folder is in its parent's
listing and the dotfile walk sees it. The filed DATA-directory issue
loses that bullet and its slug says what is left.

Also: a manifest row that serves a port and is not marked a service is
refused at render, and every config is rendered by a host test; init's
folder failure no longer says the whole session home is missing; the
shell's history finds its own folder whether HOME is the session's or,
at stage 2, the folder itself; the track records the owner's rulings,
gains a time-zone, a language and a fonts stage, and no longer ships
JetBrains Mono here, which leaves src/assets.rs and NOTICE to #528;
the sshd fail-closed issue is closed, its exit met by the blank DATA
volume every image-less boot gets.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Japabu and others added 2 commits September 26, 2026 19:14
`toolkit_iced` matched each label at its best place anywhere in the window,
and "Increment"'s best was on "Decrement": at 0.787 at (486, 279) against
"Decrement"'s 0.866 at (479, 279), so the check passed on one word's ink.
The label matched best now claims its place and the other is matched only
away from it: "Increment" then scores 0.781 on its own button, and with a
view of only `button("Decrement")` it scores 0.349 and the test reds. The
launch goes through `toolkit_launch`, which now takes the line to type.

`toolkit_window_wake` ends with one wait after more wakes than the wake pipe
holds, measured on a fresh pipe (2 097 088 bytes here): a wake that finds
the pipe full is one already pending, and the flood is one wake to the wait
and one take.

`toolkit_winit_loop`'s idle stage allows one iteration, the deadline's. The
second it allowed, a `WaitCancelled` straight after the close, was the
window leaked by stage 4: instrumented, that wait watched only the leaked
window and its completion was that window's, and with the leak fixed twelve
runs saw none.

The toolchain's memmap2 branch still answers `Ok` from `make_exec`, filed:
appending the fix there leaves `rust/Cargo.lock` behind it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
#525 took toyos-abi 0.13.0, toyos 0.14.0 and toyos-window 0.15.0, the same
toyos and toyos-window versions this branch had taken. toyos-abi stays at
#525's 0.13.0; toyos moves to 0.15.0 and toyos-window to 0.16.0, its `toyos`
pin with it. Every tracked lockfile is re-locked on the merged manifests,
which also takes #525's locks off the old fork branches: none holds a
second version of toyos-abi, toyos or toyos-window.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
@Japabu

Japabu commented Sep 26, 2026

Copy link
Copy Markdown
Collaborator Author

Round 3: the answer to the review, at 254ea74

BLOCKER 1, zombie window: fixed.

  • winit f58e1f3b: Window::drop takes the window out of creates.
  • winit_loop fails on any event for a window after the app dropped it, other than its Destroyed.
  • Stage 4 ends at the second AboutToWait after the Destroyed.
  • The harness requires every dropped window's "by the client itself" close line before the kept window's GUI+Q line.
  • Arms:
    • head: EXIT=0;
    • fix line deleted: EXIT=1, "Resized(…) after Destroyed";
    • the same with the app-side check off: EXIT=1, "window 20 … not closed by its drop … but by None".

BLOCKER 2, surviving forget: now killed.

  • New stage 5: request_redraw(X) then drop(X) inside user_event.
  • Deleting forget from Window::drop: EXIT=1, "RedrawRequested for a window its application already dropped".

BLOCKER 3, second temp-dir helper: fixed.

  • TempDir::new("fonts").
  • New sourcegate::every_host_scratch_is_the_guard: the revert is EXIT=101 and head is EXIT=0.
  • src/release.rs is filed as a counted exception.

NOTEs

  • Poll-loop delivery: fixed in the same winit commit.
  • WouldBlock:
    • The pipe holds 2 097 088 bytes, so the 100 000 wakes the review suggested would never fill it.
    • The flood is 2 097 089 wakes on a capacity measured on a fresh pipe.
    • Mutation: EXIT=1, panic at wake.rs:32.
  • Labels:
    • Without the disjoint rule, "Increment"'s best place at head was on "Decrement": 0.787 at (486, 279) against (479, 279).
    • Now the best label claims its place and the other is matched away from it: 0.781 on its own button.
    • A view with only button("Decrement") scores 0.349: EXIT=1.
  • The spurious wake was the zombie, not a leftover registration. Instrumented, the extra completion was the leaked window's, in 2 of 6 zombie runs. Head showed none in 13. IDLE_WAKES is now 1.
  • iced_test is dropped, and 19 packages leave the lock.
  • [profile.toyos] is not shared: that needs a --config in src/build.rs for every workspace (see the body).
  • memmap2 toyos: not fixed. Appending the fix leaves rust/Cargo.lock behind in --check-forks, and re-locking it changes the compiler's dependency graph. Filed: issues/build/the-toolchains-memmap2-branch-answers-ok-from-make-exec.md.
  • The slint/egui entry is now kind: defect, status: open.
  • toolkit_iced launches through toolkit_launch.

REMOVE: all three lines are deleted.

ABI. origin/main (7345e3f, #525) is merged, not rebased.

  • toyos-abi stays at 0.13.0.
  • toyos goes to 0.15.0.
  • toyos-window goes to 0.16.0, with its pin.
  • Every tracked lock is re-locked, tests/iced-counter included.
  • No lock holds two versions of any SDK crate.
  • Storage stage 3, steps 1–4: toyos-blockring, SYS_DEVICE_DMA_MAP, blockd and partition sessions #525 added no fork pin. Its locks' old-SDK crates came only through main's -sdk-0.2/base branches, and the re-lock puts them on the range branches. The only conflicts were userland/Cargo.lock and tests/toyos-rust-tests/Cargo.lock.

Gates

  • --ci host: EXIT=0 (43 steps).
  • --ci abi-split: EXIT=0 ("toyos 0.14.0 -> 0.15.0, toyos-window 0.15.0 -> 0.16.0").
  • --check-forks: EXIT=0 (23 current).
  • --nightly toolkit_: EXIT=0, 4/4.
  • snake (desktop_window_child): EXIT=0.
  • doom (doom_): EXIT=0.
  • Fast tier on the head: EXIT=1 twice.
    • lan_mdns_answer both times. It is also red on main's run, EXIT=1 with 1 failure.
    • Plus three wide-only reds per run, a different three each time. Each is green alone on both sides, and each is in a filed beside-other-guests issue.
    • main's one wide run had none of them. That difference is unexplained, and the body says so.

Japabu and others added 4 commits September 26, 2026 20:11
# Conflicts:
#	tests/toyos-rust-tests/Cargo.lock
#	userland/Cargo.lock
…sions

Merging origin/main (#531) collided this branch's toyos/wake.rs and
toyos-window/wait.rs additions with main's own bump of the same two crates to
identical version numbers (0.15.0, 0.16.0) for different content. Move both
one minor past main's landed pins and re-lock every tracked workspace with
`cargo update -w`, which also drains the dead winit 0.31.0-beta.2 subgraph and
the stale getrandom/mio/socket2 fork pins the split-version gate (added on
this branch before the merge) then caught: real crates.io toyos/toyos-abi
0.1.0/0.2.0 resolving beside the tree's own path versions because those pins
predated the tree's `-sdk-0.12` branch renames and the getrandom `toyos-0.4`
branch fix already at its head.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
`git checkout --theirs` on the two conflicted Cargo.lock files also staged
`rust` from whatever the submodule's on-disk checkout happened to be, which
was still this branch's pre-merge commit rather than the auto-merged one —
silently reverting main's HOME/launch ABI follow-through in
`sys/process/toyos.rs` and breaking every std build. Fast-forward the
gitlink to main's pin instead.

`tests/toolkitcase/system.toml`'s `compositor` row predates main's rule that
a program serving a machine-wide port is marked a service by hand
(`ServesWithoutService`); every other desktop config already carries
`service = true` beside it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Follows through on the previous commit's description: main's
ServesWithoutService rule reds every config whose machine-wide-serving
program isn't marked `service = true` by hand, and this file's `compositor`
row was the one left behind.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
@Japabu

Japabu commented Sep 26, 2026

Copy link
Copy Markdown
Collaborator Author

Merge main (#531) and re-sync

Head is now 4026950e (merge 2aae5a86 + three follow-up commits).

Versions

  • toyos-abi: unchanged at 0.14.0 (this branch never touches it)
  • toyos: 0.15.0 → 0.16.0 (collided with main's own bump of the same crate to 0.15.0 for different content — wake.rs)
  • toyos-window: 0.16.0 → 0.17.0 (same collision, on wait.rs)
  • Every in-tree dependent's version = pin moved with them; every tracked lockfile re-locked with cargo update -w in its own workspace (or a targeted -p where -w needed disambiguation).

What the re-lock and the gates caught (all pre-existing, surfaced by the merge)

  • userland/Cargo.lock and tests/{toyos-rust-tests,iced-counter}/Cargo.lock were resolving real crates.io toyos/toyos-abi/toyos-window/toyos-font 0.1.0/0.2.0 beside the tree's own path versions — dead winit-toyos-0.31.0-beta.2 subgraph plus stale getrandom/mio/socket2 fork pins that predated the tree's -sdk-0.12 branch renames and a fork-branch fix already at its head. cargo run -- --check-forks named the exact fixes (cargo update --manifest-path userland/Cargo.toml -p getrandom@0.4.2 -p mio@1.2.0 -p socket2@0.6.3); re-locking cleared the split and --check-forks now reports all 23 branches current, 0 dead.
  • My git checkout --theirs conflict resolution on the two Cargo.lock conflicts also (wrongly) staged rust from the submodule's stale on-disk checkout instead of the auto-merged pointer, silently reverting main's HOME/launch ABI follow-through (Outcome::NotDeclared gaining a home field) and breaking every std build. Fast-forwarded the gitlink to main's 80ea645f — a real merge-hygiene bug this branch would otherwise have shipped.
  • tests/toolkitcase/system.toml's compositor row predated main's ServesWithoutService rule; added service = true to match every other desktop config.

Fast-tier A/B — skipped

df -h /Users showed 26 GiB free, below the 30 GiB floor the brief set. Not attempted.

Gates

  • cargo run -- --check-forks: exit 0 (23 branches asked, all current; 0 dead declarations) — informational/on-demand, not a required check.
  • cargo run -- --ci abi-split: exit 0 — bumped: toyos 0.15.0 -> 0.16.0, toyos-window 0.16.0 -> 0.17.0.
  • cargo run -- --ci host: exit 0 — 43/43 steps green. (First run was red on build::tests::every_config_renders_its_manifest for the reason above; fixed, second run green.)
  • cargo test --test toyos-build -- --nightly toolkit_: exit 0 — 4/4 passed (toolkit_iced, toolkit_winit_pace, toolkit_winit_loop, toolkit_window_wake), 82.3s parallel.

Not arming auto-merge or waiting on CI, per the brief.

🤖 Generated with Claude Code

https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK

@Japabu

Japabu commented Sep 26, 2026

Copy link
Copy Markdown
Collaborator Author

Round-3 BLOCKERs closed and judged at 254ea74 (zombie window purged from creates, forget pinned, host scratch through TempDir, each red under its mutation); final round 4026950 merges #531 and takes toyos 0.16.0 / toyos-window 0.17.0, re-locks onto the range branches (--check-forks 0, abi-split 0), and restores main's rust gitlink after a merge slip. --ci host 43/43 and toolkit_ 4/4 exit 0. The fast-tier A/B was skipped for disk; the extra wide reds were a different three each run, each green alone and each covered by an existing filed issue, none on a GUI path. Landing.

@Japabu
Japabu added this pull request to the merge queue Sep 26, 2026
Merged via the queue into main with commit e4e540d Sep 26, 2026
2 checks passed
Japabu added a commit that referenced this pull request Sep 26, 2026
#528 (e4e540d) published toyos 0.16.0 and toyos-window 0.17.0 for the iced/
winit work, the same versions this branch had already set for its own ABI
change, so the two collide on crates.io. toyos-abi 0.15.0 is still free (main
never moved it past 0.14.0), so it stays; toyos moves to 0.17.0 and
toyos-window to 0.18.0, past main's landed versions, with every in-tree pin
and lockfile re-locked behind them (`cargo update -w` in toyos/, userland/,
userland/libc/, tests/toyos-rust-tests/ and tests/iced-counter/ — the five
workspaces a tracked lockfile of theirs names toyos or toyos-window).

Conflicts, each the two branches' additions side by side:

- src/build.rs: `ALL_CONFIGS` gained `tests/toolkitcase/system.toml` (main)
  and `tests/updatecase/system.toml` (this branch); both kept, alphabetical.
- tests/toyos-rust-tests/Cargo.lock, userland/Cargo.lock: re-locked rather
  than resolved by hand, so `swap`/`update` (this branch's new programs) and
  main's iced/winit additions both land, and the stale `toyos-abi` 0.1.0/
  0.2.0 registry entries main's fork-pin fix retired stay gone.

`rust`'s gitlink is unchanged (`git ls-tree HEAD rust` still names
80ea645f, main's own) — this branch never moved it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Japabu added a commit that referenced this pull request Sep 26, 2026
…528)

Conflicts, each resolved to carry both sides:
- bootloader/src/main.rs: the boot map's ROOT_* names with #530's update imports.
- src/image.rs: main's slotted layout, with `arch` threaded into
  create_boot_image and create_esp_volume for the removable loader's path.
- src/build.rs: main's Parts, shipped_parts and signing, keyed per
  architecture: loader_key takes the arch, the embedded key and the floor
  scope; root_image_key the plan (config and arch) and the key; build()
  writes image_for(plan.arch).
- tests/common/qemu.rs: a test's own firmware variables file where it names
  one, and otherwise the architecture's pflash.
- toyos-window is 0.19.0, past main's 0.18.0, since its scanout drain moved
  into arch modules here; both lockfiles take main's and that version.
- tests/common/update.rs names the x86-64 plan and image.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Japabu added a commit that referenced this pull request Sep 26, 2026
#528's tests/iced-counter locks the path toyos-window, which the merge moved
past main's 0.18.0.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Japabu added a commit that referenced this pull request Sep 26, 2026
main landed #528 (iced, `toyos::wake`) and #530 (self-update), which took
toyos-abi 0.15.0, toyos 0.17.0 and toyos-window 0.18.0.

- SDK versions: past main's, to toyos-abi 0.16.0, toyos 0.18.0 and
  toyos-window 0.19.0; every tracked lockfile re-locked in its own workspace
  with `cargo update -w`, tests/iced-counter's among them.
- toyos/src/lib.rs: both `power` (this branch) and `wake` (main).
- userland/logd/src/main.rs: main's hunks move logd's `Own`/`Theirs` bell
  onto `toyos::wake`; this branch deleted that machinery (logd's own lines
  are records in its ring), so they have nothing to land on and this side is
  kept. `toyos::wake` stays for its other users.
- userland/soundd/src/say.rs: deleted here; main's hunk moves its wake pipe
  onto `toyos::wake`, and soundd's mix thread writes a lane here instead.
- rust: main's pin is still 80ea645f83b, which this branch's pin already
  merges.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Japabu added a commit that referenced this pull request Sep 27, 2026
…, #531, #534) into the Netstack3 netd

Two conflicts. tests/common/origin.rs: main added `volumes` to the imports
this branch had split to name `segment`'s NEIGHBOUR and NEIGHBOUR_MAC; both
kept. userland/Cargo.lock: main's lock taken whole and re-locked against this
branch's manifests (`cargo metadata`), which adds the mirrored crates and their
dependencies and drops smoltcp and its defmt.

The rust gitlink fast-forwarded to main's fbf6ad143d8; this branch's pin
(7a809b7591f) is its ancestor, and the branch made no fork commit of its own.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
@Japabu
Japabu deleted the wt/toyos-guiplat branch September 28, 2026 09:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant