Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Flags and environment

Every command-line flag and SOLIUM_* variable the compositor reads, from environment.txt, with where the code reads each one. A test fails when the code reads one this page does not list.

Flags

Every argument is checked before anything starts, and one Solium does not know is refused with exit status 2. One of --tty, --check, --check-qml, --probe, --help and --version chooses what Solium does, anywhere on the line; with none it starts a compositor: nested, as a window, when WAYLAND_DISPLAY or DISPLAY is set, and on the hardware otherwise.

--help

Print how to run Solium, its flags and the variables that change a session, and exit. Also -h. Starts nothing.

Read at cli.rs:61.

--version

Print the version, and the commit it was built from when it was built from a git checkout (solium 0.0.0 (dfc95ce)), and exit. Also -V. Starts nothing.

Read at cli.rs:62.

--tty

Run on the hardware from a free virtual terminal, taking the screen, and write the session log, $XDG_STATE_HOME/solium/session.log (or ~/.local/state/solium/session.log).

Read at cli.rs:63.

--session

Only with --tty, anywhere on the line. solium --tty --session is the user’s graphical session, and tells systemd and D-Bus so: it exports WAYLAND_DISPLAY and the rest, starts solium-session.target, and undoes both on exit. solium-session, which the session file starts, runs it this way. Without it, --tty tells nobody unless SOLIUM_SESSION_BUS names a bus.

Read at cli.rs:81, session.rs:107.

--check

Load the configuration, print every binding it registered and every one it removed, build every scene it declares at load and every pane style of your own, and exit; also the pane style and the loading scene this run’s environment names. Exits with 1 when anything fails: the configuration fails to load or sets a key nothing reads, or a scene fails to build, misses a required property, or warns while it is built and first drawn. Scenes are built in software, on one monitor. --check <file.qml> checks one QML file instead, as --check-qml does. Starts no compositor and needs no display.

Read at cli.rs:65.

--check-qml <file.qml>

The old spelling of --check <file.qml>: load one QML file in software and, for a style’s Pane.qml, every layer it names; print what went wrong; exit with 1 when anything did. A style that requires the GPU is said to, and its layers are not loaded. Starts no compositor.

Read at cli.rs:71.

--probe

Print every connector and every mode it offers, without taking the screen. Safe to run inside another session.

Read at cli.rs:64.

--probe-qml-gpu

Internal. The child process the QML GPU trial runs in; see QML on the GPU.

Read at renderer.rs:24.

--debug-mode

Add the Developer Tweaks panel, on super+shift+d. Read anywhere on the command line.

Read at cli.rs:80, dev.rs:385.

--qml <mode>

Which scene graph QML renders on: auto, gpu or software. Also written --qml=<mode>, and read anywhere on the command line. Wins over SOLIUM_QML, SOLIUM_QML_GPU and the configuration’s qml.renderer.

Read at cli.rs:85, renderer.rs:130.

Running a session

SOLIUM_LUA_INIT=<path>

Load this configuration instead of ~/.config/solium/init.lua or the shipped init.lua.

Read at script.rs:952.

SOLIUM_TERMINAL=<command line>

The terminal super+return opens, split on spaces. Unset, the shipped init.lua opens the first terminal it finds installed.

Read at init.lua:123.

SOLIUM_PANE=<name or path>

The frame style for this run, over the configuration’s pane.

Read at check.rs:384, decoration.rs:2074.

SOLIUM_DECORATION=<name or path>

The old spelling of SOLIUM_PANE. SOLIUM_PANE wins when both are set.

Read at check.rs:384, decoration.rs:2075.

SOLIUM_QML_TITLEBAR=<path>

One QML file to frame every window with, over SOLIUM_PANE and the configuration. The oldest spelling of the knob.

Read at check.rs:384, decoration.rs:1886, decoration.rs:2130.

SOLIUM_LOADING=<name or path>

The scene a window shows before its application arrives, over the configuration’s loading.scene.

Read at check.rs:387, pane.rs:1472.

SOLIUM_QML_CURSOR=<path or name>

The pointer’s scene for one run, over the configuration’s cursor.scene: drawn for every shape, ahead of any XCursor theme, and found as cursor.scene is. The shipped cursor.qml is still what is drawn with no scene and no theme.

Read at theme.rs:141.

SOLIUM_QML_PATH=<paths>

The whole QML import path, colon separated. Replaces the search rather than adding to it: the user’s ~/.config/solium/qml and the shipped QML are no longer looked in.

Read at qml.rs:903.

SOLIUM_QML=<mode>

Which scene graph QML renders on: auto, gpu or software. Below --qml, above SOLIUM_QML_GPU and qml.renderer.

Read at dev.rs:246.

SOLIUM_QML_GPU

The older spelling of SOLIUM_QML=gpu. Set to anything, it means gpu.

Read at dev.rs:257.

