No description
  • QML 67%
  • C++ 21.1%
  • JavaScript 4.4%
  • Python 4.1%
  • Rust 1.2%
  • Other 2.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-07-10 18:19:23 +02:00
.gitea hotfix(bugreport): adding optional input field; which init system? 2026-07-10 12:07:27 +02:00
assets remove unrelated directory 2026-07-10 15:00:02 +02:00
ci update to clang-tidy + workflow improvement cpp build & lint check (#130) 2026-06-29 22:10:26 +02:00
cli chore: format test files 2026-07-08 17:01:25 +02:00
Components fix: text input field bounds 2026-07-09 14:20:06 +02:00
Config fix: add generic gpu vram support 2026-07-03 12:28:54 +02:00
Daemons added services page + rename barConfig json property to bar, migration helper function 2026-06-24 15:30:33 +02:00
Drawers better ddcutil handling, revert to using onMoved brightness slider, fix osd region 2026-07-08 16:17:37 +02:00
Effects initial commit for settings revamp 2026-06-23 16:22:56 +02:00
Greeter feat: greeter support hyprland lua 2026-07-03 15:52:27 +02:00
Helpers feat: import M3Shapes, M3 loading indicator and weather + resources + media revamp in lockscreen 2026-07-08 22:53:19 +02:00
images update picture 2026-04-03 00:34:08 +02:00
Modules add initial logo to about page + assets and readme 2026-07-10 11:32:09 +02:00
nix test nix 2026-03-25 18:27:49 +01:00
Paths initial commit for settings revamp 2026-06-23 16:22:56 +02:00
Plugins fix: fallback to python wheel if Nuitka is not available 2026-07-08 18:32:21 +02:00
scripts chore: python code formatted with ruff, ruff formatter + linter, pyproject.toml now in root 2026-07-08 16:54:41 +02:00
zshell-img-tools changes comments 2026-05-31 00:23:13 +02:00
.clang-format tidy&format(all): all files formatted and relevant warnings resolved 2026-06-30 02:04:24 +02:00
.clang-tidy clang-tidy: reordering 2026-06-30 03:38:16 +02:00
.gitignore remove unrelated directory 2026-07-10 15:00:02 +02:00
.prettierignore minor changes to workflows to prevent preemptive exits/failures 2026-05-20 00:02:14 +02:00
.prettierrc.json prettierrc line update to 80 from 100, and singleQuote -> false from true 2026-05-16 01:32:25 +02:00
.qmlformat.ini formatter 2026-02-25 17:29:14 +01:00
CMakeLists.txt mute cmake install output 2026-07-08 23:08:42 +02:00
eslint.config.js prettier and eslint ignore valid syntax for qml specific syntax. Clippy lint resolved in .rs. unused py files commented to be ignored by ruff 2026-05-19 23:53:09 +02:00
flake.lock nix fix attempt -> Zach fix pls 2026-02-21 21:33:25 +01:00
flake.nix fixed flake update, actually works : nix run builds now : devshell updated to include zshell and cli correctly 2026-02-21 22:07:40 +01:00
LICENSE fix for certain things 2026-02-21 18:32:03 +01:00
pyproject.toml update(typecheck): added typecheck in workflow and pyproject 2026-07-10 01:09:08 +02:00
README.md fix: logo colors 2026-07-10 11:44:01 +02:00
shell.qml hacky english month and day names while using system locale 2026-06-17 11:59:29 +02:00

ZShell logo

ZShell

ZShell is a Hyprland-focused desktop shell built with Quickshell + Qt6/QML.

It includes a configurable top bar, launcher, notifications daemon + sidebar, wallpaper and dynamic color pipeline, lock screen, OSD widgets, dashboard, dock, desktop icons, and a separate greetd-compatible greeter.

ZShell screenshot

Highlights

  • Multi-window shell layout driven by Drawers/Windows.qml and panel/interactions wrappers
  • Configurable bar entries and popouts (audio, tray, network, power, resources, clock, active window)
  • Launcher with app DB frequency tracking, action commands, fuzzy search modes, and wallpaper/scheme flows
  • Notification server with persistence (~/.local/state/zshell/notifs.json) and sidebar UI
  • Dynamic Material 3 palette generation from wallpaper, optional template rendering, terminal sequence application
  • Lock module with PAM support, idle monitors, optional fingerprint integration, and blur background generation
  • Additional modules: dock, desktop icons, dashboard, OSD, polkit agent, area picker/screenshot flow

Project Layout

.
├── shell.qml              # Main shell entry point (qs config: zshell)
├── Drawers/               # Window, panel, interaction composition
├── Modules/               # UI/feature modules (bar, launcher, lock, notifs, settings, etc.)
├── Config/                # JSON-backed config schema + serializers
├── Daemons/               # Notification/audio/network daemons
├── Helpers/               # Shared runtime helpers and integration glue
├── Paths/                 # Runtime paths (XDG + state/cache/data locations)
├── Plugins/ZShell/        # Native Qt/QML plugin (C++)
├── Greeter/               # Separate Quickshell greeter app and scripts
├── cli/                   # Python CLI (`zshell-cli`)
└── scripts/               # Utility scripts (greeter prep, updates, fuzzy helpers)

Runtime Requirements

Core requirements:

  • Qt6 + Quickshell
  • Hyprland (Wayland session integration)
  • Python 3 for scheme/wallpaper tooling

Make sure to have the newest Quickshell version! As of writing, version 0.2.0.r136.gfb08ece-1.

Used by major features (install as needed for your setup):

  • app2unit (launcher app execution)
  • nmcli (network integration)
  • brightnessctl, ddcutil (brightness controls)
  • wl-copy, swappy (picker/screenshot flow)
  • libqalculate (launcher calculator)
  • PipeWire + audio stack + aubio/cava paths for media visualization
  • gsettings (optional GTK dark/light mode sync)

Build and Install

CMake (manual)

cmake -B build -G Ninja
ninja -C build
sudo ninja -C build install

Defaults from CMakeLists.txt:

  • ENABLE_MODULES="plugin;shell"
  • QML plugin install dir: usr/lib/qt6/qml
  • shell config install dir: etc/xdg/quickshell/zshell
  • greeter install dir: etc/xdg/quickshell/zshell-greeter

Nix Flake

Note that Nix is not actively developed at this point. Things may be broken. Feel free to suggest fixes in a PR

The flake exposes:

  • packages.<system>.zshell
  • packages.<system>.zshell-cli

Add it as an input in your system flake:

{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    z-bar-qt = {
      url = git+https://git.zach-dev.cc/zach/z-bar-qt.git
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };
}

Full flake.nix example (nixosConfigurations):

{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    z-bar-qt = {
      url = git+https://git.zach-dev.cc/zach/z-bar-qt.git
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = inputs@{ nixpkgs, ... }:
  let
    system = "x86_64-linux";
  in {
    nixosConfigurations.my-host = nixpkgs.lib.nixosSystem {
      inherit system;
      specialArgs = { inherit inputs; };
      modules = [
        ({ ... }: {
          environment.systemPackages = [
            inputs.z-bar-qt.packages.${system}.zshell
            inputs.z-bar-qt.packages.${system}.zshell-cli
          ];
        })
        ./configuration.nix
      ];
    };
  };
}

Then install shell + CLI from the flake packages:

{ pkgs, inputs, ... }:
let
  system = pkgs.stdenv.hostPlatform.system;
in {
  environment.systemPackages = [
    inputs.z-bar-qt.packages.${system}.zshell
    inputs.z-bar-qt.packages.${system}.zshell-cli
  ];
}

If you use Home Manager, the same packages can be added to home.packages.

Run shell via wrapper binary:

zshell

CLI entrypoint:

zshell-cli

Running

  • Start shell directly with Quickshell config name: qs -c zshell
  • Start through CLI helper: zshell-cli shell start
  • Lock through IPC helper: zshell-cli shell lock

Configuration

Primary config file:

  • ~/.config/zshell/config.json

Important state/cache files:

  • ~/.local/state/zshell/scheme.json
  • ~/.local/state/zshell/wallpaper_path.json
  • ~/.local/state/zshell/notifs.json
  • ~/.local/state/zshell/apps.sqlite
  • ~/.cache/zshell/

Config is hot-reloaded and saved through Config/Config.qml serializers. Top-level sections include:

  • general
  • appearance
  • background
  • barConfig
  • launcher
  • services
  • notifs
  • sidebar
  • utilities
  • dashboard
  • osd
  • colors
  • dock

Launcher Prefixes

Default prefixes are defined in Config/Launcher.qml:

  • actionPrefix: >
  • specialPrefix: @

Special app-search filters (@ prefix by default):

  • @i app id/name
  • @c categories
  • @d description/comment
  • @e exec string
  • @w WM class
  • @g generic name
  • @k keywords
  • @t terminal-only apps

Action-driven flows (> prefix by default) include calculator, wallpaper picker, and scheme variant selection.

CLI Commands

zshell-cli provides these subcommands:

shell — daemon management

Command Description
start Start the shell daemon (pass --no-daemon to run in foreground)
kill Kill the running shell daemon
restart Kill then restart the daemon
lock Lock the session via IPC
show Show the shell window via IPC
log Print daemon logs

scheme — color scheme generation

Usage: zshell-cli scheme generate [--preset <scheme>:<variant>] [--accent <accent>]
                                   [--mode <dark|light>] [--image-path <path>]

Generate a color scheme from a wallpaper image (Material You) or from
a built-in preset.

Preset selection:
  --preset <scheme>:<variant>    Pick a built-in scheme (e.g. catppuccin:mocha)
  --accent <name>                Accent color for schemes that support it
                                   (catppuccin accepts: blue, green, mauve,
                                   peach, pink, red, rosewater, etc.)
  --mode <dark|light>            Override variant mode

  If variant has both dark and light modes, the mode is auto-detected from
  the current system or config preference.

  List all available presets:
    zshell-cli scheme list-presets         # human-readable
    zshell-cli scheme list-presets --json  # machine-readable (QML UI)

  Examples:
    zshell-cli scheme generate --preset gruvbox:medium
    zshell-cli scheme generate --preset catppuccin:mocha --accent green
    zshell-cli scheme generate --preset everforest:medium --mode light

Note: Template rendering (Jinja2) applies generated colors to ~/.config/zshell/templates/*.

screenshot — area picker

  • start — open interactive area picker
  • start-freeze — freeze screen then pick

wallpaper — wallpaper management

  • Set wallpaper and generate lockscreen blur background

Greeter

The repository ships a separate greeter shell under Greeter/ designed for greetd + Hyprland.

  • Greeter shell entry: Greeter/shell.qml
  • Default greeter config path: /etc/zshell-greeter/config.json
  • Startup script: Greeter/scripts/start-zshell-greeter
  • Helper installer script: scripts/prepare-greeter.sh

Known Caveats

  • Modules/Launcher/Services/Apps.qml references assets/wrap_term_launch.sh; ensure this script exists in your deployment.
  • cli/pyproject.toml currently does not list jinja2, but scheme.py imports it.
  • Some scheme variant naming paths may differ between UI values and CLI expectations (tonalSpot vs tonal-spot, etc.).

Inspiration

License

See LICENSE.