7.4 KiB
7.4 KiB
name, description
| name | description |
|---|---|
| niri-config-edit-validate | Locate, edit, validate, and commit niri compositor config on Frank's workstations: desk/display profiles, EDID-keyed outputs, layout, keybind grepping, dotfiles mirror, noctalia.kdl last-include color override, forced hot-reload. |
Editing niri config on Dank workstations
Layout of the config
- Live config:
~/.config/niri/config.kdlis a thin file ofinclude "./cfg/*.kdl"lines. Never conclude "not bound" from grepping onlyconfig.kdl— keybinds live incfg/keybinds.kdl, rules incfg/rules.kdl, layout incfg/layout.kdl, etc. Grep~/.config/niri/cfg/recursively. - Include order wins:
config.kdlends withinclude "noctalia.kdl"— a hand-written accent overlay at~/.config/niri/noctalia.kdlthat re-declareslayout { focus-ring/border/tab-indicator/insert-hint }+recent-windows.highlightcolors and BEATS everycfg/layout.kdlcolor edit (observed 2026-10-18: focus-ring color edits to layout.kdl appeared to "not reload" while this file silently repainted them red). Before changing any accent/outline color, grep the WHOLE~/.config/niri/tree (not justcfg/) for the property and fix the LAST includer. Tracked in repo atdotfiles/zz-blankpad/niri/.config/niri/noctalia.kdl; live file is NOT a symlink — sync bycpanddifflike the rest. - niri notation:
Mod= Super/Win key. Chords likeMod+R { switch-preset-column-width; }. ~/.config/niriis a REAL directory, not a symlink; the version-controlled copies are a partial mirror under~/.omp/dotfiles/zz-blankpad/niri/.config/niri/. Trees can drift: diff them before/after edits. (Hardlink wiring is FRAGILE — editor/agent atomic-rename writes silently break hardlinks; verify live↔mirror by CONTENT diff, never by link trust.) On blankpad thecfg/*.kdlentries are symlinks into the repo (dotfiles/niri/...base +zz-blankpadoverrides) — edit through them freely;noctalia.kdlandconfig.kdlare the plain-file exceptions.
Desk/display profiles (monitor arrangement)
- Profiles:
cfg/desk-<n>-<name>.kdl(e.g.desk-1-home.kdl,desk-2-portable.kdl); ACTIVE profile is symlinked ascfg/display.kdl—readlinkit to know which.scripts/desk.shmanages switching;desk.sh captureprints connected outputs' EDID long names. - Panels are keyed by EDID long name (
output "Lenovo Group Limited 0x40A9 Unknown"= the laptop eDP-1 panel), not connector — connector names reshuffle between desks. Long-name blocks BEAT connector-keyed blocks when both match one output (legacy connector blocks likeoutput "eDP-1"linger as duplicates; niri applies the EDID block'sposition). - Position math: x,y = top-left of each output in the logical layout; right edge = x + mode width. To place panel A left of panel B:
A.x = B.x - A.width; bottom-align:A.y = B.y + (B.height - A.height). - Verify:
niri validate→ hot-reload →niri msg outputs | grep -iE 'Output |Position'(printsLogical position: x, y).
Schema gotchas (niri 26.04)
preset-column-widthsANDpreset-window-heightsare children oflayout { }as SIBLING blocks — wiki wording misleads; nesting orwindow-ruleplacement failsniri validatewithexpected one of proportion, fixed/unexpected node.- Preset list order = cycle order for
Mod+R(switch-preset-column-width);Mod+Shift+Rcycles backwards. WITH custom preset lists the cycle contains ONLY the configured presets — no implicit full/maximize tail (verified: [0.25, 0.5] cycles period 2). Maximize = separateMod+Fmaximize-column. Built-in defaults without the node: 1/3, 1/2, 2/3. - WITHOUT
preset-window-heights,switch-preset-window-heightFALLS BACK to the width presets — user sees width-fractions as heights; define the node explicitly to stop it. - Ground truth for node placement: the binary's embedded template —
grep -a -B4 -A8 "preset-column-widths {" $(which niri). - Window outlines: base geometry (
width,off) lives incfg/layout.kdlfocus-ring/border; COLORS effectively live innoctalia.kdl(see include-order law).border { off }+ focus-ring active = the visible outline. Frank's look since 2026-10-18: amber-orange#ff8c00, width 4 (active+urgentin noctalia.kdl; tab-indicator/insert-hint/recent-windows stay red#f43841by choice).
Workflow
- Edit the live file under
~/.config/niri/cfg/(symlinked = repo file; exceptnoctalia.kdl, edit live thencpto mirror). niri validate(exit 0 + "config is valid") — mandatory before done.- Hot-reload is NOT reliable after harness edits (atomic-rename writes are missed by niri's watcher; user then tests against the OLD config and reports "no change"). ALWAYS follow with
niri msg action load-config-file(NOTreload-config). - Sync changed file into the mirror:
cp ~/.config/niri/cfg/<f>.kdl ~/.omp/dotfiles/zz-blankpad/niri/.config/niri/cfg/<f>.kdl(repo root is~/.omp, branchmain, remote = dankclaw Giteadank/command-center; push there is pre-authorized). Verify bydiff, not by cp success. - Untracked mirror files:
config.kdl,noctalia.kdl,animation.kdl,input.kdl,display.kdl(symlink target) — flag drift, don't silently add; when a live-only file turns out to be load-bearing (likenoctalia.kdlwas), commit the first durable copy intodotfiles/zz-blankpad/niri/.config/niri/. - Mirror files often carry pre-existing uncommitted drift (desk.sh captures); a commit of your edit folds it in — say so in the report/commit body.
Live-behavior verification without disturbing Frank's windows
niri msg --json <subcmd>— the--jsonflag goes BEFORE the subcmd.- Targeting differs per action: WINDOW-scoped actions take
--id <window-id>(NOT--window) — e.g.switch-preset-window-height --id N. COLUMN-scoped actions (switch-preset-column-width,set-column-width,maximize-column) have NO id — they hit the FOCUSED column; onlyset-column-width <px|±N%>positional CHANGE, no flags. - Spawned test apps do NOT reliably take focus, so blind
spawn + actioncycles resize whatever Frank is looking at. For column actions you mustfocus-window --id Nfirst — and that STEALS focus; if Frank is actively testing chords, your probes and his keystrokes interleave and corrupt both. STOP probing, deliver config + validate, and have him press the chord himself. niri msg --json focused-windowcan report a different window than assumed (focus moves); for per-window measurement readniri msg --json windowsand filter byid. Present height of proportion p with gaps g over work-area H renders ≈ p*(H+g) − g. NOTE (measured 2026-10-18): this build'swindows/focused-windowJSON returnsx/y/width/height = null— pixel-sampling the outline color from screenshots is not viable; ask Frank to eyeball afterload-config-fileinstead of burning turns on capture forensics.- If Frank reports "still seeing old values" after a config edit: run
load-config-filefirst, then verify empirically before believing anything else — and checknoctalia.kdlinclude-order override BEFORE suspecting the reload.
"What does chord X do?" triage
For "mod+" questions, check in order: ~/.config/niri/cfg/keybinds.kdl (compositor wins first), terminal configs (~/.config/ghostty, foot, kitty), tmux, then omp TUI chords (omp://keybindings.md; modifiers are ctrl/shift/alt/super only, no Mod; Ctrl+R=history search, Alt+R=app.retry).