SOLIUM_FORM_FACTOR=<form factor>

desktop (the default), laptop, tablet or phone. Chooses the input profile: click or touch to focus, whether focus follows the pointer, natural scrolling and the drag modifier. An unknown value is logged and desktop used.

Read at profile.rs:130.

SOLIUM_DRAG_MODIFIER=<modifier>

logo (also super or meta) or alt: the key held to drag a window from anywhere in it. Over the form factor’s default.

Read at profile.rs:144.

SOLIUM_DEBUG_MODE

Set to anything, the same as --debug-mode.

Read at dev.rs:386.

SOLIUM_NO_DMABUF

Set to anything, clients are not offered linux-dmabuf and fall back to shared memory.

Read at tty.rs:1283, winit.rs:231.

SOLIUM_SESSION_BUS=<address>

The D-Bus address to tell about the session, and to own org.freedesktop.ScreenSaver on (idle.dbus_inhibit), instead of the session bus. Nested, or solium --tty without --session, this is the only way either happens. Blank counts as unset. For checking the calls against a private bus: dbus-run-session -- sh -c 'SOLIUM_SESSION_BUS=$DBUS_SESSION_BUS_ADDRESS solium'.

Read at dev.rs:183.

Hosting a shell

A shell is loaded as configuration, with shell = { scene = ... }; see Where Solium ends and Lilium begins. These change that for one run, and dev/run-shell.sh sets both.

SOLIUM_SHELL_SCENE=<file.qml>

The QML file to host as the shell, over the configuration’s shell.scene. Empty counts as unset.

Read at shell.lua:26.

SOLIUM_SHELL_WATCH=<directory>

Where to look for changed .qml files, down to four directories below it, before rebuilding a hosted scene, instead of the scene’s own directory. For a shell whose files live in a tree of their own.

Read at surface.rs:557.

Development and testing

These exist so the compositor can be driven and photographed without a hand on the keyboard. dev/README.md says how they are used. The ones marked nested only are read by the nested backend alone: on the hardware, with --tty, they do nothing.

SOLIUM_CAPTURE=<path>

Nested only. Write a rendered frame to <path> as a binary PPM.

Read at dev.rs:14.

SOLIUM_CAPTURE_AT=<ms>

Nested only. Capture at this many milliseconds after startup, instead of once a window has settled.

Read at dev.rs:86.

SOLIUM_CAPTURE_FRAMES=<n>

Nested only. Capture a burst of n frames rather than one, written beside the path SOLIUM_CAPTURE names with a number added to its stem: /tmp/frame.ppm gives /tmp/frame-000.ppm, /tmp/frame-001.ppm, ….

Read at dev.rs:23.

SOLIUM_CAPTURE_INTERVAL=<ms>

Nested only. The time between the frames of a burst. 16 by default.

Read at dev.rs:78.

SOLIUM_TRIGGER_AT=<ms>:<combo>,...

Nested only. Run what these key combinations are bound to, at these moments: 5200:super+space,6200:super+space. The binding is looked up by the name written here, so this skips what a real key goes through first: the Ctrl+Alt chords, the lock screen and the key-cap lookup that keeps bindings working under another keyboard layout.

Read at dev.rs:98.

SOLIUM_KEY_AT=<ms>:<key>,...

Nested only. Press a key and let it go at these moments, through the real input path: 1500:caps_lock,3000:shift+alt_l. A key is keysym names joined by +, pressed in the order written and let go in reverse; shift, ctrl, alt and super are the left-hand keys. Each is found in the live keymap, in any of its layouts, so Caps Lock locks Caps, an xkb layout-switch option switches the layout, and a combination a binding claims runs it, exactly as from the keyboard.

Read at dev.rs:112.

SOLIUM_CLICK_AT=<ms>:<x>,<y>;...

Nested only. Hand a press at these moments and places, separated by semicolons, to the mode that is holding the pointer, such as overview. It goes to the scripts, not through the input path: for a real press, use SOLIUM_DRAG_AT with the same point at both ends.

Read at dev.rs:121.

SOLIUM_DRAG_AT=<ms>:<x1>,<y1>><x2>,<y2>;...

Nested only. Drag the pointer from one place to another, through the real input path, the real grab and the real layout scripts.

Read at dev.rs:141.

SOLIUM_LOADING_AT=<ms>:<program>,...

Nested only. Open a window for an application that will never arrive, to exercise the loading window.

Read at dev.rs:168.

SOLIUM_OUTPUTS=<n>

Nested only. Give the nested backend n monitors, from 1 to 4, side by side in its one window.

Read at dev.rs:47.

SOLIUM_OUTPUTS_AT=<ms>:<n>,...

Nested only. Change the number of nested monitors at these moments: hotplug without a cable.

Read at dev.rs:68.

SOLIUM_MEMDIAG

Set to anything, report what the compositor is holding, once a second.

