Skip to content
Velle Sinclair edited this page Jul 12, 2026 · 8 revisions

synui

The Wayland compositor, on wlroots 0.19. Written for this system rather than adapted to it: it draws its own display-settings panel, wallpaper picker, dock and control panel, renders an optional CRT post-process pass, and holds live subscriptions to synguard's verdict feed and synapd's activity.

Tiling + monocle layouts, per-output workspaces, XWayland, layer-shell. All shortcuts: Keybindings. Roadmap: synui/ROADMAP.md.


Features

Control panel (Super+C) — the front door. Lists every shortcut, generated from the live bind table, so it can't drift from the actual bindings.

Dock — auto-hide with hover-slide, right-click context menu, runtime pin/unpin, drag to any edge (vertical on left/right). Context menu has both Close Window and Quit All Windows.

Wallpapers (Super+W) — built-in Synapse (static) and Matrix (animated GLES2 rain, ported from the KDE matrix shader), plus a browser for ~/Pictures and friends.

Visual effects (Super+E) — a panel with a slider per effect (scanline, curvature, aberration, glitch), persisted to filters.state. It used to be a blind on/off toggle.

Power management (Super+P) — compositor-native dim / blank / lock / suspend. Retired swayidle entirely. Includes media idle-inhibit: it won't blank the screen while audio is playing.

Task manager (Ctrl+Alt+Delete or Super+T) — process table with CPU/RAM/GPU overview and per-process VRAM via dlopen'd NVML (no CUDA headers needed at build time).

Game mode (Super+G) — detects a fullscreen Xwayland client, stops synapd to free its VRAM, and holds off idle. Waybar shows an indicator ($XDG_RUNTIME_DIR/synui-game).

Screenshots — see Keybindings. Land in ~/Pictures/Screenshots and on the clipboard.

Lock screen (Super+L), security feed from synguard, neural overlay (Super+A) fed live from synapd, system tray (SNI), and cat mode (Super+Shift+C) — a procedurally-drawn cairo kitty that wanders your monitors on top of everything, because why not.


Hard-won rules for working on synui

These are compositor-specific traps that cost real days. Full catalogue in Troubleshooting.

Never block the wl_event_loop on X

Xwayland is itself a client of that event loop, and it starts lazily. A blocking xcb round-trip made from the event loop deadlocked the entire compositor at login — black screen, dead input, no core dump. Use a ready-flag plus a worker thread.

Reset signal dispositions in every child you spawn

SIG_IGN and the blocked mask survive exec(). This burned us three separate times: synui's SIGCHLD=SIG_IGN leaked into Xwayland and made it abort itself; and synui's signalfd blocked mask was inherited by every child, making every app synui launched immune to SIGTERM.

Decorative scene buffers must set point_accepts_input = false

Or they swallow clicks. (Discovered via cat mode, of all things.)

Keyboard focus takes view_surface(view), never the raw surface

Two click sites passed the raw (sub)surface to focus_view, sending wl_keyboard.enter to a render subsurface. Firefox therefore never made its persistent-storage doorhanger the active modal, so the panel was unresponsive and Tab skipped it. A doorhanger is a subsurface, not a popup — none of the popup/grab machinery applies to it.

Don't call focus_view on popup clicks

It disrupts the xdg_popup grab, which broke menu activation in Firefox.

Unconstrain nested popups too

parent_view is only set for toplevel-parented popups, so nested ones were never unconstrained and every submenu got its full requested size — waybar's 69-item application list ran off-screen instead of scrolling.

Pointer motion must be delivered during an implicit grab

Without wl_pointer.motion while a button is held, region-select (slurp) and every client-side drag are broken.

GTK3 hard-clips an over-long menu

It ignores the configure size and shows no scroll arrows. The waybar application menu is therefore paginated (25 items) and grouped by XDG category rather than being one flat 69-item list.


Config

~/.config/synui/synuirc (or /etc/synui/synuirc), plus outputs.conf for monitor layout — where primary=1 marks the primary output for Xwayland, which is what stops SDL games opening on the wrong monitor.

Session env vars live in three places: the live /usr/local/bin/synui-session and two blocks in syn-install.sh. Change one, change all three. (XCURSOR_SIZE lives here — unset, libXcursor auto-sized the cursor from the 3640px virtual screen width and Steam's cursor ballooned.)

See also: Keybindings, Architecture.

Clone this wiki locally