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.