AtlatestRepositorysigil-wm
1
# sigil-wm3
[](https://usesigil.org/)5
A toolkit for writing Wayland window managers in Sigil, built on wlroots.6
The native thread owns Wayland objects, input transport and scene presentation.8
Copied admissions that arrive after release, lock, or resource retirement complete9
with a cancelled `scene-move-ended` event.11
Interactive scene translation uses `start-scene-move!` with a window, held12
button, pointer anchor and an explicit set of window/pixel resources (at most13
256). The native owner follows pointer motion without a manager round trip or14
restacking. `scene-move-ended` reports `delta-x:`, `delta-y:`, `move-token:`15
and `reason:` (0 release, 1 cancellation). The manager reconciles its geometry16
in the next full plan; stale plans cannot rewind the move. Explicit fullscreen,17
tiled or hidden placements cancel translation. `stop-scene-move!`, lock, unmap18
and initiating-device removal also stop it.20
Sigil chooses placement, visibility, stacking, focus and input handling.22
The library namespaces are `(sigil wm host)`, `(sigil wm model)`,23
`(sigil wm layout)`, `(sigil wm scene)`, `(sigil wm input)` and `(sigil wm repl)`.24
Optional `(sigil wm draw)` renders text and shapes to pixel buffers using25
sigil-cairo, sigil-harfbuzz, sigil-freetype and sigil-fontconfig. The core has no26
font dependencies. See [the API design](docs/design.md).28
Build in the pinned environment:30
```sh31
guix time-machine -C channels.scm -- shell -m manifest.scm -- make32
```34
`(configure-trace! #t)` enables bounded copied timing records. Bind35
`current-trace-correlation` in `(sigil wm trace)` to an action ID before sending36
commands, or `current-trace-causes` to up to 64 IDs when coalescing actions into37
one scene/pixel upload. Capture these bindings explicitly across queued callbacks.38
The host emits `trace-record` events with `id:`, `stage:`, `monotonic-ns:`,39
`object:` and `commit-sequence:`. Stages 0, 8, 9, 10, 11 and 12 denote native40
input receipt, commit, presentation, scene application, focus and copied pixels;41
14 denotes a discarded presentation. `latency-mark!` records application stages.42
Commit/presentation associations retain each causal ID independently of newer43
input. Record storage is bounded at 8192; each output retains 64 causes and 6444
commit associations. Saturation or contention increments `trace-dropped` without45
blocking input or disabling tracing. Disabled recording returns after its atomic46
enable check, without clock reads, allocation, locks or IO. Existing untraced47
submission functions retain their ABI. Trace events are diagnostics, not snapshot48
facts, and can be lost independently of reliable host state.50
`(host-output-inventory host)` returns a detached dictionary with `connectors:`,51
`truncated?:` and `errors:`. DRM resource enumeration includes connectors which52
have never been plugged in; other backends supply their live output objects.53
Each connector includes connection/enabled/power state, available/current modes,54
scale, position, transform and backend make/model/serial where available.55
Unknown text is `#f`; an absent live output has `id: 0`. DRM connector IDs and56
device numbers disambiguate backend identities. Native output changes refresh57
the copied inventory on an idle callback. Limits (256 connectors, 128 modes per58
connector) and backend enumeration failures are reported explicitly.60
Run `scripts/test-trace-inventory` inside the pinned environment with a glibc61
Sigil runtime. It checks disabled recording, 12,000 records, drops/recovery,62
overlapping actions, a never-connected mocked DRM connector, metadata, and a63
real headless pixel/plan commit/presentation/disable cycle.65
The native maintenance timer is armed for the earliest outstanding input,66
motion, plan, scene bracket, lock grace, permission, data/output request,67
pointer hint or popup deadline. Admission and cancellation in any native/idle68
callback are reflected before the loop blocks. With no pending deadline the69
timer stays disarmed; backend/client timers continue normally. Expired bound70
keys wait for their explicit decision without periodic wakeups, and an elapsed71
lock grace never bypasses the presentation barrier. `(host-statistic host 12)`72
counts maintenance callbacks so idle tests distinguish those from real backend73
frame or client events. `scripts/test-deadlines` checks every deadline class,74
independent repeating timers, real resource expiry, lock isolation, repeated75
key streams, coalesced motion and zero blanked-host maintenance ticks.77
Popups use their root parent's output as the constraint area, including layer78
surfaces and nested popups. Initial configuration, repositioning and policy79
configuration apply the client's flip, slide and resize rules in root-surface80
coordinates. `scripts/test-popup-constraints` checks delivered geometry against81
two adjacent outputs with nonzero layout and window-geometry origins.83
Failed scene commits retain damage and client frame callbacks until an output84
commit succeeds. Ordinary scene failures retry after 16 ms through the native85
deadline timer; gamma failures retain their existing ownership and retry rules.86
`scripts/test-surface-frames` checks tiny redraws, callbacks and actual presented87
pixel phases, including one rejected commit. `scripts/test-foot-blink` samples88
cursor phases in a nested compositor, directly and through a private tmux.90
Run the stacking example from a Wayland session:92
```sh93
guix time-machine -C channels.scm -- shell -m manifest.scm -- \94
bash scripts/run-sigil -L src -L examples eval -f examples/stacking.sgl95
```97
`examples/tiling.sgl` partitions the output. `examples/tabbed.sgl` shows one98
window at a time and draws titles with `(sigil wm draw)`. Tab selects the next99
window; Escape exits. All three use the same host and explicit scene plans.101
The tabbed example also needs the optional drawing packages. Development copies102
can be staged with `scripts/stage-draw`, passing the four package source roots103
in cairo, freetype, harfbuzz, fontconfig order. Use `draw-manifest.scm` for their104
native libraries. This does not add those libraries to the compositor core.106
Set `SIGIL_WM_REPL` to a path in a private runtime directory to enable expression107
IPC in an example. `scripts/msg SOCKET '(host-snapshot host)'` inspects its live108
state. The socket permits arbitrary Sigil evaluation with the user's authority.110
The real-client tests run through `scripts/test-examples`; they retain logs,111
composed-output captures and PNGs under `build/receipts/`.113
`scripts/test-input-reply-queue` fills the 1024-command ring while a key, button114
or motion hook is returning its decision. A test-only native gate pauses115
consumption, and another scheduler task releases it to verify cooperative116
backpressure, accepted replies and subsequent input progress. It also checks117
replies before native readiness and after shutdown with an empty ring, and118
checks diagnostic rate limiting. Set `SIGIL` to a runtime with FFI119
loading support; logs are retained under `build/receipts/input-reply-queue/`.121
`scripts/test-lock-presentation` uses a test-only presentation barrier to check122
that a blank lock owner cannot be acknowledged before actual output123
presentation, that ordinary pixels remain covered, and that authenticated124
unlock restores the scene. The barrier is absent from the production library.126
`build/backend-pointer.so` is an optional test fixture for backend input. Set127
`SIGIL_WM_BACKEND_POINTER_CONTROL` before starting a headless test session;128
creating that file emits one backend pointer motion on the native event loop.129
The device uses the ordinary backend origin and is destroyed with its backend.130
This lets idle tests retain locked virtual-input refusal while exercising131
backend activity and power resume. It does not establish physical-device132
coverage and is absent from the production library.134
Security-context connections are filtered before they can discover or bind135
privileged globals: session lock, capture, data control, output controls,136
layer-shell, idle notification, virtual input, foreign-toplevel management and137
the security-context manager. Read-only ext foreign-toplevel listing remains138
available, including other applications' titles and app IDs.139
Ordinary application rendering and focused clipboard protocols stay available.140
Classification uses wlroots connection context, including empty metadata,141
without PID or application-name matching. Native connections retain compatibility142
access, including locker replacement; this is not same-user process isolation.143
Sandbox engines must use the security-context protocol: unlabelled raw-socket144
connections retain native access. There is no strict option or client allowlist.