x.multiwindow #
x.multiwindow
x.multiwindow is the low-level multi-window layer used by the gg multi-window facade. It owns native window lifetimes, backend selection, per-window events, owner-thread dispatch, and optional render scheduling.
Most application code should use gg with -d gg_multiwindow. This module is intended for the gg facade, backend work, and callers that need direct control over native windows and rendering setup.
Scope
The module provides:
- an
Appregistry for multiple native windows; - generation-checked
WindowIdhandles; - backend capability reporting and backend selection;
- lifecycle events routed to a specific window;
- backend-neutral input events routed to a specific window;
- an owner-thread job queue for cross-thread work;
- an opt-in render scheduler and opaque transaction declarations.
It does not provide layout, widgets, text rendering, high-level input semantics, or a default event loop. The gg facade supplies the higher-level loop, gg.Event mapping, and drawing API.
Creating an App
import x.multiwindow
mut app := multiwindow.new_app(backend: .mock, queue_size: 128)!
defer {
app.stop() or {}
}
win := app.create_window(title: 'Tool', width: 320, height: 200)!
info := app.window_info(win)!
println('${info.title}: ${info.width}x${info.height}')
multiwindow.new_app() uses the values in Config. The low-level default backend is .mock; .auto must be requested explicitly. The gg facade has its own configuration and defaults to .auto.
Config.require_renderer: true asks the selected backend to initialize its renderer during new_app(). The render API requires that creation-time request and Capabilities.explicit_swapchain; x.multiwindow does not lazily initialize a renderer later.
Backend Selection
BackendKind values are:
.mock: deterministic in-process backend for tests and event-only code;.x11: Linux X11 backend, compiled only with-d x_multiwindow_x11;.wayland: Linux Wayland backend, compiled only with-d sokol_wayland;.appkit: macOS AppKit backend;.win32: Windows backend;.auto: resolve to a concrete backend.
The .auto policy is platform and environment dependent:
- Windows selects
.win32. - macOS selects
.appkit. - Linux with
require_renderer: trueprefers X11 only when compiled with-d x_multiwindow_x11andDISPLAYis set, then Wayland when compiled with-d sokol_waylandandWAYLAND_DISPLAYis set. - Linux without
require_rendererprefers Wayland when compiled with-d sokol_waylandandWAYLAND_DISPLAYis set, then X11 only when compiled with-d x_multiwindow_x11andDISPLAYis set. - If no native backend is selected,
.autofalls back to.mock.
Plain capability probes do not necessarily open a display or create a device. Renderer capability probes and new_app(require_renderer: true) may fail if the display server, graphics device, or platform API is unavailable.
Backend Capabilities
Capabilities describes the selected backend contract:
multi_window: backend can manage more than one window;owner_queue: the owner-thread queue is available;explicit_swapchain: the backend can participate in managed explicit-target rendering; it does not expose a publicgfx.Swapchain;mock,native,x11,wayland,win32: selected platform flags;gl,metal,d3d11: active renderer API flags;input_events,mouse_events,keyboard_events,text_events,focus_events,drop_events,touch_events: native input classes the backend can actually deliver;cursor_shapes: native hover cursor shape updates are supported viaset_window_cursor(id, shape). This is independent from native interactive move/resize support;interactive_move_resize: native user-driven move/resize can be requested when the running backend has the required handles and current user action;native_decorations: native/server-side decorations are effective for the running backend;readback: whether the backend exposes readback support; it is false on the current native backends.
Plain capability probes do not necessarily connect to the display server, so runtime optional globals can be unknown before startup and most of those probes report implementation support. For Wayland, use app.capabilities() after new_app() for the authoritative runtime state: drop_events requires a wl_data_device, touch_events requires wl_touch, and interactive move/resize requires a seat. Wayland cursor-shape reporting is stricter: cursor_shapes is true only after a wp_cursor_shape_device_v1 has been created for the active wl_pointer. Wayland requests server-side decorations through xdg-decoration when the protocol is available; the compositor's configure(mode) decides the effective server_side or client_side mode. If server_side is refused or xdg-decoration is unavailable, apps and examples may draw a client-side fallback. Wayland cursor-shape feedback uses wp_cursor_shape_manager_v1 when the compositor exposes it and the seat has a pointer; this keeps cursor theme selection compositor-side. wl_cursor_theme client-side fallback is not implemented, so app.capabilities() reports cursor_shapes == false on Wayland compositors that do not advertise cursor-shape-v1.
Backend notes:
- Mock supports lifecycle, events, min-size clamping, and the owner queue, but it has no renderer.
- X11 is Linux-only and exists only in builds compiled with
-d x_multiwindow_x11. It supports native lifecycle, title updates, X11 size hints, borderless/fullscreen hints, optional EGL/OpenGL rendering, and native size queries after create/resize. Programmatic resize is rejected for non-resizable windows. - Wayland is Linux-only and exists only in builds compiled with
-d sokol_wayland. It requireswl_compositorandxdg_wm_base, rejectsvisible: false, and currently rejects programmatic resize. Rendering uses Wayland EGL/OpenGL when initialized. - AppKit is macOS-only. It must start on the main thread and uses Metal when rendering is required.
- Win32 is Windows-only and supports native lifecycle and min-size enforcement. D3D11 rendering requires a Windows build with
-d sokol_d3d11; without that flag, lifecycle works but managed renderer calls are unsupported. Renderer startup can still fail if D3D11 device or swapchain creation is unavailable, and DXGI occlusion during present is treated as a skipped frame.
Window Lifecycle
create_window() creates the native/backend window and returns a generation-checked WindowId. The stored WindowInfo uses the actual size reported by the backend after clamping or native size queries, not just the requested WindowConfig.
destroy_window() destroys one live window and emits a destroy event. Destroying the last window does not stop the app. stop() destroys all remaining live windows, marks the app stopped, stops the backend, and closes owner-queue admission.
Window handles are generation checked. A handle for a destroyed slot becomes stale if that slot is later reused.
Owner-Thread Rule
The thread that calls new_app() is the App owner thread. Mutating operations, event draining, registry enumeration, owner-queue draining, and rendering must run on that thread. Calls from another thread fail with:
multiwindow: operation requires the owner thread
Use post() or try_post() to enqueue short callbacks from other threads, then call drain_pending() on the owner thread. drain_pending() runs at most the requested number of jobs and rechecks app status between jobs; if a job stops the app, later queued jobs are not run.
The simple read helpers status(), capabilities(), window_exists(), and window_status() do not enforce the owner-thread check.
Events
Events are explicit. Native lifecycle and input events are not delivered to user code until the owner thread calls:
poll_events()to collect backend/native events into the App queue;drain_events()to retrieve and clear queued lifecycle events;drain_input_events()to retrieve and clear queued input events without consuming lifecycle events;drain_queued_events()to retrieve lifecycle and input events together in the exact order accepted byApp.
Lifecycle event kinds are:
.window_created: emitted bycreate_window()with the actual initial size;.window_destroyed: emitted bydestroy_window(),stop(), or accepted backend destroy notifications;.window_close_requested: emitted when the backend reports a close request;.window_resized: emitted afterresize_window()or accepted backend resize notifications with the actual size.
Backend events for stale or already-destroyed window handles are filtered.
InputEvent is the low-level backend-neutral payload used by the gg facade to rebuild gg.Event for a specific window. Input kinds include key down/up, char, mouse down/up/move/scroll/enter/leave, resize, iconified/restored, focus/unfocus, clipboard paste, file drop, and touch families. Backends report which families are implemented through the capability booleans above; unsupported input classes must remain false rather than being partially emulated.
Native input events that do not already carry a frame counter are stamped by App.poll_events(); all input events accepted in the same poll cycle share that frame_count. Mock/test events can provide an explicit non-zero frame_count, which is preserved.
Current native input support is intentionally capability-scoped:
- Mock can synthesize every input family for deterministic tests.
- Win32 routes mouse, keyboard, text/char, focus, resize, iconified/restored, clipboard paste signals, file drops via
WM_DROPFILES, andWM_TOUCHdown/move/up touch input.WM_TOUCHhandles are read and closed in the window procedure;WM_TOUCHdoes not expose a cancelled state, sotouches_cancelledis not emitted by the Win32 backend unless a future Pointer Input path ownsPOINTER_FLAG_CANCELED. - AppKit routes mouse, keyboard, text/char, focus, resize, iconified/restored, clipboard paste signals, and file drops through
NSDraggingDestinationfile URLs. It also routes AppKitNSRespondertouch phases; positions come fromNSTouch.normalizedPositionmapped into the current framebuffer, withtouches_cancelledemitted only fortouchesCancelledWithEvent:. - X11 routes mouse, keyboard, text/char, focus, resize, iconified/restored, and clipboard paste signal input events. Text uses Xlib XIM/XIC with
Xutf8LookupString; this covers committed UTF-8 text from the active input method without exposing Xlib objects through the public API. - X11 receives file drops with XDND
text/uri-listselection conversion. It decodes localfile://URIs and queues.files_droppedwith routeddropped_files. - Wayland routes pointer, keyboard, text/char through xkb keymap/state, focus, clipboard paste signal, resize input events, touch when the seat exposes
wl_touch, and file drops whenwl_data_device/wl_data_offertext/uri-listis available. Data-offer payloads are received through a non-blocking fd and drained from the owner poll path; the backend only sendswl_data_offer.finishafter a validcopyormoveaction has been received. Pending drops whose source never closes the transfer fd are rejected and cleaned up after a bounded number of owner poll cycles. Wayland text follows the existingsappxkb_state_key_get_utf8model for key presses; full IME/composed text is not implemented. Wayland synthesizes key-repeat from compositor repeat_info/xkb; pointer frame batching is not synthesized yet; event callbacks are routed as the compositor delivers them. - Native drop and touch input are false unless a backend explicitly reports the corresponding capability. Clipboard paste is an input signal; clipboard contents are not stored on
InputEvent.
QueuedEvent is the ordered queue entry used when lifecycle and input events must be consumed as a single stream. Its kind field tells whether the entry contains a lifecycle Event or an InputEvent. Use drain_queued_events() when relative ordering matters, for example input -> close-request -> input; use the separate drain_events() and drain_input_events() helpers only when that cross-family ordering is not needed.
Rendering
Rendering is optional. The render-facing source is selected by -d gg_multiwindow or -d x_multiwindow_render; plain lifecycle and .mock imports remain the no-flag isolation case.
The render contract does not expose gfx.Environment, gfx.Swapchain, native drawables, command buffers, RenderFrame, or present authority. It provides owner-thread opaque batch and target leases, backend-issued ready credits, immutable metrics and target snapshots, late target acquisition, one global commit, ordered finalization, and a private recovery anchor. Each acquired target and its stored slot share a nonzero per-window lease epoch; zero, mismatched, rotated, copied, or expired epochs are rejected.
Render-capable windows support exactly sample_count: 1; other sample counts are rejected. Current native backends report Capabilities.readback == false. The gg facade reports both window-capture and offscreen-image readback capabilities as false, and its readback request methods return gg.multiwindow: requested readback is not supported.
The normative graphics references are the V-vendored Sokol API and matching pinned upstream sokol_gfx.h. Backend lifetime and sequencing must also follow DXGI Present, DXGI ResizeBuffers, D3D11 threading, CAMetalLayer, EGL make-current, and EGL swap contracts. Local precedent does not override those lifetime and threading rules.
Relationship With gg
gg.App is the user-facing multi-window facade and is enabled with -d gg_multiwindow. It maps gg types to x.multiwindow and declares the managed sokol.gfx/sokol.sgl surface.
examples/gg/multiwindow.v is the interactive example:
./v -d gg_multiwindow run examples/gg/multiwindow.v
For Linux X11 native rendering, including Xvfb runs, add the X11 backend flag:
xvfb-run -a ./v -d gg_multiwindow -d x_multiwindow_x11 run examples/gg/multiwindow.v
For Wayland, build with -d sokol_wayland. The default build can still fall back to .mock when no enabled native backend is available. The example creates two gg windows, handles lifecycle events, and tolerates backends that reject programmatic resize.
examples/gg/multiwindow_render_runtime.v is the unattended renderer probe used by CI. The backend lanes compile it with -d gg_multiwindow and the matching native flag (-d x_multiwindow_x11, -d sokol_wayland, -d sokol_metal, or -d sokol_d3d11), select the backend with V_MULTIWINDOW_PROBE_BACKEND, and launch it through the process-tree watchdog that owns its parent gate. The probe emits {"example":"multiwindow_render_runtime","status":"PASS","cleanup":"complete"} only after renderer and window cleanup completes.
Limitations
- X11 support is compiled only with
-d x_multiwindow_x11; without that flag, the X11 backend is unsupported and X11/EGL/OpenGL libraries are not linked by low-level lifecycle or.mockimports. - Wayland support is compiled only with
-d sokol_wayland; without that flag, the Wayland backend is unsupported and Wayland libraries are not linked. - Wayland hidden window creation (
visible: false) is rejected. - Wayland programmatic resize is currently unsupported.
- X11 programmatic resize is rejected for non-resizable windows.
- Native app creation can still fail even when plain capabilities report that a backend is supported, for example when a display cannot be opened.
- The mock backend is not a renderer and cannot produce render targets.
- Multi-window render targets support only
sample_count: 1. - Native backends report readback capabilities as false; readback requests made through
gg.Appreturn an unsupported error. - The module has no layout, widget, text rendering, or drawing abstraction.
Validation
The no-flag lifecycle/source check is:
./v test vlib/x/multiwindow/multiwindow_test.v
This command is a non-render isolation check; it does not establish native renderer behavior. Renderer proofs run in the dedicated X11, Wayland, AppKit, and Win32 CI lanes. Each lane sets VGG_MULTIWINDOW_RUNTIME_PROBES=1, VGG_MULTIWINDOW_RUNTIME_BACKEND, and V_MULTIWINDOW_PROBE_BACKEND, compiles with its native renderer flags, and executes each test and runtime probe through the process-tree watchdog. The watchdog supplies the private parent gate, enforces the deadline, reaps child processes, and checks the final cleanup JSON.
fn capabilities_for_backend #
fn capabilities_for_backend(kind BackendKind) !Capabilities
capabilities_for_backend reports capabilities without creating an App.
fn capabilities_for_backend_with_renderer #
fn capabilities_for_backend_with_renderer(kind BackendKind, require_renderer bool) !Capabilities
capabilities_for_backend_with_renderer reports capabilities with the same backend resolution policy used by new_app(...).
fn capabilities_for_config #
fn capabilities_for_config(config Config) !Capabilities
capabilities_for_config reports capabilities without starting an App while respecting Config.require_renderer for .auto backend selection.
fn new_app #
fn new_app(config Config) !&App
new_app creates a low-level multi-window App with the mock backend by default.
fn AppKitWindowDrawableReleaseMode.from #
fn AppKitWindowDrawableReleaseMode.from[W](input W) !AppKitWindowDrawableReleaseMode
fn AppStatus.from #
fn AppStatus.from[W](input W) !AppStatus
fn BackendKind.from #
fn BackendKind.from[W](input W) !BackendKind
fn BackendTargetStatus.from #
fn BackendTargetStatus.from[W](input W) !BackendTargetStatus
fn CursorShape.from #
fn CursorShape.from[W](input W) !CursorShape
fn EglBindingKind.from #
fn EglBindingKind.from[W](input W) !EglBindingKind
fn EventDeliveryState.from #
fn EventDeliveryState.from[W](input W) !EventDeliveryState
fn EventKind.from #
fn EventKind.from[W](input W) !EventKind
fn InputEventKind.from #
fn InputEventKind.from[W](input W) !InputEventKind
fn InternalFaultStage.from #
fn InternalFaultStage.from[W](input W) !InternalFaultStage
fn NativeLifetimeReleaseKind.from #
fn NativeLifetimeReleaseKind.from[W](input W) !NativeLifetimeReleaseKind
fn NativeLifetimeTicketState.from #
fn NativeLifetimeTicketState.from[W](input W) !NativeLifetimeTicketState
fn NativeLocalValidation.from #
fn NativeLocalValidation.from[W](input W) !NativeLocalValidation
fn NativeOperationAuthorityScope.from #
fn NativeOperationAuthorityScope.from[W](input W) !NativeOperationAuthorityScope
fn NativeOperationTraceMilestone.from #
fn NativeOperationTraceMilestone.from[W](input W) !NativeOperationTraceMilestone
fn NativeRenderCallSite.from #
fn NativeRenderCallSite.from[W](input W) !NativeRenderCallSite
fn NativeRenderDisposition.from #
fn NativeRenderDisposition.from[W](input W) !NativeRenderDisposition
fn NativeRenderDomain.from #
fn NativeRenderDomain.from[W](input W) !NativeRenderDomain
fn NativeRenderOperation.from #
fn NativeRenderOperation.from[W](input W) !NativeRenderOperation
fn NativeRenderScope.from #
fn NativeRenderScope.from[W](input W) !NativeRenderScope
fn NativeRendererHealth.from #
fn NativeRendererHealth.from[W](input W) !NativeRendererHealth
fn QueuedEventKind.from #
fn QueuedEventKind.from[W](input W) !QueuedEventKind
fn RenderAcquireStatus.from #
fn RenderAcquireStatus.from[W](input W) !RenderAcquireStatus
fn RenderBlockReason.from #
fn RenderBlockReason.from[W](input W) !RenderBlockReason
fn RenderFinalizeStatus.from #
fn RenderFinalizeStatus.from[W](input W) !RenderFinalizeStatus
fn RenderRedrawMode.from #
fn RenderRedrawMode.from[W](input W) !RenderRedrawMode
fn RenderWindowRuntimeStatus.from #
fn RenderWindowRuntimeStatus.from[W](input W) !RenderWindowRuntimeStatus
fn RendererFaultMilestone.from #
fn RendererFaultMilestone.from[W](input W) !RendererFaultMilestone
fn RendererShutdownPath.from #
fn RendererShutdownPath.from[W](input W) !RendererShutdownPath
fn WindowDestroyStage.from #
fn WindowDestroyStage.from[W](input W) !WindowDestroyStage
fn WindowResizeEdge.from #
fn WindowResizeEdge.from[W](input W) !WindowResizeEdge
fn WindowStatus.from #
fn WindowStatus.from[W](input W) !WindowStatus
type AppJobFn #
type AppJobFn = fn (mut app App) !
AppJobFn is executed later by the owner queue while App is being pumped.
type RenderBatchFn #
type RenderBatchFn = fn (RenderBatchLease, []RenderWindowSnapshot) !
type RenderPassFn #
type RenderPassFn = fn () !
enum AppStatus #
enum AppStatus {
running
stopped
}
AppStatus describes the application lifecycle owned by App.
enum BackendKind #
enum BackendKind {
auto
mock
x11
wayland
appkit
win32
}
BackendKind selects the platform implementation. The .auto policy resolves to a concrete backend before startup/capabilities are reported.
enum CursorShape #
enum CursorShape {
default
pointer
move
n_resize
s_resize
e_resize
w_resize
ne_resize
nw_resize
se_resize
sw_resize
ew_resize
ns_resize
nesw_resize
nwse_resize
grab
grabbing
}
CursorShape identifies a native cursor image for client-side chrome hover feedback. Cursor support is independent from native interactive move/resize.
enum EventKind #
enum EventKind {
window_created
window_destroyed
window_close_requested
window_resized
}
EventKind describes core window lifecycle events emitted by the backend.
enum InputEventKind #
enum InputEventKind {
invalid
key_down
key_up
char
mouse_down
mouse_up
mouse_scroll
mouse_move
mouse_enter
mouse_leave
touches_began
touches_moved
touches_ended
touches_cancelled
resized
iconified
restored
focused
unfocused
suspended
resumed
quit_requested
clipboard_pasted
files_dropped
}
InputEventKind mirrors the input/event classes exposed by sokol/gg while remaining independent from gg and sokol imports.
enum QueuedEventKind #
enum QueuedEventKind {
lifecycle
input
}
enum RenderAcquireStatus #
enum RenderAcquireStatus {
ready
transient_unavailable
}
enum RenderBlockReason #
enum RenderBlockReason {
none
no_workload
not_configured
frame_callback_pending
hidden
minimized
occluded
unmapped
not_viewable
zero_sized
resize_pending
drawable_unavailable
backend_unavailable
renderer_failed
}
RenderBlockReason records the backend fact which withheld a ready credit.
enum RenderRedrawMode #
enum RenderRedrawMode {
on_demand
continuous
}
RenderRedrawMode controls low-level frame eligibility for one window.
enum WindowResizeEdge #
enum WindowResizeEdge {
top
bottom
left
right
top_left
top_right
bottom_left
bottom_right
}
WindowResizeEdge identifies the edge or corner used for an interactive, user-driven native resize operation.
enum WindowStatus #
enum WindowStatus {
invalid
alive
destroyed
}
WindowStatus describes the lifecycle of a registered window slot.
struct App #
struct App {
mut:
config Config
instance_id u64
status AppStatus = .running
stopping bool
backend Backend
windows []WindowSlot
events []QueuedEvent
event_deliveries map[u64]EventDeliveryState
next_event_delivery_token u64 = 1
event_dispatch_events []QueuedEvent
event_dispatch_active bool
event_dispatch_index int
event_delivery_terminal bool
teardown_acceptance_order []WindowId
window_finished map[string]bool
window_terminal map[string]string
frame_count u64
deferred_poll_error string
deferred_poll_error_active bool
deferred_poll_barrier_token u64
backend_event_terminal string
render_runtime RenderRuntimeState
render_bridge voidptr
owner_thread_id u64
admission_open bool = true
admission_epoch u64 = 1
owner_callback_depth int
next_stop_serial u64 = 1
stop_serial u64
stop_prepared bool
stop_terminal string
pending_stop_errors []string
stop_native_retry_passes u8
internal_fault InternalFaultPlan
state_mutex &sync.Mutex = sync.new_mutex()
fault_mutex &sync.Mutex = sync.new_mutex()
owner &executor.Executor = unsafe { nil }
}
App owns the low-level multi-window registry and owner queue.
fn (App) begin_window_move #
fn (mut app App) begin_window_move(id WindowId) !
begin_window_move starts a user-driven native move for a live window. Backends that require a recent native input serial may reject the request when it is not made from a deliberate user-action path.
fn (App) begin_window_resize #
fn (mut app App) begin_window_resize(id WindowId, edge WindowResizeEdge) !
begin_window_resize starts a user-driven native resize for a live resizable window.
fn (App) capabilities #
fn (app &App) capabilities() Capabilities
capabilities reports the selected backend capabilities.
fn (App) create_window #
fn (mut app App) create_window(config WindowConfig) !WindowId
create_window creates a backend window and returns its generation-checked id.
fn (App) destroy_window #
fn (mut app App) destroy_window(id WindowId) !
destroy_window destroys one live window. The app remains alive when any window, including the last one, is destroyed.
fn (App) drain_events #
fn (mut app App) drain_events() ![]Event
drain_events returns and clears pending lifecycle events.
fn (App) drain_input_events #
fn (mut app App) drain_input_events() ![]InputEvent
drain_input_events returns and clears pending input events without consuming lifecycle events.
fn (App) drain_pending #
fn (mut app App) drain_pending(max_jobs int) !int
drain_pending executes up to max_jobs queued owner callbacks while the app is running. After stop(), accepted-but-pending callbacks are not executed and this returns multiwindow: app is stopped.
fn (App) drain_queued_events #
fn (mut app App) drain_queued_events() ![]QueuedEvent
drain_queued_events returns and clears pending lifecycle/input events in the exact order accepted by App.
fn (App) drain_render_teardown_notices #
fn (mut app App) drain_render_teardown_notices() ![]RenderTeardownNotice
fn (App) finish_stop #
fn (mut app App) finish_stop(ticket AppStopTicket, prior_errors []string) !
fn (App) finish_window_destroy #
fn (mut app App) finish_window_destroy(ticket WindowDestroyTicket, prior_errors []string) !
finish_window_destroy is irreversible. It attempts backend cleanup even when earlier package cleanup failed and records one aggregate terminal outcome.
fn (App) instance_id #
fn (app &App) instance_id() u64
instance_id is process-monotonic and never reused. It stamps every handle, scheduler lease and accepted owner wrapper belonging to this App.
fn (App) logical_to_pixel_render_rect #
fn (app &App) logical_to_pixel_render_rect(id WindowId, metrics_sequence u64, x f32, y f32, width f32, height f32) !(int, int, int, int)
fn (App) pixel_to_logical_render_rect #
fn (app &App) pixel_to_logical_render_rect(id WindowId, metrics_sequence u64, x int, y int, width int, height int) !(f32, f32, f32, f32)
fn (App) poll_events #
fn (mut app App) poll_events() !int
poll_events lets the backend route native lifecycle and input events into App events.
fn (App) post #
fn (mut app App) post(f AppJobFn) !
post submits a short owner-thread callback if queue capacity is available.
fn (App) prepare_stop #
fn (mut app App) prepare_stop() !AppStopTicket
fn (App) prepare_window_destroy #
fn (mut app App) prepare_window_destroy(id WindowId) !WindowDestroyTicket
fn (App) prepare_window_destroy_for_stop #
fn (mut app App) prepare_window_destroy_for_stop(id WindowId) !WindowDestroyTicket
fn (App) render_window_eligible #
fn (app &App) render_window_eligible(id WindowId) !bool
fn (App) render_window_snapshot #
fn (app &App) render_window_snapshot(id WindowId) !RenderWindowSnapshot
fn (App) request_redraw #
fn (mut app App) request_redraw(id WindowId) !
request_redraw is thread-safe admission. Accepted foreign wrappers are app/epoch stamped and become cancellation-only work after stop closes admission; x.executor itself remains unchanged.
fn (App) resize_window #
fn (mut app App) resize_window(id WindowId, width int, height int) !
resize_window requests a native resize and then updates the authoritative App state.
fn (App) rollback_window_destroy #
fn (mut app App) rollback_window_destroy(ticket WindowDestroyTicket) !
fn (App) seal_window_destroy #
fn (mut app App) seal_window_destroy(ticket WindowDestroyTicket) !
fn (App) seal_window_destroy_terminal_for_stop #
fn (mut app App) seal_window_destroy_terminal_for_stop(id WindowId) !WindowDestroyTicket
seal_window_destroy_terminal_for_stop is the irreversible fallback used only after normal prepare/seal failed during stop. Validation happens before the slot is sealed; an accepted live generation already owns its fallback serial.
fn (App) set_render_workload #
fn (mut app App) set_render_workload(id WindowId, enabled bool) !
fn (App) set_window_cursor #
fn (mut app App) set_window_cursor(id WindowId, shape CursorShape) !
set_window_cursor updates the native hover cursor for a live window when the selected backend reports capabilities().cursor_shapes.
fn (App) set_window_title #
fn (mut app App) set_window_title(id WindowId, title string) !
set_window_title updates the native title and then the authoritative App state.
fn (App) status #
fn (app &App) status() AppStatus
status reports the application lifecycle state.
fn (App) stop #
fn (mut app App) stop() !
stop destroys live windows, closes owner-queue admission and marks the app stopped. Pending owner callbacks are canceled logically: public drain_pending() refuses to run them after stop().
fn (App) try_post #
fn (mut app App) try_post(f AppJobFn) !
try_post submits a short owner-thread callback without waiting for capacity. It follows x.executor's ! contract: queue-full and closed-queue states are returned as errors instead of a bool.
fn (App) window_exists #
fn (app &App) window_exists(id WindowId) bool
window_exists reports whether id currently points to a live window.
fn (App) window_ids #
fn (app &App) window_ids() ![]WindowId
window_ids returns live window ids in stable slot order.
fn (App) window_info #
fn (app &App) window_info(id WindowId) !WindowInfo
window_info returns a snapshot of the authoritative App-side window state.
fn (App) window_infos #
fn (app &App) window_infos() ![]WindowInfo
window_infos returns live window snapshots in stable slot order.
fn (App) window_status #
fn (app &App) window_status(id WindowId) !WindowStatus
window_status returns the lifecycle status for a valid generation.
fn (App) with_legacy_render_batch #
fn (mut app App) with_legacy_render_batch(f RenderBatchFn) !RenderBatchOutcome
fn (App) with_scheduled_render_batch #
fn (mut app App) with_scheduled_render_batch(f RenderBatchFn) !RenderBatchOutcome
with_scheduled_render_batch opens one authoritative global transaction. The callback is invoked even with no candidates so app-scoped resource work can initialize and advance without a window frame callback.
fn (App) with_teardown_render_batch #
fn (mut app App) with_teardown_render_batch(f RenderBatchFn) !RenderBatchOutcome
struct AppStopTicket #
struct AppStopTicket {
app_instance u64
serial u64
}
struct Capabilities #
struct Capabilities {
pub:
backend BackendKind
mock bool
native bool
multi_window bool
owner_queue bool
explicit_swapchain bool
readback bool
d3d11 bool
metal bool
x11 bool
wayland bool
win32 bool
gl bool
input_events bool
mouse_events bool
keyboard_events bool
text_events bool
focus_events bool
drop_events bool
touch_events bool
cursor_shapes bool
interactive_move_resize bool
native_decorations bool
}
Capabilities reports what the selected backend can do.
struct Config #
struct Config {
pub:
backend BackendKind = .mock
queue_size int = 128
require_renderer bool
}
Config configures a multi-window App.
struct Event #
struct Event {
pub:
kind EventKind
window_id WindowId
width int
height int
}
Event is always routed to a specific WindowId.
struct InputEvent #
struct InputEvent {
pub:
kind InputEventKind
window_id WindowId
frame_count u64
key_code int
char_code u32
key_repeat bool
modifiers u32
mouse_button int = input_event_invalid_mouse_button
mouse_x f32
mouse_y f32
mouse_dx f32
mouse_dy f32
scroll_x f32
scroll_y f32
num_touches int
touches [8]InputTouchPoint
window_width int
window_height int
framebuffer_width int
framebuffer_height int
dropped_files []string
}
InputEvent is always routed to a specific WindowId. It carries the full backend-neutral payload needed to rebuild gg.Event in the gg facade.
struct InputTouchPoint #
struct InputTouchPoint {
pub:
identifier u64
pos_x f32
pos_y f32
android_tooltype int
changed bool
}
InputTouchPoint is the backend-neutral representation of one touch point.
struct QueuedEvent #
struct QueuedEvent {
delivery_token u64
pub:
kind QueuedEventKind
lifecycle Event
input InputEvent
}
QueuedEvent preserves backend ordering between lifecycle and input events.
struct RenderBatchLease #
struct RenderBatchLease {
app_instance u64
epoch u64
include_all bool
}
RenderBatchLease is opaque authority for one owner-thread transaction.
fn (RenderBatchLease) epoch_for_gg #
fn (lease RenderBatchLease) epoch_for_gg() u64
epoch_for_gg exposes immutable validation data without exposing scheduler mutation or finish authority.
struct RenderBatchOutcome #
struct RenderBatchOutcome {
suppressed_callback_target RenderTargetLease
suppressed_callback_outcome NativeRenderResult
suppressed_callback_message string
pub:
batch_epoch u64
committed bool
had_gpu_work bool
completed_user_passes int
finalized_submissions int
error string
}
struct RenderMetricsSnapshot #
struct RenderMetricsSnapshot {
pub:
logical_width f32
logical_height f32
framebuffer_width int
framebuffer_height int
dpi_scale f32
metrics_sequence u64
metrics_available bool
conversion_available bool
}
RenderMetricsSnapshot contains only backend-observed values. Conversion is unavailable unless the backend can reproduce it for metrics_sequence.
struct RenderTargetAcquisition #
struct RenderTargetAcquisition {
pub:
status RenderAcquireStatus
lease RenderTargetLease
snapshot RenderWindowSnapshot
block_reason RenderBlockReason
}
struct RenderTargetLease #
struct RenderTargetLease {
app_instance u64
batch_epoch u64
target_epoch u64
window_epoch u64
window WindowId
}
RenderTargetLease identifies one acquired target without exposing its swapchain, drawable, command buffer, framebuffer, or native handles.
struct RenderTargetSnapshot #
struct RenderTargetSnapshot {
pub:
target_identity u64
color_format int
depth_format int
sample_count int
}
struct RenderTeardownNotice #
struct RenderTeardownNotice {
pub:
window WindowId
snapshot RenderWindowSnapshot
ticket WindowDestroyTicket
}
struct RenderWindowSnapshot #
struct RenderWindowSnapshot {
pub:
window WindowId
redraw_mode RenderRedrawMode
dirty_epoch u64
consumed_epoch u64
frame_serial u64
submitted_frame u64
metrics RenderMetricsSnapshot
target RenderTargetSnapshot
eligibility_sequence u64
block_reason RenderBlockReason
focus_known bool
focused bool
minimized_known bool
minimized bool
batch_epoch u64
}
RenderWindowSnapshot is immutable scheduler and backend state. Batch candidates expose the checked next serial without mutating persistent state.
struct RendererConfig #
struct RendererConfig {
pub:
buffer_pool_size int = 128
image_pool_size int = 1024
sampler_pool_size int = 128
shader_pool_size int = 128
pipeline_pool_size int = 256
attachments_pool_size int = 256
}
struct RendererInfo #
struct RendererInfo {
pub:
color_format int
depth_format int
sample_count int
}
struct WindowConfig #
struct WindowConfig {
pub:
title string = 'V Window'
width int = 800
height int = 600
min_width int
min_height int
resizable bool = true
visible bool = true
high_dpi bool = true
borderless bool
fullscreen bool
sample_count int = 1
redraw_mode RenderRedrawMode = .on_demand
// render_workload is set by the gg facade. A window without work is never
// claimed merely because it was exposed or marked dirty.
render_workload bool
}
WindowConfig describes one window at creation time.
struct WindowDestroyTicket #
struct WindowDestroyTicket {
app_instance u64
window WindowId
serial u64
}
WindowDestroyTicket is opaque and app/generation/serial checked at every stage. Only an unsealed ticket can be rolled back.
struct WindowId #
struct WindowId {
app_instance u64
slot int
generation u32
}
WindowId is an opaque generation-checked handle to a window.
fn (WindowId) str #
fn (id WindowId) str() string
str returns a diagnostic representation of a WindowId without exposing its fields as public mutable state.
fn (WindowId) app_instance_for_gg #
fn (id WindowId) app_instance_for_gg() u64
app_instance_for_gg exposes immutable identity data needed by the gg facade to reject foreign handles before any local slot lookup.
struct WindowInfo #
struct WindowInfo {
pub:
id WindowId
status WindowStatus
title string
width int
height int
min_width int
min_height int
resizable bool
visible bool
high_dpi bool
borderless bool
fullscreen bool
native_decorations bool
}
WindowInfo is a snapshot of the authoritative App-side window state.
- README
- fn capabilities_for_backend
- fn capabilities_for_backend_with_renderer
- fn capabilities_for_config
- fn new_app
- fn AppKitWindowDrawableReleaseMode.from
- fn AppStatus.from
- fn BackendKind.from
- fn BackendTargetStatus.from
- fn CursorShape.from
- fn EglBindingKind.from
- fn EventDeliveryState.from
- fn EventKind.from
- fn InputEventKind.from
- fn InternalFaultStage.from
- fn NativeLifetimeReleaseKind.from
- fn NativeLifetimeTicketState.from
- fn NativeLocalValidation.from
- fn NativeOperationAuthorityScope.from
- fn NativeOperationTraceMilestone.from
- fn NativeRenderCallSite.from
- fn NativeRenderDisposition.from
- fn NativeRenderDomain.from
- fn NativeRenderOperation.from
- fn NativeRenderScope.from
- fn NativeRendererHealth.from
- fn QueuedEventKind.from
- fn RenderAcquireStatus.from
- fn RenderBlockReason.from
- fn RenderFinalizeStatus.from
- fn RenderRedrawMode.from
- fn RenderWindowRuntimeStatus.from
- fn RendererFaultMilestone.from
- fn RendererShutdownPath.from
- fn WindowDestroyStage.from
- fn WindowResizeEdge.from
- fn WindowStatus.from
- type AppJobFn
- type RenderBatchFn
- type RenderPassFn
- enum AppStatus
- enum BackendKind
- enum CursorShape
- enum EventKind
- enum InputEventKind
- enum QueuedEventKind
- enum RenderAcquireStatus
- enum RenderBlockReason
- enum RenderRedrawMode
- enum WindowResizeEdge
- enum WindowStatus
- struct App
- fn begin_window_move
- fn begin_window_resize
- fn capabilities
- fn create_window
- fn destroy_window
- fn drain_events
- fn drain_input_events
- fn drain_pending
- fn drain_queued_events
- fn drain_render_teardown_notices
- fn finish_stop
- fn finish_window_destroy
- fn instance_id
- fn logical_to_pixel_render_rect
- fn pixel_to_logical_render_rect
- fn poll_events
- fn post
- fn prepare_stop
- fn prepare_window_destroy
- fn prepare_window_destroy_for_stop
- fn render_window_eligible
- fn render_window_snapshot
- fn request_redraw
- fn resize_window
- fn rollback_window_destroy
- fn seal_window_destroy
- fn seal_window_destroy_terminal_for_stop
- fn set_render_workload
- fn set_window_cursor
- fn set_window_title
- fn status
- fn stop
- fn try_post
- fn window_exists
- fn window_ids
- fn window_info
- fn window_infos
- fn window_status
- fn with_legacy_render_batch
- fn with_scheduled_render_batch
- fn with_teardown_render_batch
- struct AppStopTicket
- struct Capabilities
- struct Config
- struct Event
- struct InputEvent
- struct InputTouchPoint
- struct QueuedEvent
- struct RenderBatchLease
- struct RenderBatchOutcome
- struct RenderMetricsSnapshot
- struct RenderTargetAcquisition
- struct RenderTargetLease
- struct RenderTargetSnapshot
- struct RenderTeardownNotice
- struct RenderWindowSnapshot
- struct RendererConfig
- struct RendererInfo
- struct WindowConfig
- struct WindowDestroyTicket
- struct WindowId
- struct WindowInfo