Install
Three commands:
$ git clone https://github.com/Sn3akyy1/lucid.git
$ cd lucid
$ ./install.sh
Then reload Hyprland so the new binds and rules take effect, or log out and back in, which picks up the autostart too. To start the shell by hand in the meantime, run qs.
$ hyprctl reload
Set a wallpaper from Settings → General on first run. That is what generates your colour palette.
What the installer does
- Checks your system. It refuses to run anywhere it can't finish the job, rather than leaving you half-installed.
- Installs dependencies. It finds
paruoryayand uses it, falling back topacmanfor repo packages. It lists everything and asks before touching your system. Say no and it carries on, telling you which features won't work. This includes the apps Lucid pins to the dock, several GB and mostly from the AUR;--no-appsskips them. - Copies the shell to
~/.config/quickshell, moving any existing config to~/.config/quickshell.backup-<timestamp>first. - Sets up Hyprland:
hyprland.luaand its modules, meaning the keybinds, window and layer rules, blur, animations, and an autostart that launches the shell on login. An existing config is backed up and you are asked first;--no-hyprkeeps yours untouched. - Sets up theming: the palettes, the wallpaper hook and the matugen template. An existing
matugen/config.tomlis appended to, never replaced. - Applies the look: kitty's colours, opacity and fish shell, the starship prompt (wired into
.bashrc,.zshrcandconfig.fish), the VSCode/VSCodium Matugen theme, and the GTK theme,adw-gtk3-darkwith the FairyWren icons.--no-lookskips this. - Pins the dock by reading your installed
.desktopfiles, so the dock is never a row of blank letter tiles. - Offers to restart a running instance onto the new files.
Updating
Pull and re-run. Your settings, pinned apps, reminders, Shazam history and API keys are carried forward into the new install, and the previous install is kept as a timestamped backup.
$ git pull
$ ./install.sh
Lucid tells you when there is something to pull. Once a day it asks GitHub's public API for the newest release, and when that is newer than your install it posts one notification, once per version. The request is a plain curl for api.github.com/repos/Sn3akyy1/lucid/releases/latest and carries nothing about you or your machine. Settings → About shows what it found and turns it off.
$ qs ipc call updates status # what it knows
$ qs ipc call updates check # ask now
The v0.57 beta stays available as a tag. Nothing carries over between it and v1.x, which moved enough that a fresh install is worth it.
$ git clone --branch v0.57 https://github.com/Sn3akyy1/lucid.git
Installer options
| Flag | What it does |
|---|---|
--no-theming | Skips the palette layer and leaves ~/.config/lucid and ~/.config/matugen alone. Use it if you already have a matugen setup you don't want touched. |
--no-hypr | Keeps your Hyprland config. Lucid's binds, window rules, blur and autostart are not installed. |
--no-apps | Doesn't install the apps the dock ships pinned (Zen, VSCodium, Spotify, Vesktop, Files, Steam, Proton VPN). The dock pins whatever equivalents you already have. |
--no-look | Doesn't touch kitty.conf, starship.toml, your shell rc files, VSCode settings, or the GTK theme and icons. |
--no-wallpapers | Doesn't copy the bundled wallpapers into ~/Pictures/wallpapers. They are about 180 MB. |
--with-hypr | Reinstalls Lucid's Hyprland config even when one is already in place. |
--skip-deps | Never installs packages, just reports what's missing. |
-y, --yes | Accepts every prompt. |
Keybinds
The installer ships these in ~/.config/hypr/modules/binds.lua, along with the window rules, blur, animations and autostart. Run hyprctl reload after installing to pick them up.
| Keys | Does |
|---|---|
| Super tap | Launcher |
| Super+P | Command palette |
| Super+T | Theme picker |
| Super+B | Wallpaper picker |
| Super+Shift+V | Clipboard history |
| Super+S | Settings |
| Super+. | Emoji picker |
| Super+K | On-screen keyboard |
| Super+W | Workspace overview (also a three-finger swipe) |
| Super+D or Print | Region screenshot |
| Super+Print | Full screenshot |
| Super+Shift+T | Copy text from a region (OCR) |
| Super+Shift+C | Pick a colour off the screen |
| Super+E | Files |
| Super+C | Close window |
| Super+V | Toggle float |
| Super+1–0 | Switch workspace (add Shift to move the window) |
| Super+Shift+S | Scratchpad, or put away whichever special workspace is up |
| Super+Alt+S | Stash the focused window in the scratchpad, or send it back |
| Super+Shift+M | Music workspace |
| Super+Shift+D | Comms workspace |
| Super+Shift+R | To-do workspace |
| Ctrl+Shift+Esc | System monitor workspace |
| Super+arrows | Move focus |
| Super+R | Reload Hyprland |
| F1–F6 | Volume, mic, brightness |
| F9 | Terminal |
| F10 | Lock |
| F12 | Calculator |
Binding your own
Installed with --no-hypr, or want to bind things yourself? Everything is exposed over IPC, so bind the calls from your own Lua config (Hyprland 0.55.6 and newer):
hl.bind("SUPER + space", hl.dsp.exec_cmd("qs ipc call -- launcher toggle"))
hl.bind("SUPER + E", hl.dsp.exec_cmd("qs ipc call -- moji toggle"))
hl.bind("SUPER + L", hl.dsp.exec_cmd("qs ipc call -- lock lock"))
hl.bind("SUPER + S", hl.dsp.exec_cmd("qs ipc call -- snap toggle"))
hl.bind("SUPER + SHIFT + T", hl.dsp.exec_cmd("qs ipc call -- snap text"))
hl.bind("SUPER + SHIFT + C", hl.dsp.exec_cmd("qs ipc call -- snap color"))
hl.bind("SUPER + comma", hl.dsp.exec_cmd("qs ipc call -- settings open"))
hl.dsp.exec_cmd runs its command directly, not through a shell, so keep each one to a plain command: &&, || and quoting are passed through as literal arguments.
Keep the --. It is only strictly needed when the call takes an argument: qs ipc call settings show bar fails with “The following argument was not expected: bar”, while qs ipc call -- settings show bar works. It is harmless on calls without arguments, so using it everywhere saves you the surprise.
Special workspaces are Hyprland Lua rather than IPC. On a Lua config of your own, copy support/hypr/modules/specials.lua into ~/.config/hypr/modules/ and bind its functions the way Lucid's modules/binds.lua does:
local specials = require("modules.specials")
hl.bind("SUPER + SHIFT + M", specials.toggle("music"))
IPC reference
Every surface is scriptable: qs ipc call -- <target> <function> [arg].
| Target | Functions |
|---|---|
launcher | toggle open close wallpaper theme power blur command shuffle clipboard search <query> |
settings | toggle open close show <page> general users glass bar dock environment displays widgets workspaces notifications sound network bluetooth kdeconnect idle datetime font reset |
idle | status keepawake awake normal on off restart |
network | status list rescan |
kdeconnect | status list rescan ring <id> ping <id> clipboard <id> files <id> send <id> <path> |
widgets | add <type> <variant> remove <uid> clear toggle lock unlock list catalogue settings resize <uid> <w> <h> |
moji | toggle open close emoji kaomoji gif center |
keyboard | toggle open close letters fnkeys center bigger smaller |
notifs | toggle open close clear toggleDnd expandAll settings count |
lock | lock unlock isLocked status. Nothing here bypasses the password; PAM is the only way in. |
snap | toggle open close text color |
toast | show <icon> <label> warn <icon> <label> |
screenshot | full text |
media | toggle open close identify playPause next previous |
workspaces | toggle open close |
updates | status check |
displays | list settings shell <where> bar <where> dock <where>. where is an output name, left, middle or right, here, next, prev or auto. |
polkit | status demo <action-id> fail grant close. demo raises the dialog with no PAM session behind it, for previewing a theme. |
debug | toggle on off. Draws input and blur region outlines. |
Toast icons by name are copy, check, alert, info, text, game and camera. Anything else is taken as a raw SVG path.
Theming
Colours come from one of seven palettes, picked in Settings or through the launcher's Theme mode. Matugen and Pywal generate a palette from your current wallpaper. Catppuccin Mocha, Gruvbox, Nightfox, Nord and Tokyo Night are fixed palettes that don't change with the wallpaper. Anything you import sits alongside them, and the whole list can be dragged into the order you want.
Whichever is active, the shell reads ~/.cache/quickshell/matugen.json, a flat map of Material 3 colour roles. Changing your wallpaper through Lucid runs ~/.config/hypr/scripts/wallpaper/set-wallpaper.sh, which sets the wallpaper and regenerates that file if the active theme comes from the wallpaper.
If you already use matugen, the installer appends its Quickshell template to your config.toml and backs up the original. Your existing templates are left alone.
Light mode
Every palette has a light mode: Light or dark on the Theme page. Matugen and Pywal re-extract the wallpaper in the mode you pick, and the fixed palettes get a light version built from their own colours, so Nord lands on its own Snow Storm and Gruvbox on its own cream. Light surfaces carry a trace of the accent, and Accent tint on the General page sets how much. GTK and Qt apps follow, switching to the light or dark counterpart of their theme where one is installed.
Wallpapers per display
Every display gets the same picture, cropped to fill. To treat one differently, like a portrait screen that should letterbox, or a second screen with a picture of its own, add a rule to ~/.config/lucid/wallpaper-outputs.conf, one output per line:
DP-3 --resize fit --fill-color 000000
HDMI-A-1 ~/Pictures/wallpapers/second.jpg
Any argument that is a file becomes that output's picture; the rest is passed to awww/swww. Outputs with no rule keep the wallpaper you picked, and colours still come from that one. qs ipc call displays list prints your outputs, left to right.
Your own theme
Settings → Theme takes the URL of any colour-scheme repo, clones it, reads it, and builds a full Material 3 palette from what it finds. base16 and base24 YAML and name-keyed JSON (Catppuccin and friends) are read exactly; anything else falls back to harvesting hex codes and sorting them by tone and chroma. A repo with several variants lists them so you can pick one, and wallpapers in the repo come along with it.
Nothing from the repo is ever executed. Only text is parsed and only images are copied.
It writes ~/.config/lucid/themes/<id>/{quickshell.json,meta.json} and ~/Pictures/wallpapers/<id>/, which you can also do by hand: a quickshell.json with the same keys as the bundled palettes is all a theme is. The importer runs from a terminal too:
$ python3 ~/.config/lucid/add-theme.py <repo-url> [--list] [--variant <name>] [--name <label>]
Requirements
Arch Linux and Hyprland. The installer handles all of this; it is listed here so you know what is being pulled in. Lucid uses Hyprland-specific APIs for workspaces and window management and will not work on other compositors.
Required
The shell won't start without these:
quickshellqt6-5compatqt6-declarativeqt6-multimedia
Per feature
A missing one breaks only its own feature.
| Package | Backs |
|---|---|
matugen, jq | Wallpaper-derived colours, theme switching |
git | Importing a theme from a scheme repo |
awww | Setting the wallpaper |
python-pywal | The Pywal theme |
networkmanager | Wi-Fi panel |
bluez, bluez-utils | Bluetooth panel and the Bluetooth settings page |
kdeconnect, python-gobject | The Phone page. Without either the page says so and does nothing else |
libpulse, wireplumber | Volume, audio devices |
brightnessctl, upower | Brightness, battery |
hypridle | The Idle page: dimming, locking, screen off and suspend |
grim, wf-recorder, ffmpeg, imagemagick | Screenshots and recording |
tesseract, tesseract-data-eng | The text copier's OCR |
python-pillow, python-numpy, python-fonttools | Emoji in copied text. Without them the text still copies, minus the emoji |
wl-clipboard, wtype | Emoji and GIF pasting |
cliphist | Clipboard history |
cava | Audio visualisers in the media panel and the desktop widget |
songrec | Song identification |
curl | Weather, location lookup and GIF search |
polkit | Every administrator prompt. The shell is the session's authentication agent, so no other agent should be started |
accountsservice | The Users and Accounts page |
libnotify | Notification actions |
swappy | The Open action on a screenshot notification |
hyprpicker | The colour picker |
xdg-utils | Opening links and files from the shell |
librsvg | Turning the pointer's shadow off |
noto-fonts-emoji | Emoji rendering |
The Hyprland config and the look
Installed unless you pass --no-hypr or --no-look. The binds shell out to these, so a missing one is a dead key: kitty, fish, nautilus, playerctl, gnome-calculator, starship, ttf-jetbrains-mono-nerd, adw-gtk-theme and papirus-icon-theme.
The dock's default pins
Installed unless you pass --no-apps. Several GB, mostly from the AUR:
zen-browser-binvscodium-binspotifyvesktopnautilussteamproton-vpn-gtk-app
Anything you already have an equivalent of is left alone: vscodium counts for vscodium-bin, discord for vesktop, and so on. steam is skipped unless the multilib repo is enabled.
Fonts
The default UI font is Google Sans, which is not in the Arch repos. Without it Qt falls back to your default sans and everything still works, or you can pick any installed font in Settings → General.
Optional setup
GIF search needs a free Giphy key (email only, no card) from developers.giphy.com. Put it in ~/.config/quickshell/lucidmoji/config.json. Tenor works too. Emoji and kaomoji need no key.
{ "giphyKey": "your-key-here", "tenorKey": "", "gifDir": "" }
Wallpapers default to ~/Pictures/wallpapers, one folder per theme: ~/Pictures/wallpapers/gruvbox is what the strip shows while you are on Gruvbox. The installer puts a set in each, skipping any file you already have. Change the folder in Settings → General, which then applies to every theme.
Uninstall
$ ./uninstall.sh
It moves ~/.config/quickshell aside rather than deleting it, so your settings survive. Packages installed by install.sh are left alone. It prints what else it left in place (the matugen template blocks, ~/.config/hypr, starship.toml and its init lines in your rc files, kitty's colour and opacity includes), each with a timestamped backup beside it, so you can undo them by hand.
Something not working? The Help Center covers the common problems, and Support helps you file a good bug report.