AtlatestRepositorysigil-wm
1# sigil-wm
2
3[![Created with Sigil](https://usesigil.org/badge/created-with-sigil-on-light.svg)](https://usesigil.org/)
4
5A toolkit for writing Wayland window managers in Sigil, built on wlroots.
6The native thread owns Wayland objects, input transport and scene presentation.
7
8Copied admissions that arrive after release, lock, or resource retirement complete
9with a cancelled `scene-move-ended` event.
11Interactive scene translation uses `start-scene-move!` with a window, held
12button, pointer anchor and an explicit set of window/pixel resources (at most
13256). The native owner follows pointer motion without a manager round trip or
14restacking. `scene-move-ended` reports `delta-x:`, `delta-y:`, `move-token:`
15and `reason:` (0 release, 1 cancellation). The manager reconciles its geometry
16in the next full plan; stale plans cannot rewind the move. Explicit fullscreen,
17tiled or hidden placements cancel translation. `stop-scene-move!`, lock, unmap
18and initiating-device removal also stop it.
20Sigil chooses placement, visibility, stacking, focus and input handling.
22The library namespaces are `(sigil wm host)`, `(sigil wm model)`,
23`(sigil wm layout)`, `(sigil wm scene)`, `(sigil wm input)` and `(sigil wm repl)`.
24Optional `(sigil wm draw)` renders text and shapes to pixel buffers using
25sigil-cairo, sigil-harfbuzz, sigil-freetype and sigil-fontconfig. The core has no
26font dependencies. See [the API design](docs/design.md).
28Build in the pinned environment:
30```sh
31guix time-machine -C channels.scm -- shell -m manifest.scm -- make
32```
34`(configure-trace! #t)` enables bounded copied timing records. Bind
35`current-trace-correlation` in `(sigil wm trace)` to an action ID before sending
36commands, or `current-trace-causes` to up to 64 IDs when coalescing actions into
37one scene/pixel upload. Capture these bindings explicitly across queued callbacks.
38The host emits `trace-record` events with `id:`, `stage:`, `monotonic-ns:`,
39`object:` and `commit-sequence:`. Stages 0, 8, 9, 10, 11 and 12 denote native
40input receipt, commit, presentation, scene application, focus and copied pixels;
4114 denotes a discarded presentation. `latency-mark!` records application stages.
42Commit/presentation associations retain each causal ID independently of newer
43input. Record storage is bounded at 8192; each output retains 64 causes and 64
44commit associations. Saturation or contention increments `trace-dropped` without
45blocking input or disabling tracing. Disabled recording returns after its atomic
46enable check, without clock reads, allocation, locks or IO. Existing untraced
47submission functions retain their ABI. Trace events are diagnostics, not snapshot
48facts, 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 which
52have never been plugged in; other backends supply their live output objects.
53Each connector includes connection/enabled/power state, available/current modes,
54scale, position, transform and backend make/model/serial where available.
55Unknown text is `#f`; an absent live output has `id: 0`. DRM connector IDs and
56device numbers disambiguate backend identities. Native output changes refresh
57the copied inventory on an idle callback. Limits (256 connectors, 128 modes per
58connector) and backend enumeration failures are reported explicitly.
60Run `scripts/test-trace-inventory` inside the pinned environment with a glibc
61Sigil runtime. It checks disabled recording, 12,000 records, drops/recovery,
62overlapping actions, a never-connected mocked DRM connector, metadata, and a
63real headless pixel/plan commit/presentation/disable cycle.
65The native maintenance timer is armed for the earliest outstanding input,
66motion, plan, scene bracket, lock grace, permission, data/output request,
67pointer hint or popup deadline. Admission and cancellation in any native/idle
68callback are reflected before the loop blocks. With no pending deadline the
69timer stays disarmed; backend/client timers continue normally. Expired bound
70keys wait for their explicit decision without periodic wakeups, and an elapsed
71lock grace never bypasses the presentation barrier. `(host-statistic host 12)`
72counts maintenance callbacks so idle tests distinguish those from real backend
73frame or client events. `scripts/test-deadlines` checks every deadline class,
74independent repeating timers, real resource expiry, lock isolation, repeated
75key streams, coalesced motion and zero blanked-host maintenance ticks.
77Popups use their root parent's output as the constraint area, including layer
78surfaces and nested popups. Initial configuration, repositioning and policy
79configuration apply the client's flip, slide and resize rules in root-surface
80coordinates. `scripts/test-popup-constraints` checks delivered geometry against
81two adjacent outputs with nonzero layout and window-geometry origins.
83Failed scene commits retain damage and client frame callbacks until an output
84commit succeeds. Ordinary scene failures retry after 16 ms through the native
85deadline timer; gamma failures retain their existing ownership and retry rules.
86`scripts/test-surface-frames` checks tiny redraws, callbacks and actual presented
87pixel phases, including one rejected commit. `scripts/test-foot-blink` samples
88cursor phases in a nested compositor, directly and through a private tmux.
90Run the stacking example from a Wayland session:
92```sh
93guix time-machine -C channels.scm -- shell -m manifest.scm -- \
94 bash scripts/run-sigil -L src -L examples eval -f examples/stacking.sgl
95```
97`examples/tiling.sgl` partitions the output. `examples/tabbed.sgl` shows one
98window at a time and draws titles with `(sigil wm draw)`. Tab selects the next
99window; Escape exits. All three use the same host and explicit scene plans.
101The tabbed example also needs the optional drawing packages. Development copies
102can be staged with `scripts/stage-draw`, passing the four package source roots
103in cairo, freetype, harfbuzz, fontconfig order. Use `draw-manifest.scm` for their
104native libraries. This does not add those libraries to the compositor core.
106Set `SIGIL_WM_REPL` to a path in a private runtime directory to enable expression
107IPC in an example. `scripts/msg SOCKET '(host-snapshot host)'` inspects its live
108state. The socket permits arbitrary Sigil evaluation with the user's authority.
110The real-client tests run through `scripts/test-examples`; they retain logs,
111composed-output captures and PNGs under `build/receipts/`.
113`scripts/test-input-reply-queue` fills the 1024-command ring while a key, button
114or motion hook is returning its decision. A test-only native gate pauses
115consumption, and another scheduler task releases it to verify cooperative
116backpressure, accepted replies and subsequent input progress. It also checks
117replies before native readiness and after shutdown with an empty ring, and
118checks diagnostic rate limiting. Set `SIGIL` to a runtime with FFI
119loading support; logs are retained under `build/receipts/input-reply-queue/`.
121`scripts/test-lock-presentation` uses a test-only presentation barrier to check
122that a blank lock owner cannot be acknowledged before actual output
123presentation, that ordinary pixels remain covered, and that authenticated
124unlock restores the scene. The barrier is absent from the production library.
126`build/backend-pointer.so` is an optional test fixture for backend input. Set
127`SIGIL_WM_BACKEND_POINTER_CONTROL` before starting a headless test session;
128creating that file emits one backend pointer motion on the native event loop.
129The device uses the ordinary backend origin and is destroyed with its backend.
130This lets idle tests retain locked virtual-input refusal while exercising
131backend activity and power resume. It does not establish physical-device
132coverage and is absent from the production library.
134Security-context connections are filtered before they can discover or bind
135privileged globals: session lock, capture, data control, output controls,
136layer-shell, idle notification, virtual input, foreign-toplevel management and
137the security-context manager. Read-only ext foreign-toplevel listing remains
138available, including other applications' titles and app IDs.
139Ordinary application rendering and focused clipboard protocols stay available.
140Classification uses wlroots connection context, including empty metadata,
141without PID or application-name matching. Native connections retain compatibility
142access, including locker replacement; this is not same-user process isolation.
143Sandbox engines must use the security-context protocol: unlabelled raw-socket
144connections retain native access. There is no strict option or client allowlist.