A feature-complete Hyprland desktop shell built with Quickshell. Includes a custom lock screen, a built-in idle manager, custom and wallpaper-based theming, and a fully configurable top bar — no external bar, no separate lock/idle daemons.
![]() |
![]() |
Shell & Bar
- 16 built-in widgets across three configurable pill sections (left / center / right)
- Drag-and-drop widget reordering via a built-in Settings popup
- System Tray, MPRIS player with cava visualizer, Battery, Bluetooth, Network
- Time tracking (optional, requires
selftrackdaemon): today's active time in the bar, centered popup with day/week/month summary, 00–24 timeline strip and per-app page breakdown (qs ipc call selftrack toggle) - Settings popup: keybind rebinding and Hyprland window options (gaps, opacity, rounding, borders, dwindle/master layout) — applied live, no config file editing required
Lock Screen & Idle
- Native lock screen via
ext-session-lock-v1with PAM authentication - Keyboard layout badge next to the password field (left-click cycles layouts, right-click picks from the list)
- Brute-force protection — lockout after repeated failed attempts
- Built-in idle manager — lock → DPMS → suspend timeouts (replaces hypridle)
- Media playback pauses idle timers automatically
Bluetooth
- Secure pairing: every attempt shows a confirmation popup with the passkey (or PIN entry for legacy devices) — nothing pairs silently
- Per-device trust with a lock toggle in the Bluetooth manager
- Pairing mode: the adapter only accepts new pairings while Discoverable is on, and both flags drop together on timeout
Phone — KDE Connect via kcd
- Optional headless Go daemon kcd (
AUR kcd-bin,systemctl --user enable --now kcd), LAN-only1716/udp+tcp1739:1764/tcp, no KDE stack, no telemetry - Battery + reachable dot, Ping / Ring (FindMyPhone), Share file (
zenity/kdialog→kcd share), Clipboard push (kcd clipboard), SFTP browse/mount/unmount (kcd sftp→~/Downloads/kcd/mnt↔/storage/emulated/0), notifications (Phone • Appin toast + phone popup history, deduplicated,kcdDndEnabled— only popup when DND on) - Phone popup: battery bar, Ping / Ring, Share file, Clipboard push, SFTP browse/mount/unmount, recent notifications + Clear, firewall hint. Pairing is phone-initiated only (Accept/Decline popup); terminal flow (
kcd pair,kcd connect) unchanged.kcdDndEnabledtoggle (header bellF0F3/F1F6+ widget badge) - MPRIS/media, volume and lock work via
kcdplugins automatically (no extra UI)
Themes & Colors
- Three modes: Black (built-in fixed palette), Matugen (wallpaper-derived), Custom (your own colors)
- Edit all 30 palette colors through an interactive preview, HEX input and RGBA sliders
- Save personal themes, apply saved themes with one click, rename, duplicate and delete presets
- Custom themes stay independent of wallpaper changes and survive updates
- Wallpaper-based palette generation via
matugen - Live reload — terminal (Kitty), prompt (Starship), file manager (Yazi) all update
- No restart required
Hardware
- Monitor brightness via
ddcutilwith coalesced writes (one transaction per drag) - Blue-light filter via
hyprsunset(3500K–6500K slider) - Power actions: Shutdown, Reboot, Suspend, Logout, Lock
Installer & CLI
install.sh— full setup from a fresh Arch install (greetd, services, cursor, AUR packages)selfshell doctor— runtime diagnostics (dependencies, services, hardware)selfshell update,selfshell lock,selfshell reload— all operations from CLI
Genshin Impact widget (optional)
- Real-time resin tracking with local regeneration calculation (1 resin / 8 min)
- HoYoLAB API sync for expeditions, dailies, teapot coins
- Auto-sync at high resin (≥198) and rate-limit protection
- Pulsing visual indicator at critical resin (≥190)
- Requires credentials in
scripts/.env(see.env.example)
| Component | Role |
|---|---|
| Hyprland | Wayland compositor (≥ 0.56.0 — supported Lua API) |
| Quickshell | QML-based shell/panel |
| Kitty | Terminal |
| Fish | Shell |
| Starship | Prompt |
| Yazi | File manager |
| Fastfetch | System info |
| kcd | Headless KDE Connect daemon (phone, optional, AUR kcd-bin) |
| selftrack | Focus-based time tracker (time tracking widget, optional, cargo install --git) |
The installer targets Arch Linux. Back up an existing desktop configuration before replacing it. Installer failure paths are tested with isolated system-command stubs; hardware setup still depends on your machine.
git clone https://github.com/TripShuti/SELFshell
cd SELFshell
./install.sh
# follow the prompts, then rebootThe script installs dependencies, copies configs and optionally sets up
greetd + tuigreet for an uwsm session. It enables greetd for the next
boot without stopping the current display manager. If declined, start the
session from a TTY with uwsm start hyprland.desktop; Fish login autostart
is added only when a Fish config exists, and does not change your login shell.
Dotfiles are optional: installing only Quickshell does not configure Hyprland
startup. The final selfshell doctor --preboot checks dependencies and the
installed compositor version before services are enabled.
For a fresh configuration directory, clone and copy the component dirs into ~/.config/ (each repo subdir maps
to ~/.config/<name>, mirroring what install.sh copies):
git clone https://github.com/TripShuti/SELFshell
mkdir -p ~/.config
cp -r SELFshell/{quickshell,hypr,fish,kitty,starship,yazi,fastfetch} ~/.config/
python3 SELFshell/quickshell/scripts/update_config.py record SELFshell ~/.config/quickshell quickshell hypr fish kitty starship yazi fastfetchThen:
- Copy
quickshell/scripts/.env.exampleto.envand fill in your credentials (if using Genshin widgets). - Place your wallpapers in
quickshell/wp/. - Review and adjust path references in configs.
- Lock-screen frame
current-lock.jpgandcurrent.*are generated on every wallpaper switch; the tracked defaults arewp1.jpgandblack.png. - Ensure all dependencies listed in
install.sh(PACMAN_DEPS) are installed.
Use selfshell update for an installed copy. It downloads main, prepares
and validates a separate tree, preserves settings/secrets/wallpapers and
updates the components recorded by the installer. Previously owned files
removed upstream are removed; conflicting edits to managed source files
stop the update. Backups remain until the new shell answers IPC. Failure
rolls files back and restarts the previous shell. Updates/reloads are
serialized and require an unlocked screen with no wallpaper apply running.
The installation manifest is ~/.config/quickshell/.selfshell-install.json.
Older installs without it update Quickshell only; optional component
ownership and palette integration must be recorded explicitly. Keep the Git
checkout outside ~/.config: the repository contains several component
directories and is not itself a runnable Quickshell configuration. Source
checkouts are updated with Git and reviewed before installation.
To register additional components in an existing installation, first merge their managed source files with the checkout, then run:
python3 quickshell/scripts/update_config.py adopt . ~/.config/quickshell hypr fish kitty starship yazi fastfetchAdoption refuses missing or differing managed files and preserves palette opt-in.
Hyprland local.lua (loaded after the shared modules), its JSON overrides,
and Yazi yazi.toml/keymap.toml remain personal across updates.
Re-running ./install.sh is a replacement with backups, not a settings-preserving
update. Existing Quickshell configs require confirmation (default no);
declining exits before package or service changes. --yes accepts every
optional step; --no prints a plan and exits without changing anything.
On failure the installer restores backed-up files and removes fresh targets.
Package installations and external system settings are not rolled back.
Palette integration is enabled for the optional configs selected at install. For a manually managed application, opt in explicitly, for example:
selfshell palette enable yazi
selfshell palette enable kitty
# Matugen: regenerate from the current wallpaper
selfshell wallpaper reload
# Custom: use Save and apply in Settings → Appearance insteadAvailable integrations: kitty, fish, starship, yazi, foot, qt6ct.
palette disable <app> stops subsequent writes. Enabling Yazi delegates its
theme.toml and generated palette flavor to SELFshell; back up custom themes.
palette reload only rereads palette.json; it does not regenerate app themes
or lock-screen frames. To regenerate application themes, use wallpaper reload
in Matugen, theme set black in Black, or Save and apply in Custom.
wallpaper current returns the desktop image, including GIF; the lock screen
uses a separate generated static frame.
install.sh installs a selfshell CLI into ~/.local/bin:
selfshell doctor # check dependencies, config, services, hardware
selfshell doctor --preboot # same, but skip session checks (for installer)
selfshell lock # lock the screen
selfshell toggle-lock # lock the screen (lock-only alias, no-op if already locked)
selfshell launcher # toggle application launcher
selfshell settings # toggle bar settings popup
selfshell control # toggle control center
selfshell clipboard # toggle clipboard history
selfshell kcd # toggle phone (kcd) popup
selfshell audio # toggle audio mixer
selfshell osd <volume|brightness> # show OSD overlay
selfshell theme [list|status|set <black|matugen|custom>] # manage theme
selfshell wallpaper <list|current|set <file>|random|reload> # manage wallpapers
selfshell palette <list|reload|show|path|enable <app>|disable <app>> # palette operations
selfshell config <list [filter]|describe <key>|get <key>|set <key> <value>|edit|reset|path|check> # manage config.json
selfshell ipc [call] <target> <function> [args...]
selfshell reload # restart quickshell
selfshell update # staged update of managed components, with rollback
selfshell version # show version
selfshell list # list running quickshell instances
selfshell status # quick status summary
selfshell services # list servicesUse selfshell palette list to see supported applications and their opt-in state.
palette enable <app> enables future theme generation. Apply it using the action
for your theme mode described above; palette reload only re-reads the shell palette.
Discover configuration keys with selfshell config list (or config list idle).
selfshell config describe barHeight shows the description, type, allowed range,
default and current value. For example:
selfshell config get barHeight
selfshell config set barHeight 40
selfshell config set dndEnabled true
selfshell config set barPos bottomset validates values and applies them live when the shell is running.
Use theme set to apply a theme: setting themeMode alone only changes the key.
config reset resets all settings; config edit requires a stopped shell.
Choose a mode in Settings → Appearance → Theme mode:
| Mode | Colors | When the wallpaper changes |
|---|---|---|
| Black | Built-in fixed palette | Only the wallpaper and lock-screen frame change |
| Matugen | Generated from the wallpaper | Shell colors and opted-in application themes regenerate |
| Custom | Your manually edited palette | Only the wallpaper and lock-screen frame change; colors stay fixed |
- Select Custom. Switching modes keeps the current colors, so a Matugen palette can become the starting point for a personal theme.
- Click New theme from current colors and enter a name. The saved-theme list, creation button and name field sit above the preview.
- Select any of the 30 color swatches in the preview. The selected field's name, HEX value and transparency sample appear below the swatches.
- Edit the HEX value or use the R / G / B / A sliders. The preview updates immediately and shows a bar, volume indicator, notification text, primary and secondary actions, and Default / Hover / Pressed states. The checkerboard sample shows transparency. Color selection and editing are in the preview; there is no separate long color list.
- Choose Save, Save as copy, or Save and apply:
| Action | Result |
|---|---|
| Save | Stores the name and colors without changing the active shell palette |
| Save as copy | Creates a separate preset from the current draft |
| Save and apply | Saves the draft, activates Custom mode and updates the shell and opted-in application themes |
| Click a saved theme | Immediately applies the saved palette and opens it for editing |
| Rename | Change the name field and use Save |
| Delete beside a saved theme | Click again when it reads Delete? to confirm; applied colors stay unchanged |
Draft edits affect the preview until applied. HEX accepts #RRGGBB or Qt's
#AARRGGBB (alpha first); for example, #80ffffff is approximately 50% opaque
white. All 30 fields, including derived colors and overlays, are independently
editable. font is not a color and is not part of the custom theme editor.
Personal presets live in ~/.config/quickshell/data/custom-themes.json, separate
from the active palette.json. They survive selfshell update. Preset deletion
never restores a different palette or switches the current wallpaper.
Supported integrations: Kitty, Fish, Starship, Yazi, Foot and qt6ct. Use
selfshell palette list to inspect opt-in state and palette enable <app> to
opt in. In Custom mode, use Save and apply (or select a saved theme) after
opting in. wallpaper reload deliberately keeps Custom colors and does not
regenerate application themes. External application color values use the RGB
channels; alpha is preserved in the shell palette.
selfshell theme set custom freezes the current palette; it does not select a
saved preset by name. Saved presets are selected in Settings. See the
configuration reference
for the library format and troubleshooting
for recovery and application-theme issues.
All runtime dependencies are handled by install.sh. See the PACMAN_DEPS
array in the script for the complete list. Key packages:
| Package | Purpose |
|---|---|
hyprland quickshell |
Compositor & shell |
kitty fish starship yazi |
Terminal, shell, prompt, file manager |
networkmanager bluez bluez-utils |
Network & Bluetooth |
pipewire wireplumber pipewire-pulse |
Audio |
hyprsunset |
Blue-light filter |
matugen awww |
Color generation & wallpaper |
breeze-cursors (extra) |
KDE Breeze cursor theme (XCURSOR_THEME + gsettings + index.theme) |
grim slurp wl-clipboard |
Screenshots & clipboard |
ddcutil |
Monitor brightness control |
upower |
Battery widget |
power-profiles-daemon |
Power profiles (Settings → System, auto power-saver) |
qt6-5compat |
Qt5Compat.GraphicalEffects — lock screen blur (required, shell won't start without it) |
greetd greetd-tuigreet |
TUI login screen (starts Hyprland via uwsm) |
uwsm |
User session manager (session start from greetd / fallback autostart) |
python-requests python-dotenv |
Genshin Impact widget (Hoyolab API) |
kcd (kcd, AUR kcd-bin) |
Phone — KDE Connect without KDE stack (optional, systemctl --user enable --now kcd, sshfs for SFTP, zenity/kdialog for Share) |
selftrack (SELFtrack, cargo) |
Time tracking widget (optional, systemctl --user enable --now selftrack-daemon; the shell uses only daemon + export, the TUI is a standalone fallback) |
docs/ - documentation (architecture, components, config formats)
fastfetch/ - system info config
fish/ - shell config, functions, yt-dlp wrapper
hypr/ - Hyprland (lua module system, env.json for user settings) & hyprsunset configs
install.sh - automated setup script
kitty/ - terminal config
quickshell/ - QML panels, core, popups, widgets, monitors, scripts, data, assets, services
- core/ — shell infrastructure (AppConfig, IdleManager, LockSurface/LockContext, AnimatedPopup, HoverItem/HoverButton, etc.)
- monitors/ — background data monitors (Cava, Genshin, SelfTrack)
- widgets/ — panel widgets (16 total, incl. KdeConnectWidget)
- popups/ — popup windows (21 total, incl. KdeConnectPopup + settings/audio/mpris/control sections) + shared blocks (HoverButton, WallpaperController, PactlJsonProc, ResolvedIcon, EmptyHint)
- scripts/ — helper scripts (palette, Genshin, AudioMixerUtils, Format.js, etc.)
- data/ — persisted state (config.json, calendar-tasks, eq.json, etc.)
- assets/ — icons, sounds
- services/ — pairing agent, TrackListService, PacmanService, PowerProfileService, KdeConnectService, cava config
- pam/password.conf — PAM config for lock screen auth
starship/ - prompt config
yazi/ - file manager config, keybindings, themes
Disclaimer: Bugs or breakage may occur on your machine. Feel free to use anything you like, but at your own risk.
hypr/env.json— user-level Hyprland settings: terminal/browser/cursor, autostart apps, input devices. If the file is missing, built-in defaults (identical values) are used.~/.config/hypr/binds.jsonand~/.config/hypr/visual.json— keybinding and visual overrides written by the Settings popup (see docs/CONFIG_FORMAT.md). Both files are optional; deleting them restores the built-in defaults.- Genshin Impact widgets require Hoyolab API credentials (see
quickshell/scripts/.env.example). - Bluetooth pairing agent (
qs-bt-agent) runs as a systemd user service and implements secure pairing: every new device must be confirmed in a popup, and trusted devices are managed in the Bluetooth manager.


