Added
Native processes can have threads.
SXN_SYS_THREAD_CREATE,SXN_SYS_THREAD_EXITandSXN_SYS_THREAD_EXIT_CODE(sxn_thread_create,sxn_thread_exit,sxn_thread_exit_code): a waitable handle per thread, and the last thread's exit ends the process. Threads of one process run on several cores at once: unmapping a view other cores may hold sends them a TLB shootdown IPI, and its pages are freed only once they have flushed. Seedocs/kernel/THREADS_ROADMAP.md.Each native thread has its own
%fsand%gs.SXN_SYS_SET_THREAD_BASE(sxn_set_thread_base,SXN_THREAD_BASE_FS/_GS) sets the calling thread's segment base, the anchor of thread-local storage and of a future Win64 TEB. Seedocs/kernel/KERNEL_NATIVE_API.md.Native threads can sleep on a word of memory.
SXN_SYS_WAIT_ADDRESSandSXN_SYS_WAKE_ADDRESS(sxn_wait_address,sxn_wake_address): a futex /WaitOnAddressfor building locks, keyed by process and address. Seedocs/kernel/KERNEL_NATIVE_API.md.POSIX programs can use threads.
pthread.h(create/join/detach, mutexes, condition variables, once, keys),sched.hand__threadvariables;errnois per thread, the heap and stdio lock,execends the other threads.pthread-testsmoke. Seedocs/kernel/THREADS_ROADMAP.md.AHCI (SATA) disk driver with DMA.
kernel/ahci.cppregisters SATA disks asahciN, and QEMU now attachesdisk.imgto the q35 AHCI controller by default (SAVANXP_DISK_BUS=ideorrun_qemu.py --disk-bus idekeeps legacy IDE). Up to 256 sectors per command: a 390 KB copy moves in 0.33 s instead of 1.99 s. Seedocs/kernel/AHCI.md.The Command Prompt, the first SUN application.
/bin/console(Start menu or Ctrl+Alt+T) runs/bin/sh --console 3as a separate process over pipes: an 80x300 buffer with a scroll bar,doskeyline editing and history, and Ctrl+C that ends the foreground job. In that modeshprints<cwd>>, separates commands with;and hasstart. Seedocs/desktop/CONSOLE.md.SUN windows choose their size, title and icon, and present rectangles.
sxnwm_submit_rects,sxnwm_request_size,sxnwm_check_resize,sxnwm_close_requested,sxnwm_set_title; a native program's.sxresis compiled in as<name>.sunres.h(gen_sxe_resources.py --native-program).SUN gets
CreatePipeandCreateProcesswith chosen handles.SXN_SYS_PIPE_CREATE(sxn_pipe_create) andSXN_SYS_SPAWN_EX(sxn_spawn_ex: stdio plus up to four handles at 3..6, nothing else), andSXN_SYS_TERMINATEnow ends any descendant. Seedocs/userland/SUN.md.The Start menu shows ▲/▼ arrows when its list does not fit. As in Windows 98, resting the pointer on a strip scrolls the list, and the arrow at an end is greyed. The scroll bar arrow is now shared as
sxchrome_draw_arrow.Native programs have a heap.
system/runtime/sxn_runtime.c, linked into every native target (CMakeNATIVEandbuild-user.sh --native), mapsmalloc's arenas through SXN, somallocworks past the 256 KiB bootstrap arena. Seedocs/userland/NATIVE_HEAP.md.SXN_SYS_SPAWN_STDIOandSXN_SYS_SET_NONBLOCKING. A native process can start a child that gets only stdio, and make a pipe or device stop blocking (sxn_spawn_stdio,sxn_set_nonblocking);sessiondspawns that way.SXN_SYS_PROCESS_QUERYtells a native process about any other. Parent, whether it is running or ended (with its exit code), handle count and name (sxn_process_query).SXN_SYS_WAIT_MANY, and pipes and devices can be waited on. A native process waits for any of up to 16 handles (sxn_wait_many); a stream opened for reading counts as signaled while a read would not block, for native and POSIX waits alike. Seedocs/kernel/KERNEL_NATIVE_API.md.sessiond, the session manager. A native processinitnow starts instead ofwindowd: it startswindowd, then the desktop and Program Manager, restarts the desktop, and restarts the whole session whenwindowddies;session-smokekills both and checks they come back. Seedocs/desktop/DESKTOP_ARCHITECTURE.md#the-session-manager-sessiond.SXN_SYS_TERMINATEends a child. A native process can end a process it spawned, with the exit status itswaitpidwill report (sxn_terminate); any other pid is refused. Seedocs/kernel/KERNEL_NATIVE_API.md.Ports, and POSIX on the native floor.
SXN_SYS_PORT_CREATE,_CONNECTand_ACCEPTlet a process find a service by name (two pipes per connection),SXN_SYS_PIPE_SEND/RECEIVE_HANDLEpass handles natively, and POSIX processes can make the native object calls. Seedocs/kernel/KERNEL_NATIVE_API.md.Native calls for handles, devices and time.
SXN_SYS_CLOSE,_DUPLICATE,_READand_WRITE(pipes and devices),_OPEN_DEVICEand_DEVICE_CONTROL(a device by bare name, the same control codes asioctl) and_CLOCK, withsxn.hwrappers;native-testcovers them.Window roles and global hotkeys for the shell.
gfx_window_open_roleopens apanel(a reserved screen edge) or apopup(dismissable on an outside press);SAVANXP_WM_SHELL_REGISTER_HOTKEY(shell protocol v4) routes a key to the shell. Seedocs/desktop/DESKTOP_ARCHITECTURE.md.Web Viewer (
/bin/webview), a local HTML viewer in the spirit of IE 1.1. Opens.html/.htmfiles from disk, renders headings, paragraphs, lists, rules and entities in vertical flow, and ships with/disk/welcome.htmlas its sample page.Web Viewer gains its browser chrome. An address bar with Go (file paths,
file://included), Back/Forward buttons with a history of visited paths on the buttons, the Go menu and Alt+Left/Right, plus/disk/about.htmlas a second sample page.Web Viewer fetches
http://pages from numeric IPs, follows links and redirects, and shows source. Clickable blue underlined links,View Sourceon Ctrl+U,3xxfollowing for same-scheme locations, and honest errors where DNS or TLS would be needed.Web Viewer paints a first CSS. Tag rules from
<style>plusstyle="", over colour, background, alignment, bold (double-strike), underline and a two-face size;bodyrules and<body>attributes set the page colours,<font color>works.Web Viewer resolves names through DNS. A minimal A-record client over UDP (numeric IPv4 stays a local fast path), with CNAME chasing, NXDOMAIN told apart, and
dns://plus--dnsoverrides pointing it at a test server.The taskbar shows a W2K-style clock that opens a calendar. A sunken
HH:MMreadout (RTC in UTC, uptime fallback) whose click toggles a popup with the month grid (today highlighted) and a liveHH:MM:SS, closed by toggle or outside click.Manual date/time setting (
/bin/date,SET_REALTIME). A new syscall writes the CMOS RTC (UTC, years 2000..2099, leap-aware validation);dateprints it bare and sets it asdate YYYY MM DD HH MM SS, anddate-smokecovers set, reject and restore.Automatic time sync (
/bin/ntpsync,ntp-smoke). A one-shot SNTP client over UDP (numeric IPs, transmit +rtt/2, sane-range validation) that sets the RTC from the server, with a host fixture and a closed-port failure path in the smoke.Paint (
/bin/paint), in the Accessories group. A drawing sketchbook with the toolbox on the left, the colors on top and the canvas over a status bar; pencil, line, rectangle and ellipse tools, 16 color swatches and 24-bitBI_RGBBMP open/save../build.sh smoke paint-smokecovers the geometry plus a bit-exact save/load round-trip through--selftest.Paint gains brush, eraser, picker and undo. The brush stamps ellipses along the drag (
+/-size it), the eraser paints the background, the picker reads the pixel under the cursor, and every stroke pushes one of 8 document snapshots forEdit > Undoand Ctrl+Z.tools/shoot.sh --scenario paintdrives tool switching by keyboard and asserts the status bar on screen.Paint gains a flood-fill bucket. Clicking pours the current color into the exact-match 4-connected region under the cursor (iterative, with a visited set, so it always fits and always terminates); like every stroke it pushes undo first. Covered in
--selftest(frame intact, no leaks) and in thepaintvisual scenario.libsximg.so.0.4, a PNG decoder the tree builds and installs in/disk/lib. Reference implementation (no third-party code): inflate written from RFC 1951 plus the 8-bit truecolor/RGBA non-interlaced subset with all five filters, zlib-checked, alpha composited over white.savanxp-sximg-testproves the engine on the host (stored, fixed and dynamic blocks, RGB/RGBA, rejections); Paint maps it and opens.pngthrough the same load path as BMP, with/disk/paint-test.pngas its guest fixture.--guiexternal applications link the window-chrome module.tools/build-user.shwas missingsxchrome.c, which the toolkit needs since the system 3D edges moved out of it, so no--guibinary outside the tree could link.GitHub Actions CI (
.github/workflows/ci.yml) on every push and pull request. In anarchlinux:latestcontainer it runs./build.sh build,./build.sh test, the Doom persistence check and thesmoke,native-test,windowd-smokeandsxgui-smokeQEMU scenarios.<dlfcn.h>:dlopen,dlsym,dlclose,dlerroranddladdrfor PIE programs. Per-handle scopes withRTLD_LOCAL/RTLD_GLOBAL/RTLD_NOLOAD,dlsymthrough the handle'sDT_NEEDEDtree, constructors run, and a faileddlopenrolls back with the reason indlerror();dlclosenever unmaps. Newdltestscenario, also run bysmoke. Step 1 of the Xash3D FWGS plan.
Changed
Every house icon is redrawn in a Windows 2000 look, each size drawn on its own: the system catalog, Shut Down, the media player, the Doom and Celeste ports and the tray speaker. The Tango file-type icons are unchanged.
icon_file=now takes one PNG per size (icon_file=icon.png,icon-32.png). Seedocs/desktop/ICON_STYLE.md.The Start menu draws each program's own 16x16 icon (
progman_item_icon_small) instead of shrinking its 32x32 one; a binary with only a large icon is still shrunk.Static programs map their ELF headers.
linker.ldputs them at0x400000with the text right after, sosx_image_baseis the header for every program; editing the script now relinks every static program.The kernel schedules threads, not processes.
process::Threadowns the saved context, kernel stack, FPU state and every wait; a process is the container. Each process has exactly one thread, so nothing visible changes yet: phase 0 ofdocs/kernel/THREADS_ROADMAP.md.Disk writes are written back in the background. Physical disks queue writes in the block layer (
block::write_cached, ordering points viablock::flush) and the idle task drains them one bounded step at a time, so a write syscall no longer freezes the system for the device's duration (Doom's quit: 8–13 ms in write syscalls, was 247–293). Writes are durable once drained;sync, shutdown and reboot wait for it (block::sync_all). Seedocs/kernel/BLOCK_WRITEBACK.md.Disk writes are ordered by explicit flushes.
block::write_cachedandblock::flushjoinblock::write; an SxFS commit flushes at its four ordering points instead of after every write, and file writes reach SxFS in pieces of up to 64 KiB instead of 256 bytes. Doom's quit spends 247 ms inside SxFS on virtio-blk instead of 522 ms. Seedocs/fs/SXFS_JOURNAL.md.The libc
FILEbuffer is 4 KiB, allocated on first use instead of embedded in the stream pool, sofopen("w")plusfprintfgrows a file in fewer, larger writes.SxFS commits write only the metadata sectors that changed. The journal logs a sparse set (
SXFS_JOURNAL_KIND_SPARSE) instead of a full metadata copy, sofscheck'sbytes_per_commitdrops from 1575424 to about 3872 and saving a file no longer freezes the system for seconds (Doom's in-game quit: 70.7 s → 0.53 s on IDE). Format stays v2; old full journals still replay, and mount validates home metadata after the replay. Seedocs/fs/SXFS_JOURNAL.md.The taskbar's Start label uses the caption font. "Start" is drawn in
SX_FONT_UI_TITLE, the title-bar face, standing in for the bold label of Win9x.The visual harness opens programs through the Command Prompt.
Session.run()andtaskbar-smoketypestart <program>; exitinstead of walking Start menu > Program Manager;shoot.sh --scenario consolereplacesshell.AltGr never triggers a hotkey. On layouts where it is Ctrl+Alt, AltGr plus a letter stays a character.
Program Manager no longer opens with the session.
sessiondstarts onlycompositord,windowdanddesktop; Program Manager is opened from the Start menu (System), andsession-smokeasserts it is not started.The desktop's text is Wine's MS Sans Serif, crisp and 1-bit.
SX_FONT_UIis its hand-drawn 13px bitmap strike instead of antialiased Noto Sans, so lines are 13px tall and layouts tighten;genfont.py sfdbakes it. Noto now only draws the boot wordmark. Seedocs/desktop/UI_FONTS.md.malloc's page source is a replaceable hook. The arenas past the bootstrap one come fromsx_heap_pages_map/sx_heap_pages_unmap(weak,savanxp/libc.h), so a native runtime can supply them;native-testasserts a native program gets the bootstrap arena only. Seedocs/userland/NATIVE_HEAP.md.The platform services live in
system/.compositord,windowdandsessiondmoved out ofsubsystems/posix/userland/intosystem/<service>/, built bysavanxp_system_service(cmake/SystemServices.cmake);compositor_protocol.hmoved tosystem/include/.Application frames go straight to
compositord. The submit event in the WM welcome iscompositord's; requests getwindowd's own event, asked for withSAVANXP_WM_HELLO_REQUEST_EVENT(older clients still work, their requests seen onwindowd's tick).compositord-statsreplaceswindowd-stats. A pipe's handle queue holds eight handles instead of four.compositordcomposes the desktop.windowdpaints only its own surface (frames, the Alt+Tab switcher, the fallback background) and commits the scene;compositordmaps the client surfaces, composes, presents and draws the cursor (compositor_protocol.hv5: ATTACH, DETACH, COMMIT). Frames now pace on the GPU's present event:shoot.sh --scenario spinon virtio-gpu went from ~61 to ~970 fps. Seedocs/desktop/DESKTOP_ARCHITECTURE.md#composition-in-compositord.compositordis a session service.sessiondstarts it beforewindowd; it allocates the display memory and opens the portcompositord, whichwindowdconnects to (compositor_protocol.hv4). Either one ending restarts the whole session;windowdno longer respawnscompositord. Seedocs/desktop/DESKTOP_ARCHITECTURE.md, phase 4.windowdis a native process. It speaks only the SXN API:windowd_sys.hmaps the POSIX calls of its sources onto it (windowd_sys.c), text goes to/dev/serial. Seedocs/desktop/DESKTOP_ARCHITECTURE.md, phase 3.compositordconnects towindowdthrough a private port.windowdnames the port oncompositord's command line and hands over the display section as a handle, instead of a fork with descriptors 3, 4 and 5 (compositor_protocol.hv3).Closing a window asks the program; a hung one gets an End Program dialog. The X and Alt+F4 request the close and the runtime ends a program that does not handle it (
gfx_handle_closeto answer yourself);windowdnever kills. A program still running 5 s later shows "(Not Responding)" and the desktop offers End Now / Wait. Seedocs/desktop/DESKTOP_ARCHITECTURE.md#closing-a-window.The shell role goes to a process the session started. The desktop asks for it with
gfx_open_shell(SAVANXP_WM_HELLO_SHELL);windowdgrants it only when the client's parent is its own parent or itself, one at a time. A client whose WM went away is asked to close.Programs connect to
windowdfor a window (WM protocol v5). A client opens the portwindowd, sends a hello with the launch flags its own.sxedeclares, and gets its handles with the welcome;gfx_desktop_launch*now spawns the program in the caller, andwindowdno longer forks clients, keeps a launch queue or uses fixed descriptors (surface header v5). Native clients usesxnwm_connect. External programs must be rebuilt. Seedocs/desktop/WM_SUBSYSTEM.md#descriptor-budget.Each window publishes its own title, icon, accent and style. The runtime reads the program's
.sxeatgfx_open(savanxp_wm_presentationin the surface header);windowdreads no binary for it and its per-path table is gone. External programs built earlier show their file name until rebuilt.compositordis a native process. It speaks only the SXN API -- the GPU as a device with control codes, its pipes through native read/write -- and no POSIX. In-tree programs can be built native withNATIVEincmake/UserPrograms.cmake(tools/stamp_osabi.py).Ctrl+Esc opens the Start menu, Ctrl+Shift+Esc opens Task Manager, and Alt+Tab shows its own switcher. The keys are hotkeys the desktop registers (a fullscreen app leaves fullscreen first); the switcher is a box with the icon and title of the next window.
The shell is one
/bin/desktopprocess. Wallpaper, taskbar, Start menu and the volume, clock and keyboard-layout popups are windows of it instead of six processes, so a popup opens without a launch;windowdno longer knows any of them, its fallback background is a solid colour, and it restarts a desktop that exits. The Start button stays sunken while the menu is open.New
app-paintandapp-webviewicons. Paint shows a palette with a brush and pencil in a cup, after the classic Windows Paint icon; Web Viewer is now a shaded globe.The system edition is centralized as
SAVANXP_EDITION. System Properties reads it frominclude/shared/version.hinstead of a hardcoded string, and the boot splash and the desktop stamp now show it alongside the system name.The native syscall dispatcher is a separate kernel unit. It now compiles as
kernel/native_dispatch.cppagainst the public process boundary instead of sharingprocess.cppinternals; syscalls and the POSIX fallback behave as before.The kernel has an
sx::native surface. User-memory copy, current-process identity and errors live once inkernel/sx.cpp(include/kernel/sx.hpp); the native dispatcher speakssx::and theprocess::wrappers keep drivers compiling untouched.The POSIX dispatcher is a separate translation unit. It now compiles as
subsystems/posix/kernel/posix_dispatch.cppagainst the publishedprocess::translation boundary instead of sharingprocess.cppinternals; numbers, errors and the blocking protocol behave as before.The native ABI is standalone, with its first guest test.
SXN_SYS_EXITgives native processes their own minimal lifecycle viasx::exit_current, the< 0x1000POSIX fallback is cut (any non-SXN number is ENOSYS), andsdk/nativetestproves it from the guest over raw syscalls (./build.sh smoke native-test, built withtools/build-user.sh --native).Neutral
sx::sync primitives. Event, timer and semaphore constructors and signals live inkernel/sx.cpp; theprocess::translation keeps flag parsing, access masks and handle allocation with identical errors and wakes.Native spawn/wait (
SXN_SYS_SPAWN,SXN_SYS_WAITPID). Backed by the publishedprocess::machinery withwaitpid_childas the shared core behind both WAITPID paths;sdk/nativetestself-spawns and checks ECHILD, reaped pid and child status.Native event/section/wait syscalls plus the
sxn.huserland surface.SXN_SYS_EVENT_CREATE/SET/RESET,SXN_SYS_WAIT_ONEandSXN_SYS_SECTION_CREATE/MAP_VIEW/UNMAP_VIEWride the published cores over the shared handle table; header-only typed wrappers ininclude/sxn/sxn.hneed no tool or link change, andsdk/nativetestproves cross-process sync plus shared memory through them. Native spawn clones the caller's handle table, so inherited handles arrive (POSIX spawn still takes stdio only).First native window, proven inside real
windowd.sdk/nativedemopaints a v4 client surface using SXN syscalls only (output-only: the input pipe stays unread) and a newwindowdselftest launches it through the unchanged fork/dup2/exec path, composes it and samples the marker from the framebuffer (./build.sh smoke windowd-smoke).Native input ring plus the
sxnwm.htoolkit seed.windowdsniffs EI_OSABI at launch and routes input records to a shared ring on fd 7 for native clients (same 32-byte records, drop-when-full, wake signaled); header-only attach/submit/composed-wait/drain over a context struct, used by a demo that answers a key with green, proven end to end through the real router.Native widgets with scripted interaction. Label, Button and Field over
sxnwm.hwith a hand 5x7 font ininclude/sxn/sxnwidgets.h;sdk/nativewidgetscounts button clicks and typed text into state squares, and the selftest clicks, types and sends Esc through the real router, sampling the squares from the framebuffer.Real PS/2 keys into a native form, native apps in the launcher.
windowd --hw-native-test(scenarionative-hw-smoke) drains/dev/input0through the production path intonativewidgetswhile the host tapsh,i,Escover QMP, asserting the typed square from the framebuffer; both native demos ship.sxreswith a menu category andprogman --selftestasserts the scan lists them.POSIX translation out of the kernel. The 33 POSIX-only process bodies (fds, fs, sockets, pipes, timers, semaphores, fork/kill, poll) move to
subsystems/posix/kernel/posix_translation.cpp, sharing kernel machinery through the internalkernel/process_detail.hpp; lifecycle, scheduler and shared cores stay inkernel/process.cpp.docs/userland/NATIVE_APPS.mdguides native programs with examples.The kernel stops including the POSIX SDK. The shared wire contract moves to
include/abi/savanxp_abi.h; the SDK keeps the POSIX vocabulary and includes it.kernel/andinclude/kernel/now depend on no userland header, and a layout guard keeps it that way.The current directory leaves the process state. Each subsystem now declares its per-process private state and the kernel reserves it without reading it, so
Processno longer carries a POSIXcwd; a native process declares zero bytes. Newcwdtestasserts chdir/getcwd, relative resolution, fork inheritance and exec preservation.The kernel no longer parks processes for poll(). The timer tick walked the process table re-evaluating POSIX poll requests; now a subsystem hook receives any process parked with a deadline and decides what it was waiting for. The request and its evaluation move to the POSIX subsystem's private state, taking 32 KiB of unconditional kernel memory with them.
POSIX signals leave the process state. The kernel's pending-signal flags were written and never read — this kernel has no signal delivery — so they existed only to name POSIX signals. The signal vocabulary moves to the POSIX subsystem;
killandwaitpidbehaviour is unchanged.The smoke runner no longer leaves a QEMU behind when it is killed. Its cleanup runs in a
finally, which does not run if the process is killed, so an aborted scenario used to leave a TCG machine spinning on a core indefinitely. QEMU now getsPR_SET_PDEATHSIG. Verified A/B: killing the runner mid-scenario leaves zero orphans with the fix and one without it.A wedged disk is reset instead of failing the operation. A long write (390 KB, ~16,000 sectors, five minutes) used to die on a single exhausted status poll, with nothing in the whole chain retrying. Each command is now re-issued whole up to three times, and if those all fail the controller is reset by software and the command is retried again. Intermittent
progman-smokecopy failures on a loaded host should stop with it.The error space belongs to the kernel. Errors returned by the kernel are now
sx_status/SX_E*rather thansavanxp_error_code/SAVANXP_E*, with the POSIX names kept as aliases so existing programs are unaffected. The values are unchanged, so no userland-visible behaviour moves with this.Native IPC proven over sections plus events.
sdk/nativetestruns a 50-round ping-pong ring between parent and child with strict alternation (same shape as a WM submit/retire channel, no new syscalls); the windowed-client design is rendezvous by inheritance, withwindowdnative attach as slice 9 (seedocs/kernel/KERNEL_NATIVE_API.md).Neutral
sx::sections, views and waits. Section constructors, view map/unmap with the W^X and mask policy, and wait satisfaction/consumption live inkernel/sx.cpp; theprocess::translation keeps flag parsing, file checks, handle allocation and clock/parking orchestration. One shared integer handle table per process, enforced by granted access, is the decided handle model (seedocs/kernel/KERNEL_NATIVE_API.md).
Removed
The icon generators are no longer in the repository (
tools/gen_desktop_source_art.py, the player'sgen_icons.py): the checked-in PNGs are the source of the art, and thesavanxp_desktop_source_arttarget exists only where a local copy of the generator does.Eight redundant test programs.
spawnloop,pipestress,waittest,errtest,demo,seektest,renametestandtruncatetestare gone:sh,init,mv,truncateand thesmokesuite already exercise the same paths. An existingbuild/disk.imgkeeps the stale copies.SDK examples that duplicated in-tree programs.
sdk/errdemo(same assdk/hello),sdk/udptestandsdk/tcpgetare gone; the in-treeudptestandtcpgetremain.shellapp, the old terminal window. The Command Prompt (/bin/console) replaces it in the Start menu and Program Manager, and the legacyicon=shellalias now points at it. An existingbuild/disk.imgkeeps its stale/disk/bin/shellappuntil it is removed by hand.The BusyBox port.
vendor/busybox,vendor/busybox-portand/bin/busyboxare gone;ls,cat,echo,mkdir [-p],rm [-rf],mv,cp [-r],ps,true,falseandsleepare small in-tree programs (subsystems/posix/userland/coreutils).The Task List. The taskbar, Alt+Tab and Task Manager cover switching, restoring and ending tasks (see
docs/desktop/DESKTOP_ARCHITECTURE.md)./bin/shellui,/bin/taskbar,/bin/startmenu,/bin/volumepopup,/bin/clockpopupand/bin/kbdlayoutpopup, now part of/bin/desktop, and the four shell launch flags (SAVANXP_DESKTOP_LAUNCH_FLAG_TASKBAR_POPUP,_START_MENU,_VOLUME_POPUP,_CLOCK_POPUP).The Haxe native experiment is removed.
subsystems/native(builder, SDK, apps, smoke scenarios) is gone and userland is C on the POSIX SDK only. The neutralsavanxp_native_abi.hrouting stays reserved for the future NT-style kernel API (seedocs/userland/SYSTEM_LAYERING.md).
Fixed
clearin the Command Prompt no longer loses the prompt. The clear now travels in band (ESC [ 2 J) on the output pipe instead of the control channel; theclscontrol line is gone. The prompt lands on the top row, with no blank line before it, as afterclsin cmd.A process ended by
SXN_SYS_TERMINATEno longer reads as running. When it was running on another core,SXN_SYS_PROCESS_QUERYreported it running until that core tore it down; it now reports it ended, with its status, as soon asTERMINATEreturns.Windows opened during a fullscreen app get the desktop's size. A taskbar, Start menu or window created while the screen ran in the 640x400 fullscreen mode kept that geometry after the restore, or was refused;
windowdnow lays every window out on the native mode (layout_display).Paint no longer overwrites PNG files or resizes what it opens. Save on a PNG asks for a
.bmpname instead of writing BMP bytes into the.png; opened images keep their own size; top-down BMPs load; a failed Save As keeps the old name; no-op strokes push no undo step.IDE flushes reach the drive.
FLUSH CACHEwas written while the drive was still busy with the write before it, and dropped; it is now issued once BSY clears, so a commit is on the medium when it returns.waitpidreturns to the parent that is waiting, not to whoever waits first. A process inwaitpid(-1)(initandsessiondalways are) took any process's exiting child, so a shell waiting for its command in the graphical session waited forever.Window titles are sharp. RetroSans was baked at 18px, off its 17px pixel grid, so over a third of every caption's pixels came out grey.
windowd-statslines are back. Sincewindowdbecame native its clock read was a POSIX call that failed, so every frame was discarded as unmeasured.A POSIX program started by a native one has its POSIX state. Spawning kept the parent's subsystem state even when the child's image is of another subsystem, so
pollfailed in it.The kernel's text console no longer stalls the machine when it scrolls. It repainted the whole framebuffer for every line; it now writes only the glyph pixels that changed, which matters when it takes the screen back from the desktop.
Leaving fullscreen right after
compositorddied left the screen in the low mode. A mode change is now the first to notice a dead daemon and recovers it, as present does; andwindowdkills acompositordthat does not confirm its shutdown instead of waiting forever.Minimizing a window from the taskbar left the next window's caption inactive. The window below became active but kept its gray caption until something else repainted it;
taskbar-smokenow asserts it.A clean checkout builds again.
tools/check_shared_libs.py(run by every./build.sh build),tools/glyphs.py(sxgui-smoke) andtools/qmp_native_hw.py(native-hw-smoke) were caught by thetools/*rule in.gitignoreand had never been committed.tools/verify_doom_persistence.shruns on any host. Its scratch directory was created under a machine-specific/tmp/opencode; it now uses$TMPDIR(default/tmp)../build.sh testbuilds and passes again. The gfx2d, audio and ccleste-wav host tests findabi/savanxp_abi.h, the removednative-port-layout-testis no longer registered, andsmoke-runner-layout-testreadsdocs/kernel/KERNEL_NATIVE_API.md.The loader no longer holds a descriptor per library, nor leaks a failed load's segments. The handle of each executable segment stayed open for the life of the process, and a load that failed after mapping left its views in place.