Skip to content

jutraim/niri-caelestia-shell

 
 

Repository files navigation

🌌 Niri-Caelestia Shell

GitHub last commit GitHub Repo stars GitHub repo size

A Quickshell-based desktop environment forked from Caelestia Shell, adapted to run with the Niri window manager. This fork keeps the dashboard-based workflow while experimenting with new sidebar features and Niri.

out.mp4

Caution

This is my personal thingy and it's STILL WORK IN PROGRESS.

Due to civil unrest in my country I don't have much time to boot up my PC so I update slowly :/

This repo is ONLY for the desktop shell of the caelestia dots. For the default caelestia dots, head to the main repo instead.

Warning

HELP REQUIRED!

I skipped unneccesary commit from original shell named: "bar/workspaces: add special ws overlay" and "bar/workspaces: better scroll" because there is no special workspace in Niri.

Unfortunately, I skipped an important commit from original shell named: "bar: per-monitor workspaces option (#394)"

  • Reason: I don't have multi monitor so I'm not sure if this actually works, I might break stuff :/. I need help implementing that feature :)

✨ What’s Different in This Fork?

Replaces Hyprland with Niri as the window manager.

Dashboard

  • Window switch popup

    • Dashboard is now opened after clicking on the popup instead of completely popping up and taking up half the screen.
    • Window decorations for pinning, hovering window, toggling fullscreen, and closing the window.
  • Experimental Niri management tab in dashboard

    • Niri IPC command buttons for focused workspace
    • Needs re-design

Sidebar

  • Workspace bar refactor (WIP)
    • Program Icon support instead of Material Font
    • Switch to window by clicking
    • Right click context menu
      • Allow performing Niri IPC operations in context menu
    • Reorder window in workspace by drag&drop
    • Grouping windows of same program
    • Layout sensitive icons
    • Needs rewrite

Misc

    • Niri event parser for Quickshell
    • Task manager (GPU/CPU/Memory monitoring, still improving)
    • Collapsible container UI element
    • Application dock
    • Searching programs in Niri overview

Note

Some Caelestia features are dropped or WIP due to Niri limitations. See known issues


📦 Dependencies

You need both runtime dependencies and development headers.


  • All dependencies in plain text:
    • quickshell-git networkmanager fish glibc qt6-declarative gcc-libs cava libcava aubio libpipewire lm-sensors ddcutil brightnessctl material-symbols caskaydia-cove-nerd grim swappy app2unit libqalculate

Note

Unlike the default shell, caelestia-cli is not required for Niri.

Detailed info about all dependencies

Core Dependencies 🖥️

Package Usage
quickshell-git Must be the git version
networkmanager Network management
fish Terminal
glibc C library (runtime dependency)
qt6-declarative Qt components
gcc-libs GCC runtime

Audio & Visual 🎵

Package Usage
cava Audio visualizer
libcava Visualizer backend
aubio Beat detector
libpipewire Media backend
lm-sensors System usage monitoring
ddcutil Monitor brightness control
brightnessctl Brightness control

Fonts 🔣

Package Usage
material-symbols Icon font
caskaydia-cove-nerd Monospace font

Screenshot & Utilities 🧰

Package Usage
grim Screenshot tool
swappy Screenshot annotation
app2unit Launch apps
libqalculate Calculator

BUILD dependencies 🏗️

Package Usage
cmake Build tool
ninja 🥷

Manual installation

To install the shell manually, install all dependencies and clone this repo to $XDG_CONFIG_HOME/quickshell/niri-caelestia-shell. Then simply build and install using cmake.


⚡ Installation

Note

There is NO package manager installation support yet because... 🤔

Manual Build

  1. Install dependencies.

  2. Clone the repo:

    cd $XDG_CONFIG_HOME/quickshell
    git clone https://github.com/jutraim/niri-caelestia-shell
  3. Build:

    cd $XDG_CONFIG_HOME/quickshell/niri-caelestia-shell
    cmake -B build -G Ninja \
      -DCMAKE_BUILD_TYPE=Release \
      -DCMAKE_INSTALL_PREFIX=$HOME \
      -DINSTALL_QSCONFDIR=$HOME/.config/quickshell/niri-caelestia-shell
    cmake --build build
    cmake --install build

    It's trying to install into system paths (/usr/lib/caelestia/...), so grab the necessary permissions or use sudo while installing.

    If you get VERSION is not set and failed to get from git error, that means I forgot to tag version. You can do git tag 1.1.1 to work around it :)