Read at dev.rs:266.

SOLIUM_PACING

Set to anything, say where a frame’s time went on the frames that took longer than the monitor’s frame interval, and say it too when a monitor flipped late, which is counted apart as late: the vblanks a monitor should have flipped at and did not, summed over the monitors, from the kernel’s flips (always 0 nested, where there are none). On a monitor with vrr on, whose vblank waits for its frame, a slow frame drawn at a flip delays the next vblank instead of missing it and is rarely counted, while one started from idle is still judged against the monitor’s fastest rate, so vrr’s late does not compare with a fixed rate’s. A line carries the slowest pass since the last line: each phase on the CPU, the three scenes Qt spent the most of it on, costliest first (qml_top, as rounded/Frame=410: each scene’s folder and file, @ the monitor it is hosted on if it is, and its microseconds), how many windows were captured (captures), and the GPU’s time for the pass (gpu, gpu_us, and gpu_prep_us for the captures), which is read a few passes later, so a line waits up to eight passes for it and goes without it (gpu="unread") after that, or sooner, still gpu="unread", if nothing is being drawn and it has still not come (always nested, where the time is read only when a pass draws); gpu reads unsupported on a GPU that cannot time itself and disjoint when its clock jumped. unread is not late, which counts flips. Nested, only the captures and, with several monitors, each monitor are timed on the GPU, not the window’s own draw. Each line also carries the GPU’s clocks as that pass ended: where they come from (clocks: nvml, i915 or none), gpu_mhz, mem_mhz (0 on i915) and NVIDIA’s pstate (-1 where unknown), sampled four times a second by a thread of their own, and none until that thread has found them, which NVML can take a second or more to do; the log says what it found when it has. Misses and late flips are counted whether or not this is set, and every session ends with one pacing line of totals.

Read at dev.rs:285.

SOLIUM_FENCE_WAIT=<on|off>

off (or 0, no, skip) drops a window capture’s fence instead of waiting for it on the CPU: the GPU orders the read after the draw on the one context. on, or unset, waits, which is the default until #59 lands. Each session’s log says which it ran with.

Read at dev.rs:340.

SOLIUM_RECAPTURE=always

Draw every window capture (a warp’s, a rounded client’s) on every pass, as before captures were kept until what they show changes. For measuring the difference on one build.

Read at dev.rs:373.

SOLIUM_PACING_CLOCKS=off

With SOLIUM_PACING, do not start the thread that samples the GPU’s clocks (NVML, or i915’s sysfs). For checking that sampling them does not itself keep the GPU out of its low-power states.

Read at clocks.rs:77.

SOLIUM_TRACE=<path>

Write one JSON line per pass (drew 0 for one in which no monitor was ready to draw), and one per page flip, to <path>, and turn SOLIUM_PACING on. Buffered and written once a second; put it on $XDG_RUNTIME_DIR. Not passed on to the programs Solium starts, so a Solium started inside a traced one does not write over its file. dev/pacing-summary.py reads it; the fields are in dev/README.md, under Measuring frame pacing on a TTY.

Read at dev.rs:296, launch.rs:45.

SOLIUM_RESIZE_TRACE=<file>

Append a per-frame trace of every resize drag to <file>.

Read at resizing.rs:1001.

Packaging

SOLIUM_DATADIR=<directory>

Read when Solium is built, not when it runs: the first place the binary looks for its qml and lua. After it come the tree the binary was built in, then ../share/solium beside the binary, then /usr/share/solium; the first that holds both is used.

Read at assets.rs:76.

Also read

Not Solium’s own, but they change what it does.

RUST_LOG=<filter>

Log levels, in tracing filter syntax. info by default.

WAYLAND_DISPLAY

With this or DISPLAY set and no backend flag given, Solium runs nested, as a window.

Read at main.rs:221, session.rs:281, open.rs:395.

DISPLAY

See WAYLAND_DISPLAY.

Read at main.rs:222, session.rs:284, open.rs:410, open.rs:411.

XDG_CONFIG_HOME

Where solium/init.lua, solium/user.lua and solium/qml are looked for; ~/.config when unset.

Read at folder.rs:66, folder.rs:395, icon.rs:86, qml.rs:944, script.rs:842, script.rs:956.

XDG_STATE_HOME

Where the session log goes; ~/.local/state when unset.

Read at main.rs:78.

XCURSOR_THEME

The pointer theme when the configuration’s cursor.theme is not set.

Read at theme.rs:139.

XCURSOR_SIZE

The pointer size when the configuration’s cursor.size is not set.

Read at theme.rs:140, theme.rs:213.

XKB_CONFIG_ROOT

Where xkb’s data is; /usr/share/X11/xkb when unset. Solium reads rules/evdev.xml there for each layout’s short name, sol.keyboard().layout_short. A layout the rules do not name, or every layout when the file is not there, gets the first two letters of its name, in capitals.