feat(launcher): Process.*, Http.save_to/received/expected, App.window_hide/show

Process.spawn/poll/kill/free - non-blocking child processes with no shell: posix_spawn on
macOS (process.ll), CreateProcessW with MSVC-quoted arguments and no console window on
Windows (process_win.ll), linked only when a program uses Process.*.

Http.save_to streams a response body into a file (NSURLSession with a run-time delegate
class on macOS, the WinHTTP read loop on Windows); Http.received / Http.expected report
progress while it is pending. Freeing a pending request cancels it and parks the slot
until the worker has finished.

App.window_hide / App.window_show take the game's window off the screen and back without
closing it; the run goes on while hidden. Docs, examples, tests and a changeset.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-17 13:32:23 +03:00
parent c1db0d71ed
commit 43d5eb5b88
31 changed files with 89274 additions and 86727 deletions

View file

@ -4,4 +4,4 @@ title: App
order: 48
---
The running application, as distinct from its window. Today that is the boot splash: the runtime raises it before <code>main</code> from the game's asset pack, and <a href="app-splash_hide"><code>App.splash_hide</code></a> takes it down when the game has something to show instead.
The running application, as distinct from its window. Today that is the boot splash: the runtime raises it before <code>main</code> from the game's asset pack, and <a href="app-splash_hide"><code>App.splash_hide</code></a> takes it down when the game has something to show instead. <a href="app-window_hide"><code>App.window_hide</code></a> and <a href="app-window_show"><code>App.window_show</code></a> take the game's own window off the screen and bring it back without closing it — a launcher stepping aside while the game it started runs.

View file

@ -0,0 +1,35 @@
---
id: app-window_hide
name: App.window_hide
category: app
kind: namespace-method
tokens: App.window_hide
sig: App.window_hide() -> void
tip: Take the game's window off the screen.
order: 3
ns: App
member: window_hide
---
Takes the game's window off the screen without closing it: its GL context or Vulkan surface, its size and its contents are kept, and the program goes on running — a hidden window does not end the run. <a href="app-window_show.html"><code>App.window_show</code></a> brings it back. It is how a launcher steps aside while the game it started with <a href="../process/process-spawn.html"><code>Process.spawn</code></a> runs.
Keep the frame loop going while hidden so the child can be polled, but there is nothing to see: skip the drawing, and throttle the loop yourself — a hidden window is not paced by the display, so an unthrottled loop spins. It does not touch the boot splash (<a href="app-splash_hide.html"><code>App.splash_hide</code></a> does). Safe to call when there is no window yet, and twice. Headless there is no window and the call lowers to nothing.
```ludic skip
program Launcher {
var game: int = -1
function play() -> void {
game = Process.spawn(game_path(), new []string)
if game >= 0 { App.window_hide() }
}
handler Watch phase Update {
if game >= 0 and Process.poll(game) != -1 {
Process.free(game)
game = -1
App.window_show()
}
}
}
```
<code>orderOut:</code> on macOS; <code>ShowWindow(SW_HIDE)</code> on Windows, which also forgets any key held as the window went.

View file

@ -0,0 +1,26 @@
---
id: app-window_show
name: App.window_show
category: app
kind: namespace-method
tokens: App.window_show
sig: App.window_show() -> void
tip: Bring the game's window back.
order: 4
ns: App
member: window_show
---
Puts a window hidden by <a href="app-window_hide.html"><code>App.window_hide</code></a> back on screen, in front and focused, as it was. Safe to call on a window that is already showing, when there is no window, and headless, where it lowers to nothing.
```ludic skip
program Demo {
entry {
App.window_hide()
wait_for_the_game()
App.window_show()
}
}
```
On macOS <code>makeKeyAndOrderFront:</code> and the application is activated. On Windows <code>ShowWindow(SW_SHOW)</code> and <code>SetForegroundWindow</code>; Windows may refuse the focus to a program that is not in the foreground, in which case the window comes back and its taskbar button flashes instead.