Module gui::gui_headless
GUI: the headless backend.
A complete struct GuiBackend (gui_backend.h) that keeps windows in memory only: nothing is shown, presenting just counts frames, the clipboard is a process-local string, and the clock is virtual — it moves only when gui_headless_advance() moves it (or when an event loop waits: a pump with a timeout and nothing queued advances the clock by that timeout instead of sleeping). That makes everything above the backend — multi-window event routing, timers, animation frames, the widget toolkit — testable deterministically, on any target, with no display server; it's also how to render GUI frames on a server.
gui_use_headless(); // before the first window
struct GuiWindow win = GuiWindow::create("t", 200, 100);
gui_headless_click(&win, 10.0, 10.0); // MOUSE_DOWN + MOUSE_UP
gui_headless_type(&win, "héllo"); // KEY_DOWN/UP per character
while (win.poll_event(&ev)) { ... }
Events injected for a window arrive through that window's poll_event() (or GuiApp's loop) exactly as a platform backend's would, with windowId, timeMs and double-click counts filled in. Window operations behave like a cooperative window manager: set_size() posts GUI_EVENT_RESIZE, set_position() GUI_EVENT_MOVE, focus() FOCUS_OUT to the old focus window and FOCUS_IN to the new one, request_close() GUI_EVENT_CLOSE.
Functions
| gui_headless_backend | The headless backend's table. |
| gui_headless_requested | 1 if $SAFEC_GUI_BACKEND is "headless" (always 0 where there is no environment: WebAssembly, bare metal). The platform backends' gui_platform_backend() check it, so any GUI program can be run without a display (CI, servers) by setting SAFEC_GUI_BACKEND=headless. |
| gui_use_headless | Installs it (gui_set_backend). Returns 0 if a window already exists. |
| gui_headless_advance | The virtual clock, in milliseconds (starts at 0). |
| gui_headless_now_ms | |
| gui_headless_set_scale | The scale factor hiDpi windows created from now on get (default 1.0). |
| gui_headless_set_primary_mod | GUI_MOD_* the primary modifier reports (default GUI_MOD_CTRL). |
| gui_headless_inject | Queues 'ev' for 'win' as if the platform had delivered it. Returns 0 for an offscreen window. |
| gui_headless_mouse_move | Conveniences built on gui_headless_inject (coordinates in buffer pixels). |
| gui_headless_mouse_down | |
| gui_headless_mouse_up | |
| gui_headless_click | |
| gui_headless_scroll | |
| gui_headless_key | KEY_DOWN then KEY_UP; 'codepoint' (0 for none) rides on the KEY_DOWN. |
| gui_headless_type | One key press per UTF-8 character of 'text'. |
| gui_headless_resize | The user resizing the window to a new logical size. |
| gui_headless_close | The user clicking the close button. |
| gui_headless_present_count | How many times 'win' was presented. |
| gui_headless_cursor | The cursor the window last asked for (GUI_CURSOR_*). |