Lucidv1.1.0
Lucid on GitHub, stars:170
  1. Home
  2. Docs

Docs

Installing, updating, keybinds, IPC and theming. Lucid installs to ~/.config/quickshell and needs Arch Linux and Hyprland.

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

  1. Checks your system. It refuses to run anywhere it can't finish the job, rather than leaving you half-installed.
  2. Installs dependencies. It finds paru or yay and uses it, falling back to pacman for 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-apps skips them.
  3. Copies the shell to ~/.config/quickshell, moving any existing config to ~/.config/quickshell.backup-<timestamp> first.
  4. Sets up Hyprland: hyprland.lua and 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-hypr keeps yours untouched.
  5. Sets up theming: the palettes, the wallpaper hook and the matugen template. An existing matugen/config.toml is appended to, never replaced.
  6. Applies the look: kitty's colours, opacity and fish shell, the starship prompt (wired into .bashrc, .zshrc and config.fish), the VSCode/VSCodium Matugen theme, and the GTK theme, adw-gtk3-dark with the FairyWren icons. --no-look skips this.
  7. Pins the dock by reading your installed .desktop files, so the dock is never a row of blank letter tiles.
  8. 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

FlagWhat it does
--no-themingSkips 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-hyprKeeps your Hyprland config. Lucid's binds, window rules, blur and autostart are not installed.
--no-appsDoesn'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-lookDoesn't touch kitty.conf, starship.toml, your shell rc files, VSCode settings, or the GTK theme and icons.
--no-wallpapersDoesn't copy the bundled wallpapers into ~/Pictures/wallpapers. They are about 180 MB.
--with-hyprReinstalls Lucid's Hyprland config even when one is already in place.
--skip-depsNever installs packages, just reports what's missing.
-y, --yesAccepts 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.

KeysDoes
Super tapLauncher
Super+PCommand palette
Super+TTheme picker
Super+BWallpaper picker
Super+Shift+VClipboard history
Super+SSettings
Super+.Emoji picker
Super+KOn-screen keyboard
Super+WWorkspace overview (also a three-finger swipe)
Super+D or PrintRegion screenshot
Super+PrintFull screenshot
Super+Shift+TCopy text from a region (OCR)
Super+Shift+CPick a colour off the screen
Super+EFiles
Super+CClose window
Super+VToggle float
Super+10Switch workspace (add Shift to move the window)
Super+Shift+SScratchpad, or put away whichever special workspace is up
Super+Alt+SStash the focused window in the scratchpad, or send it back
Super+Shift+MMusic workspace
Super+Shift+DComms workspace
Super+Shift+RTo-do workspace
Ctrl+Shift+EscSystem monitor workspace
Super+arrowsMove focus
Super+RReload Hyprland
F1F6Volume, mic, brightness
F9Terminal
F10Lock
F12Calculator

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].

TargetFunctions
launchertoggle open close wallpaper theme power blur command shuffle clipboard search <query>
settingstoggle open close show <page> general users glass bar dock environment displays widgets workspaces notifications sound network bluetooth kdeconnect idle datetime font reset
idlestatus keepawake awake normal on off restart
networkstatus list rescan
kdeconnectstatus list rescan ring <id> ping <id> clipboard <id> files <id> send <id> <path>
widgetsadd <type> <variant> remove <uid> clear toggle lock unlock list catalogue settings resize <uid> <w> <h>
mojitoggle open close emoji kaomoji gif center
keyboardtoggle open close letters fnkeys center bigger smaller
notifstoggle open close clear toggleDnd expandAll settings count
locklock unlock isLocked status. Nothing here bypasses the password; PAM is the only way in.
snaptoggle open close text color
toastshow <icon> <label> warn <icon> <label>
screenshotfull text
mediatoggle open close identify playPause next previous
workspacestoggle open close
updatesstatus check
displayslist settings shell <where> bar <where> dock <where>. where is an output name, left, middle or right, here, next, prev or auto.
polkitstatus demo <action-id> fail grant close. demo raises the dialog with no PAM session behind it, for previewing a theme.
debugtoggle 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.

PackageBacks
matugen, jqWallpaper-derived colours, theme switching
gitImporting a theme from a scheme repo
awwwSetting the wallpaper
python-pywalThe Pywal theme
networkmanagerWi-Fi panel
bluez, bluez-utilsBluetooth panel and the Bluetooth settings page
kdeconnect, python-gobjectThe Phone page. Without either the page says so and does nothing else
libpulse, wireplumberVolume, audio devices
brightnessctl, upowerBrightness, battery
hypridleThe Idle page: dimming, locking, screen off and suspend
grim, wf-recorder, ffmpeg, imagemagickScreenshots and recording
tesseract, tesseract-data-engThe text copier's OCR
python-pillow, python-numpy, python-fonttoolsEmoji in copied text. Without them the text still copies, minus the emoji
wl-clipboard, wtypeEmoji and GIF pasting
cliphistClipboard history
cavaAudio visualisers in the media panel and the desktop widget
songrecSong identification
curlWeather, location lookup and GIF search
polkitEvery administrator prompt. The shell is the session's authentication agent, so no other agent should be started
accountsserviceThe Users and Accounts page
libnotifyNotification actions
swappyThe Open action on a screenshot notification
hyprpickerThe colour picker
xdg-utilsOpening links and files from the shell
librsvgTurning the pointer's shadow off
noto-fonts-emojiEmoji 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.