- config.yml: default/commit -> frank-medium (dankserver); task/tiny/smol/vision -> frank-small (dankclaw-3090); vision xhigh - models.yml: add llamacpp (dankclaw-3090) provider; frank-large preserve_thinking + context notes - niri: focus-ring/border/shadow layout, hot-corners off, re-add noctalia.kdl include; blankpad eDP-1 scale 1.0 - memories: flush rollouts; retire frank_large + marreta_authentik skills; add auth-chain/kv-pool/quadlet-log skills - managed-skills: 40+ new fleet runbook skills - agent/skills: import built-in skill set
3.8 KiB
name, description
| name | description |
|---|---|
| niri-output-rotation-pinning | Rotate/re-arrange niri monitors (portrait transforms, positions, scale) persistently and verify — covers the output-block-resets-defaults trap and auto-layout reflow that flings unpinned outputs, plus the counter-clockwise transform convention. |
Rotating and pinning outputs on niri
Verified on blankpad, niri 26.04, 2026-09-15 (two PM1601 externals + eDP-1 laptop panel).
0. Ground truth first
niri msg outputs # connector names, current mode, scale, transform, logical pos/size
niri --version
Niri output names are connector names (eDP-1, DP-2, HDMI-A-1), not EDID model strings. The EDID strings printed before them in niri msg outputs are decoration — use the parenthesized name.
On blankpad the live config is split by include "./cfg/*.kdl" from ~/.config/niri/config.kdl, and cfg/display.kdl is a symlink into the dotfiles repo (~/.omp/dotfiles/zz-blankpad/niri/.config/niri/cfg/display.kdl). Edit the repo path, not the symlink target path — they are the same file, but the repo path is the one that gets committed. Check with ls -ld.
1. Transform direction is counter-clockwise
niri msg output <NAME> transform --help # "Transform to set, counter-clockwise"
| value | effect |
|---|---|
90 |
content rotated 90° CCW ⇒ the panel's top bezel sits on the LEFT |
270 |
top bezel on the RIGHT |
180 |
upside down |
flipped-90 / flipped-270 |
mirrored variants |
90 vs 270 is a physical-stand fact no tool can read (portable monitors expose no orientation in EDID/MCCS). Pick one, apply it, and give the user the one-liner to flip — don't stall on the question.
2. Two traps that bite when you edit the config
- An
output "X" { … }block resets every property you don't restate to its default. Pinning position oneDP-1without repeatingscale 1.25silently drops the laptop panel to scale 1.0. Restatescale(andmodeif you care) in every block you touch. - Niri re-runs auto-layout for outputs with no pinned position. Pinning only the externals shoved
eDP-1from0,0to3936,0(laptop became rightmost). If you want the pre-existing left-to-right order, pin every output's position.
Positions are logical pixels at each output's own scale. Original order preserved example:
output "DP-2" {
scale 1
transform "90"
position x=1536 y=0
}
output "HDMI-A-1" {
scale 1
transform "90"
position x=2736 y=0
}
output "eDP-1" {
scale 1.25 // MUST restate: dashed-out by the block otherwise
position x=0 y=0
}
x-offsets chain: eDP-1 logical width 1536 → DP-2 at 1536 → +1200 (portrait width) → HDMI-A-1 at 2736.
3. Apply and verify
niri validate -c ~/.config/niri/config.kdl # exit 0, "config is valid"
niri msg action load-config-file # live reload; load-config-file, NOT reload-config
sleep 1
niri msg outputs | grep -E '^Output|Transform|Logical|Scale'
Success looks like Logical size: 1200x1920 (swapped) plus Transform: 90° counter-clockwise on each rotated panel, with positions matching the intended chain.
One-off rotation without touching config (temporary, forgotten on next config change):
niri msg output DP-2 transform 90
4. Commit
Dotfiles repo is dank/command-center (main); push to the local Gitea is permitted.
cd ~/.omp && git pull --ff-only
git add dotfiles/zz-blankpad/niri/.config/niri/cfg/display.kdl
git commit -m "blankpad(niri): <what changed>"
git push
Pitfalls
reload-configis not a niri subcommand — it'sniri msg action load-config-file.- Never SIGUSR1 a terminal to "reload"; niri config reloads do not touch ghostty themes.
- No man page for niri on this host;
niri <sub> --helpand/usr/share/doc/niri/default-config.kdlare the docs.