--- title: Umbriel description: Umbriel scrolling compositor config — Noctalia-only session, niri layout and springs, Hyprland-style named scratchpads, outputs, and keybindings. --- [Umbriel](https://docs.noctalia.dev/umbriel/) is a wlroots scrolling compositor from the Noctalia project. The config ports the [niri](/desktop/niri) layout, rules, springs, and binds, and adds the per-app scratch workspaces from [Hyprland](/desktop/hyprland) as Umbriel scratchpads. The session starts only `noctalia`: its launcher, clipboard history, polkit agent, notifications, and OSD replace vicinae, cliphist, and polkit-gnome. :::note Linux `desktop` and `laptop` roles only (`.chezmoiignore.tmpl`). `umbriel` and its portal backend `xdg-desktop-portal-umbriel` (screenshots and screen sharing for portal clients) come from the `[cachyos]` repo (`packages.arch.desktop.cachyos`); the AUR `umbriel` is a placeholder and `umbriel-git` conflicts with the repo build, so other Arch machines install them by hand. ::: ## 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` | 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 [#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 | From | | --- | --- | --- | | Keyboard | `us`, repeat delay 400 ms, rate 50, NumLock on | niri | | Touchpad | natural scroll, tap, left-right-middle, sensitivity 1.0 | niri | | Tablet, touch | mapped to `eDP-1` | niri | | Cursor | `capitaine-cursors-light` 24, hidden while typing, follows keyboard focus (so scratchpads open on the output focus moved to) | niri, Umbriel | | Layout | gap 8, presets 0.333 / 0.5 / 0.667, new columns 1/3 on every output, focus never centers, a lone column centers | niri | | Appearance | corner radius 10, no shadows, wallpaper-only blur on every window, tab bar hidden for one tab | niri | | Activation | apps may focus and reveal their windows (`focus_on_activate`), e.g. Noctalia notification actions | niri `honor-xdg-activation-with-invalid-serial` | | Overview | zoom 0.4; no hot corner | niri | | Animation | springs `0.82,1125` (open), `0.88,2025` (close), `0.85,1463` (move, overview, scratchpad), `0.78,1350` (workspaces) | niri | | Environment | `TERMINAL=ghostty` (default terminal), `ELECTRON_OZONE_PLATFORM_HINT=auto`, `QT_QPA_PLATFORM=wayland`, `QT_QPA_PLATFORMTHEME=kde`, `QT_STYLE_OVERRIDE=Darkly` | niri, plus `TERMINAL` | Umbriel owns `XDG_CURRENT_DESKTOP`, so niri's override is not carried over. niri's `XDG_MENU_PREFIX`/`kbuildsycoca6` startup (Dolphin associations) and the `INIR_*` quickshell variables are dropped. ## 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 Studio Display and ultrawide match Hyprland. The laptop panel runs at 1.5 (149 logical ppi), denser than the externals, because scale 2 left too little room. 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 | 1.5 | 1706x1066 | `0, 0` | VRR in fullscreen, cursor starts here | | Apple Studio Display | 5120x2880, 218 ppi | 2 | 2560x1440 | `-2560, -374` | | | Samsung S34CG50 ultrawide | 3440x1440@100, 110 ppi | 1 | 3440x1440 | `-3440, -374` | VRR in fullscreen | | Portable HDMI (AOP 16PM1QB) | 1920x1080, 141 ppi, rotated 90° | 1.25 | 864x1536 | `-864, -470` | | | Portable USB-C (ASUS MB16AC) | 1920x1080, 141 ppi | 1.25 | 1536x864 | `-1536, 202` | | The Studio Display's phantom 640x480 connector, which niri switched off as `DP-5`, needs no rule: Umbriel leaves connectors without a preferred mode or identity disabled. ## Scratchpads Named scratchpads replace Hyprland's `special:*` workspaces and `omarchy-toggle-scratch`. A window rule sends each app into its scratchpad when it opens; toggling an empty scratchpad runs `spawn_when_empty`. Shown scratchpads are maximized over a desktop dimmed to 0.6, on the output under the pointer. | 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 | | `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 (Hyprland) | | 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 | Noctalia's bar, panels, notifications, dock, OSD, and desktop widgets get blur through a layer rule. ## Keybindings `Mod` is Super. Where niri and Hyprland bound a key differently, niri's bind wins, except the scratchpad keys above, which follow Hyprland. ### Shell and session | Keys | Action | | --- | --- | | `Mod+Space` | Noctalia launcher | | `Mod+Shift+Space` | Noctalia launcher, emoji search (`/emo`) | | `Mod+P` | Noctalia clipboard history | | `Mod+Period` / `Mod+Comma` | Noctalia control center / settings | | `Super+Alt+Ctrl+N` | Noctalia notes panel | | `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` | Brave Origin | `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` | move column left / right | | `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% | | `Mod+F` | full-width column | | `Mod+Shift+F` | maximize to the output edges | | `Mod+Ctrl+F` | fullscreen | | `Mod+C` | center column | | `Mod+Ctrl+O` | toggle floating | | `Mod+W` | toggle the workspace between the scrolling and master layouts | | `Mod+Shift+W` | tab / untab the column | | `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. Not carried over: niri's named `w`/`h`/`x` workspaces (`niri-dynamic-workspaces`), center-visible-columns, window-only screenshots, the vicinae window switcher (use the overview), the Linear and AI-cycle launchers whose keys now toggle scratchpads, and the Omarchy-only Hyprland binds (`omarchy-pip`, `omarchy-summon`, notification dismiss, strata in the terminal's cwd).