🔃 Updating

You can update by running git pull in $XDG_CONFIG_HOME/quickshell/niri-caelestia-shell.

cd $XDG_CONFIG_HOME/quickshell/niri-caelestia-shell
git pull


🚀 Usage

The shell can be started via the quickshell -c niri-caelestia-shell -n command or qs -c niri-caelestia-shell -n on your preferred terminal.

(qs and quickshell are interchangable.)

  • Example line for niri config.kdl to launch the shell at startup:

    spawn-at-startup "quickshell" "-c" "niri-caelestia-shell" "-n"
    

Custom Shortcuts/IPC

All keybinds are accessible via Quickshell IPC msg.

All IPC commands can be called via quickshell -c niri-caelestia-shell ipc call ...

  • For example:

    qs -c niri-caelestia-shell ipc call mpris getActive <trackTitle>
  • Example shortcut in config.kdl to toggle the launcher drawer:

    Mod+Space { spawn  "qs" "-c" "niri-caelestia-shell" "ipc" "call" "drawers" "toggle" "launcher"; }
    Mod+Space hotkey-overlay-title="Caelestia app launcher" { spawn-sh "qs -c niri-caelestia-shell ipc call drawers toggle launcher"; }

The list of IPC commands can be shown via qs -c shell ipc show.


Ipc Commands
❯ qs -c shell ipc show
target picker
  function openFreeze(): void
  function open(): void
target drawers
  function list(): string
  function toggle(drawer: string): void
target lock
  function unlock(): void
  function isLocked(): bool
  function lock(): void
target wallpaper
  function get(): string
  function set(path: string): void
  function list(): string
target notifs
  function clear(): void
target mpris
  function next(): void
  function previous(): void
  function getActive(prop: string): string
  function playPause(): void
  function pause(): void
  function stop(): void
  function list(): string
  function play(): void

⚙️ Configuration

Config lives in:

~/.config/caelestia/shell.json
Example JSON
{
    "appearance": {
        "anim": {
            "durations": {
                "scale": 1
            }
        },
        "font": {
            "family": {
                "material": "Material Symbols Rounded",
                "mono": "CaskaydiaCove NF",
                "sans": "Rubik"
            },
            "size": {
                "scale": 1
            }
        },
        "padding": {
            "scale": 1
        },
        "rounding": {
            "scale": 1
        },
        "spacing": {
            "scale": 1
        },
        "transparency": {
            "enabled": false,
            "base": 0.85,
            "layers": 0.4
        }
    },
    "general": {
        "apps": {
            "terminal": [
                "foot"
            ],
            "audio": [
                "pavucontrol"
            ]
        }
    },
    "background": {
        "desktopClock": {
            "enabled": false
        },
        "enabled": true,
        "visualiser": {
            "enabled": true,
            "autoHide": true,
            "rounding": 1,
            "spacing": 1
        }
    },
    "bar": {
        "clock": {
            "showIcon": false
        },
        "dragThreshold": 20,
        "entries": [
            {
                "id": "logo",
                "enabled": true
            },
            {
                "id": "workspaces",
                "enabled": true
            },
            {
                "id": "spacer",
                "enabled": true
            },
            {
                "id": "activeWindow",
                "enabled": true
            },
            {
                "id": "spacer",
                "enabled": true
            },
            {
                "id": "tray",
                "enabled": true
            },
            {
                "id": "clock",
                "enabled": true
            },
            {
                "id": "statusIcons",
                "enabled": true
            },
            {
                "id": "power",
                "enabled": true
            },
            {
                "id": "idleInhibitor",
                "enabled": false
            }
        ],
        "persistent": false,
        "showOnHover": true,
        "status": {
            "showAudio": false,
            "showBattery": true,
            "showBluetooth": true,
            "showMicrophone": false,
            "showKbLayout": false,
            "showNetwork": true
        },
        "tray": {
            "background": true,
            "recolour": true
        },
        "workspaces": {
            "activeIndicator": true,
            "activeLabel": "󰮯",
            "activeTrail": false,
            "groupIconsByApp": true,
            "groupingRespectsLayout": true,
            "windowRighClickContext": true,
            "label": "",
            "occupiedBg": true,
            "occupiedLabel": "",
            "showWindows": true,
            "shown": 4,
            "windowIconImage": true,
            "focusedWindowBlob": true,
            "windowIconGap": 0,
            "windowIconSize": 30
        }
    },
    "border": {
        "rounding": 25,
        "thickness": 10
    },
    "dashboard": {
        "mediaUpdateInterval": 500,
        "showOnHover": true
    },
    "launcher": {
        "actionPrefix": ">",
        "dragThreshold": 50,
        "vimKeybinds": false,
        "enableDangerousActions": false,
        "maxShown": 8,
        "maxWallpapers": 9,
        "specialPrefix": "@",
        "useFuzzy": {
            "apps": false,
            "actions": false,
            "schemes": false,
            "variants": false,
            "wallpapers": false
        },
        "showOnHover": false
    },
    "lock": {
        "recolourLogo": false
    },
    "notifs": {
        "actionOnClick": false,
        "clearThreshold": 0.3,
        "defaultExpireTimeout": 5000,
        "expandThreshold": 20,
        "expire": false
    },
    "osd": {
        "enabled": true,
        "enableBrightness": true,
        "enableMicrophone": true,
        "hideDelay": 2000
    },
    "paths": {
        "mediaGif": "root:/assets/bongocat.gif",
        "sessionGif": "root:/assets/kurukuru.gif",
        "wallpaperDir": "~/Pictures/Wallpapers"
    },
    "services": {
        "audioIncrement": 0.1,
        "defaultPlayer": "Spotify",
        "gpuType": "",
        "playerAliases": [
            {
                "from": "com.github.th_ch.youtube_music",
                "to": "YT Music"
            }
        ],
        "weatherLocation": "",
        "useFahrenheit": false,
        "useTwelveHourClock": false,
        "smartScheme": true,
        "visualiserBars": 45
    },
    "session": {
        "dragThreshold": 30,
        "vimKeybinds": false,
        "commands": {
            "logout": [
                "loginctl",
                "terminate-user",
                ""
            ],
            "shutdown": [
                "systemctl",
                "poweroff"
            ],
            "hibernate": [
                "systemctl",
                "hibernate"
            ],
            "reboot": [
                "systemctl",
                "reboot"
            ]
        }
    }
}
Example Nix Home Manager

I don't have nix, plz help :D

{
  programs.niri-caelestia-shell = {
    enable = true;
    with-cli = true;
    settings.theme.accent = "#ffb86c";
  };
}

🎭 PFP/Wallpapers

The profile picture for the dashboard is read from the file ~/.face, so to set it you can copy your image to there or set it via the dashboard. It's not a directory.

The wallpapers for the wallpaper switcher are read from ~/Pictures/Wallpapers by default. To change it, change the wallpapers path in ~/.config/caelestia/shell.json.

To set the wallpaper, you can use the app launcher command > wallpaper.


🧪 Known Issues

  1. Multi-monitor support is currently hardcoded :(
  2. Task manager has no Intel GPU support.
  3. Workspace bar needs refactoring at the moment.
  4. Picker (screenshot tool) window grabbing is WIP due to Niri limitations.
  5. Focus grabbing for Quickshell windows (power menu, task manager, settings) behaves awkwardly because of Niri limitations.
  6. Quickshell may occasionally crash because of upstream issues (it re-opens automagically)
  7. I'm not happy that you have to build it to be able to use it, so I might revert.
  8. Some dependencies aren't actually required but I keep them because the original repo still has them.
  9. I haven't touched theming, be cautious.

❓ FAQ

Q: Can I theme it? A: Yes, via shell.json (or Nix options if you use Home Manager).

Q: Why does my task manager Intel GPU messed-up? A: GPU monitoring is limited; Intel isn’t supported yet.

Q: Why does it take so long for you to update? A: Civil unrest in my country 😥


🙏 Credits

  • Quickshell – Core shell framework
  • Caelestia – Original project
  • Niri – Window manager backend
  • All upstream contributors :)

📈 Useless chart

Star History Chart

About

A very segsy desktop shell ported to niri wm.

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

No contributors

Languages

  • QML 86.0%
  • JavaScript 6.3%
  • C++ 6.1%
  • Nix 1.0%
  • CMake 0.4%
  • Shell 0.1%
  • GLSL 0.1%