Problem Statement
CachyOS ships Noctalia v4.7.7 as part of its meta package cachyos-niri-noctalia. The meta package has both niri and noctalia as the name suggests.
Noctalia has shipped V5 which is a complete rewrite and a different package than the v4.7.7 train (if I could call it that).
It might take some time for CachyOS to switch from v4.7.7. I dont want to wait till then because v5.x looks sick.
Solution
Assumption
- You are using defaults that came with the meta package.
- If not, this might not exactly work as-is.
We are going to rip out old Noctalia, but the meta package lists Noctalia as a dependency, so running a remove command will fail with this error: removing noctalia-shell breaks dependency 'noctalia-shell' required by cachyos-niri-noctalia
If we force remove it, Niri will also become an orphan, so lets handle that one by one.
Saving Niri
Lets mark Niri as explicitly installed so it doesnt get orphaned.
sudo pacman -D --asexplicit niri
Ripping Old Noctalia and Meta Package
Lets also remove the meta package and niri shell, because its not really needed anymore.
sudo pacman -R cachyos-niri-noctalia noctalia-shell
New Noctalia
Note
- shelly here instead of pacman because noctalia-git is in AUR, so we need an AUR helper.
Lets install the latest noctalia. Since AUR builds locally, expect it to take a long time based on your hardware.
shelly install noctalia-git
Accomodating breaking changes
At this point new noctalia is available but since there are breaking changes between old and new version, we need to modify config files.
autostart.kdl
This file should be at ~/.config/niri/cfg/autostart.kdl
Comment out or remove the line that references noctalia-shell, should be something like spawn-sh-at-startup "qs -c noctalia-shell"
and replace it with a simple spawn-at-startup
spawn-at-startup "noctalia"
keybinds.kdl
This file should be at ~/.config/niri/cfg/keybinds.kdl
Noctalia has simplified these calls to just follow the format noctalia msg instead of the IPC system.
You can remove all the IPC calls with simple msg calls. Here is my complete kdl file for reference.
binds {
// ────────────── Keybindings ──────────────
// https://github.com/YaLTeR/niri/wiki/Configuration:-Key-Bindings
// ─── noctalia-shell keybinds ───
// https://docs.noctalia.dev/getting-started/keybinds/
Mod+Shift+ESCAPE { show-hotkey-overlay; }
// ─── Applications ───
Mod+Return hotkey-overlay-title="Open Terminal: Kitty" { spawn "kitty"; }
Mod+CTRL+Return hotkey-overlay-title="Open App Launcher: noctalia launcher" { spawn-sh "noctalia msg panel-toggle launcher"; }
Mod+B hotkey-overlay-title="Open Browser: firefox" { spawn "firefox"; }
Mod+ALT+L hotkey-overlay-title="Lock Screen: noctalia lock" { spawn-sh "noctalia msg session lock"; }
Mod+Shift+Q hotkey-overlay-title="Session Menu: noctalia sessionMenu" { spawn-sh "noctalia msg panel-toggle session"; }
// Please choose your own file manager.
Mod+E hotkey-overlay-title="File Manager: Nautilus" { spawn "nautilus"; }
// ─── Media Controls ───
XF86AudioRaiseVolume allow-when-locked=true { spawn-sh "noctalia msg volume-up"; }
XF86AudioLowerVolume allow-when-locked=true { spawn-sh "noctalia msg volume-down"; }
XF86AudioMute allow-when-locked=true { spawn-sh "noctalia msg volume-mute"; }
XF86AudioMicMute allow-when-locked=true { spawn-sh "noctalia msg mic-mute"; }
XF86AudioNext allow-when-locked=true { spawn-sh "noctalia msg media-next"; }
XF86AudioPrev allow-when-locked=true { spawn-sh "noctalia msg media-previous"; }
XF86AudioPlay allow-when-locked=true { spawn-sh "noctalia msg media-play-pause"; }
XF86AudioPause allow-when-locked=true { spawn-sh "noctalia msg media-play-pause"; }
// ─── Brightness Controls ───
XF86MonBrightnessUp allow-when-locked=true { spawn-sh "noctalia msg brightness-up"; }
XF86MonBrightnessDown allow-when-locked=true { spawn-sh "noctalia msg brightness-down"; }
// ─── Window Movement and Focus ───
Mod+Q { close-window; }
Mod+Left { focus-column-left; }
Mod+H { focus-column-left; }
Mod+Right { focus-column-right; }
Mod+L { focus-column-right; }
Mod+Up { focus-window-up; }
Mod+K { focus-window-up; }
Mod+Down { focus-window-down; }
Mod+J { focus-window-down; }
Mod+CTRL+Left { move-column-left; }
Mod+CTRL+H { move-column-left; }
Mod+CTRL+Right { move-column-right; }
Mod+CTRL+L { move-column-right; }
Mod+CTRL+UP { move-window-up; }
Mod+CTRL+K { move-window-up; }
Mod+CTRL+Down { move-window-down; }
Mod+CTRL+J { move-window-down; }
Mod+Home { focus-column-first; }
Mod+End { focus-column-last; }
Mod+CTRL+Home { move-column-to-first; }
Mod+CTRL+End { move-column-to-last; }
Mod+Shift+Left { focus-monitor-left; }
Mod+Shift+Right { focus-monitor-right; }
Mod+Shift+UP { focus-monitor-up; }
Mod+Shift+Down { focus-monitor-down; }
Mod+Shift+CTRL+Left { move-column-to-monitor-left; }
Mod+Shift+CTRL+Right { move-column-to-monitor-right; }
Mod+Shift+CTRL+UP { move-column-to-monitor-up; }
Mod+Shift+CTRL+Down { move-column-to-monitor-down; }
// ─── Workspace Switching ───
Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; }
Mod+WheelScrollUp cooldown-ms=150 { focus-workspace-up; }
Mod+CTRL+WheelScrollDown cooldown-ms=150 { move-column-to-workspace-down; }
Mod+CTRL+WheelScrollUp cooldown-ms=150 { move-column-to-workspace-up; }
Mod+WheelScrollRight { focus-column-right; }
Mod+WheelScrollLeft { focus-column-left; }
Mod+CTRL+WheelScrollRight { move-column-right; }
Mod+CTRL+WheelScrollLeft { move-column-left; }
Mod+Shift+WheelScrollDown { focus-column-right; }
Mod+Shift+WheelScrollUp { focus-column-left; }
Mod+CTRL+Shift+WheelScrollDown { move-column-right; }
Mod+CTRL+Shift+WheelScrollUp { move-column-left; }
Mod+1 { focus-workspace 1; }
Mod+2 { focus-workspace 2; }
Mod+3 { focus-workspace 3; }
Mod+4 { focus-workspace 4; }
Mod+5 { focus-workspace 5; }
Mod+6 { focus-workspace 6; }
Mod+7 { focus-workspace 7; }
Mod+8 { focus-workspace 8; }
Mod+9 { focus-workspace 9; }
Mod+CTRL+1 { move-column-to-workspace 1; }
Mod+CTRL+2 { move-column-to-workspace 2; }
Mod+CTRL+3 { move-column-to-workspace 3; }
Mod+CTRL+4 { move-column-to-workspace 4; }
Mod+CTRL+5 { move-column-to-workspace 5; }
Mod+CTRL+6 { move-column-to-workspace 6; }
Mod+CTRL+7 { move-column-to-workspace 7; }
Mod+CTRL+8 { move-column-to-workspace 8; }
Mod+CTRL+9 { move-column-to-workspace 9; }
Mod+TAB { focus-workspace-previous; }
// ─── Layout Controls ───
Mod+CTRL+F { expand-column-to-available-width; }
Mod+C { center-column; }
Mod+CTRL+C { center-visible-columns; }
Mod+Minus { set-column-width "-10%"; }
Mod+Equal { set-column-width "+10%"; }
Mod+Shift+Minus { set-window-height "-10%"; }
Mod+Shift+Equal { set-window-height "+10%"; }
// ─── Modes ───
Mod+T { toggle-window-floating; }
Mod+F { fullscreen-window; }
Mod+W { toggle-column-tabbed-display; }
// ─── Screenshots ───
CTRL+Shift+1 { screenshot; }
CTRL+Shift+2 { screenshot-screen; }
CTRL+Shift+3 { screenshot-window; }
// ─── Emergency Escape Key ───
// Use this when a fullscreen app blocks your keybinds.
// It disables any active keyboard shortcut inhibitor, restoring control.
Mod+ESCAPE allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; }
// ─── Exit / Power ───
CTRL+ALT+Delete { quit; } // Also quits Niri
Mod+Shift+P { power-off-monitors; } // Turn off screens (useful for OLED or privacy)
Mod+O repeat=false { toggle-overview; }
}
Information
- Thanks to pete at noctalia discord for reviewing and suggesting corrections. paru commands were removed. incorrect casing on meta packages were corrected from the original post.