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.