Files
Prad Nukala ee355bcfd5 Initial import: chezmoi source for CachyOS + Umbriel + Noctalia
Imported from prdlk/dotfiles master (efdd827). Drops the niri, Hyprland/Omarchy,
macOS, and Blume docs-site layers; docs/ is plain Markdown.
2026-11-02 09:14:11 -05:00

185 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Umbriel
Umbriel scrolling compositor config — Noctalia-only session, layout and springs, named scratchpads, outputs, and keybindings.
[Umbriel](https://docs.noctalia.dev/umbriel/) is a wlroots scrolling compositor from the Noctalia project. The config sets up the layout, window rules, springs, binds, and per-app scratchpads. The session starts only `noctalia`, which provides the launcher, clipboard history, polkit agent, notifications, and OSD.
Noctalia's polkit agent is off by default. `~/.config/noctalia/config.toml` (the [prdlk/noctalia](https://github.com/prdlk/noctalia) external, see [externals](../chezmoi/externals-and-ignore.md#chezmoiexternals); merged under the GUI's unmanaged `~/.local/state/noctalia/settings.toml`) sets `[shell] polkit_agent = true`, so `pkexec` and other privileged actions prompt in a Noctalia panel. `polkitd` itself is D-Bus activated (`polkit.service` is static; nothing to enable).
> [!NOTE]
> `desktop` and `laptop` roles only (`.chezmoiignore.tmpl`). `umbriel-git` comes from the AUR (`packages.arch.desktop.aur`) and pulls in its portal backend `xdg-desktop-portal-umbriel-git` (screenshots and screen sharing for portal clients). The `[cachyos]` `umbriel` build (`0.1.0.r1213`) lacks `window-move-by`, which `binds.toml` uses, and rejects the config. `umbriel-git` conflicts with it, so on a machine that already has the repo build, swap them by hand once (`yay -S umbriel-git`, accepting the removal); the package script runs `--noconfirm`, which declines that removal.
## Files
| Source (repo) | Target |
| --- | --- |
| `dot_config/umbriel/config.toml` | `~/.config/umbriel/config.toml`: includes, session, environment, input, layout, appearance, animation |
| `dot_config/umbriel/outputs.toml` | `~/.config/umbriel/outputs.toml` |
| `dot_config/umbriel/rules.toml` | `~/.config/umbriel/rules.toml`: scratchpads, window and layer rules |
| `dot_config/umbriel/binds.toml` | `~/.config/umbriel/binds.toml` |
| `dot_local/bin/executable_umbriel-launch` | `~/.local/bin/umbriel-launch` |
| `dot_local/bin/executable_umbriel-smart-move` | `~/.local/bin/umbriel-smart-move` |
| `dot_local/bin/executable_umbriel-float-square` | `~/.local/bin/umbriel-float-square` |
Umbriel watches these files and applies a valid save immediately; `umbriel config validate` checks them without a session. Include paths resolve against the symlinks in `~/.config/umbriel`, not the chezmoi source. Defining `[keybinds]` replaces Umbriel's built-in binds, so `binds.toml` is the complete set.
### Theme
`~/.config/umbriel/noctalia.toml` holds the colors. Noctalia's umbriel template writes it on every theme change and its post-hook keeps `"noctalia.toml"` last in `[include.optional]`; the file is not managed by chezmoi.
## Settings
| Area | Value |
| --- | --- |
| Keyboard | `us`, repeat delay 400 ms, rate 50, NumLock on |
| Touchpad | natural scroll, tap, left-right-middle, sensitivity 1.0 |
| Tablet, touch | mapped to `eDP-1` |
| Cursor | `Bibata_Ghost` (dark translucent Bibata, AUR `bibata-cursor-translucent`) 28, hidden while typing, follows keyboard focus (so scratchpads open on the output focus moved to). Umbriel exports it as `XCURSOR_THEME` and over XSETTINGS; GTK apps on Wayland read the GNOME settings instead, set once with `gsettings set org.gnome.desktop.interface cursor-theme Bibata_Ghost` and `… cursor-size 28` (dconf, not managed) |
| Layout | gap 8, presets 0.333 / 0.5 / 0.667, new columns 1/3 (0.8 on the laptop panel, see [Outputs](#outputs)), focus never centers, a lone column centers |
| Appearance | corner radius 10, no shadows, wallpaper-only blur on every window (radius 10, 4 passes, strong enough to hide wallpaper detail behind Brave Origin's own translucent background), tab bar hidden for one tab |
| Activation | apps may focus and reveal their windows (`focus_on_activate`), e.g. Noctalia notification actions |
| Overview | zoom 0.4; no hot corner |
| Animation | springs `0.82,1125` (open), `0.88,2025` (close), `0.85,1463` (move, overview, scratchpad), `0.78,1350` (workspaces) |
| Environment | `TERMINAL=ghostty` (default terminal), `ELECTRON_OZONE_PLATFORM_HINT=auto`, `QT_QPA_PLATFORM=wayland`, `QT_QPA_PLATFORMTHEME=kde`, `QT_STYLE_OVERRIDE=Darkly` |
Umbriel owns `XDG_CURRENT_DESKTOP`, so the config does not override it.
## Outputs
Matched by monitor identity (`umbriel outputs` → `Config name`). The external scales bring each display to about 110 logical pixels per inch (the ultrawide's native density), so windows keep their size across them. The laptop panel runs at 2 (112 logical ppi, 1280x800). It sits at the origin and every external sits directly to its left at negative x, bottoms aligned. The externals are used one at a time and share that slot.
| Display | Physical | Scale | Logical | Position | Other |
| --- | --- | --- | --- | --- | --- |
| Laptop (Tianma TL134ADXP03, `eDP-1`) | 2560x1600, 224 ppi | 2 | 1280x800 | `0, 0` | VRR in fullscreen, cursor starts here, new scrolling columns 0.8 wide |
| Apple Studio Display | 5120x2880, 218 ppi | 2 | 2560x1440 | `-2560, -640` | |
| Samsung S34CG50 ultrawide | 3440x1440@100, 110 ppi | 1 | 3440x1440 | `-3440, -640` | VRR in fullscreen, workspaces 1–9 start in dwindle |
| Portable HDMI (AOP 16PM1QB) | 1920x1080, 141 ppi, rotated 90° | 1.25 | 864x1536 | `-864, -736` | |
| Portable USB-C (ASUS MB16AC) | 1920x1080, 141 ppi | 1.25 | 1536x864 | `-1536, -64` | |
Umbriel sets the layout mode per workspace, not per output, so the ultrawide's dwindle default is nine `[[workspace]]` rules in `outputs.toml`, one for each index 1–9 on that monitor. A workspace past 9 starts in scrolling. `Mod+W` still toggles any workspace between scrolling and dwindle.
The Studio Display's phantom 640x480 connector needs no rule: Umbriel leaves connectors without a preferred mode or identity disabled.
## Scratchpads
Named scratchpads hold one app each. A window rule sends each app into its scratchpad when it opens; toggling an empty scratchpad runs `spawn_when_empty`. A shown scratchpad window floats centered on the output under the pointer at 48% × 77% of its usable area (`default_floating_size`, the last window rule in `rules.toml`: 1638×1109 on the ultrawide, 614×594 on the laptop panel, 1229×1109 on the Studio Display) over a desktop dimmed to 0.6. `animation.scratchpad.maximize` is off. The size is a default: a resident that was already open before the rule changed keeps its old geometry until it is reopened.
| Scratchpad | App id | Launch | Keys |
| --- | --- | --- | --- |
| `tern` | `so.stencil.tern` | `tern` | `Super+A`, `Super+Alt+Ctrl+H` |
| `claude` | `com.anthropic.Claude` | `claude-desktop` | `Super+Alt+Ctrl+L`, `Super+Ctrl+A` |
| `fastmail` | `com.fastmail.Fastmail` / `com-fastmail-fastmail` | `gtk-launch com.fastmail.Fastmail` | `Super+Alt+Ctrl+E` |
| `beeper` | `Beeper` | `gtk-launch beeper` | `Super+Alt+Ctrl+M`, `Super+Alt+Ctrl+B` |
| `home` | `brave-home.google.com__*` | `gtk-launch 'Google Home'` | `Super+Ctrl+H` |
| `lmstudio` | `ai.elementlabs.lmstudio` | `gtk-launch ai.elementlabs.lmstudio` | `Super+Ctrl+L` |
## Window rules
| Match | Rule |
| --- | --- |
| every window | blur |
| `Folo`, `Spotify`, `zen`, `brave-origin`, `gemini-desktop`, `claude-desktop`, `kitty*`, `zed`, `obsidian`, `Beeper`, `chromium`, `com.mitchellh.ghostty` | opacity 0.9, tiled, focused |
| `brave-origin`, `zen`, `chromium` | opacity 0.97 (overrides the 0.9 above) |
| `dev.noctalia.Noctalia` | floating 1080 × 920 |
| `dev.noctalia.UmbrielSharePicker` | floating 800 × 600 |
| `io.github.lgse.Strata`, `org.gnome.Nautilus`, `com.gabm.satty` | floating, half the output wide, focused |
| `brave-youtube.com__*` | floating, pinned, 30% × 30%, 10 px from the bottom-left |
| title `Picture-in-Picture` / `Picture in picture` | floating, unfocused, opaque, 24 px from the top-right of `eDP-1` |
| YouTube and chat/mail/dashboard apps (`chromium`, Calendar, Discord, Slack, Gemini, Hermes, Todoist, Cloudflare web apps) | laptop panel, workspace 1, maximized |
| `zed`, `obsidian`, sticky notes, `vacuumtube`, `Fladder`, `kitty`, `kitty-herdr`, `kitty-tmux` | Apple Studio Display |
| the six scratchpad apps | their scratchpad, floating 48% × 77% centered |
Noctalia's bar, panels, notifications, dock, OSD, and desktop widgets get blur through a layer rule.
## Keybindings
`Mod` is Super.
### Shell and session
| Keys | Action |
| --- | --- |
| `Mod+Space` | Noctalia launcher |
| `Mod+Shift+Space` | Noctalia launcher, emoji search (`/emo`) |
| `Super+Ctrl+Shift+BackSpace` | Noctalia launcher, session actions (`/session`: lock, suspend, reboot, shutdown, logout) |
| `Mod+P` | Noctalia clipboard history |
| `Mod+Period` / `Mod+Comma` | Noctalia control center / settings |
| `Super+Alt+Ctrl+N` | Noctalia notes panel |
| `Mod+Shift+B` | Noctalia bookmarks panel (`dunarand/bookmarks` plugin) |
| `Mod+Ctrl+R` | ostt recorder plugin |
| `Mod+Tab` | overview |
| `Mod+Shift+Q` | Noctalia session menu |
| `Mod+Shift+E` | quit Umbriel (asks first) |
| `Mod+Escape` | pass shortcuts through to the focused app (works while inhibited) |
| `Mod+S`, `Print` | region screenshot |
| `Mod+Ctrl+S`, `Ctrl+Print` | focused-monitor screenshot |
| `Mod+Ctrl+Shift+S` | all-monitors screenshot |
| `Mod+F24` | voxtype dictation (`--profile hermes`) |
| media, volume, brightness keys | `noctalia msg …`, also on the lock screen |
### Apps
`umbriel-launch PATTERN COMMAND…` focuses the next window whose app id matches `PATTERN` (case-insensitive), cycling on repeated presses, and runs `COMMAND` through `umbriel msg spawn` when none is open. It skips scratchpad windows. The binds call it as `~/.local/bin/umbriel-launch` because the session `PATH` has no `~/.local/bin`.
| Keys | Cycles | Launches |
| --- | --- | --- |
| `Super+Alt+Ctrl+J` | Ghostty, kitty, alacritty | `ghostty` |
| `Super+Alt+Ctrl+K` | browsers: Brave Origin, Chromium, Firefox (not web apps) | `brave-origin` |
| `Super+Alt+Ctrl+G` | Ghostty | `ghostty` |
| `Super+Alt+Ctrl+O` | Obsidian | `obsidian` |
| `Super+Alt+Ctrl+F` | strata | `gtk-launch io.github.lgse.Strata` |
| `Super+Alt+Ctrl+W` | tldraw offline | `gtk-launch tldraw-offline` |
| `Super+Alt+Ctrl+T` | Todoist | `gtk-launch todoist` |
| `Super+Alt+Ctrl+Y` | web apps (`webapp-*`, `chrome-*`, `brave-*__*`) | `gtk-launch YouTube` |
| `Super+Alt+Ctrl+Space` | Sticky Notes Canvas | `gtk-launch io.github.faridjaff.StickyNotesCanvas` |
| `Super+Ctrl+G` | Gemini | `gemini-desktop` |
| `Mod+Shift+G` | — | Goliath kitty (`--class=kitty-goliath`) |
### Windows and layout
| Keys | Action |
| --- | --- |
| `Mod+H` / `Mod+L` | focus left / right, or the output on that side at the strip's edge |
| `Mod+J` / `Mod+K` | focus down / up, or the next / previous workspace at the edge |
| `Mod+BackSpace` | previously focused window |
| `Mod+WheelUp` / `Mod+WheelDown` | focus left / right |
| `Mod+Left` / `Mod+Right` / `Mod+Up` | focus the output in that direction |
| `Mod+O`, `Super+Ctrl+J` / `Super+Ctrl+K` | next / previous output |
| `Mod+Shift+H` / `Mod+Shift+L` | [smart move](#smart-move) left / right: consume or expel, then on to the next output |
| `Super+Ctrl+Shift+H` / `Super+Ctrl+Shift+L` | move column first / last |
| `Mod+Shift+J` / `Mod+Shift+K` | move column to next / previous workspace |
| `Mod+Shift+Down` / `Mod+Shift+Up` | move column to the right / left output |
| `Mod+Shift+O`, `Mod+Ctrl+Shift+J` / `Mod+Ctrl+Shift+K` | move window to next / previous output |
| `Mod+R` / `Mod+Shift+R` | cycle width / height presets |
| `Alt+Shift+H` / `Alt+Shift+L` | width −10% / +10% |
| `Alt+Shift+J` / `Alt+Shift+K` | height −10% / +10% |
| `Alt+H` / `Alt+J` / `Alt+K` / `Alt+L` | move the focused floating window 50 px left / down / up / right (`window-move-by`, held keys repeat; kept inside the usable area) |
| `Mod+F` | full-width column |
| `Mod+Shift+F` | maximize to the output edges |
| `Mod+Ctrl+F` | fullscreen |
| `Mod+C` | floating window: [square it](#float-square) at the usable height minus 4 px top and bottom, centered; tiled: center column |
| `Mod+T` | toggle floating |
| `Mod+W` | toggle the workspace between the scrolling and dwindle layouts |
| `Mod+G` | tab the focused window with the windows stacked in its column, or stack a tab group again (scrolling layout; dwindle has no columns). Windows join a group by dragging onto its tab bar |
| `Mod+Q` | close window |
| `Mod+1`…`Mod+9`, `Alt+Q W E R Y U I O` | workspace 1–9 / 1–8 |
| `Mod+Shift+1`…`9`, `Alt+Shift+Q`…`O` | move window to that workspace |
Workspaces are dynamic per output.
### Smart move
`umbriel-smart-move left|right` consumes or expels the window left or right and continues across outputs. In the scrolling layout it picks one action for the focused window:
| Focused window | Action |
| --- | --- |
| stacked with other windows in its column | expel it to a new column on that side |
| alone, with a column on that side | consume it into that column |
| alone, at the strip's end | move it to the output on that side (nothing at the outermost output) |
Two presses step a window past its neighbour: the first stacks it into the neighbour's column, the second expels it on the far side. On dwindle and master workspaces it runs `window-move-or-output-left/right`. Floating and scratchpad windows stay put.
### Float square
`umbriel-float-square` (`Mod+C`) acts on the window with keyboard focus (`.active` in `umbriel windows --json`). A floating window becomes a square whose side is the output's usable height (below Noctalia's bar) minus 4 px above and below (`PAD`): `window-set-secondary-extent` and `window-set-primary-extent` get that side as a fraction of the usable height and width. The script then waits up to 1 s for the client to commit the new width, because `window-center` centers the committed size, and centers it. On the laptop panel that is 764×764 at y 32; on the ultrawide 1404×1404. A tiled window gets `column-center`, the previous `Mod+C`.