| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Desktop shell built on Quickshell. Part of the quantumfate desktop, alongside the hypr compositor config and the scripts CLI helpers.
See ARCHITECTURE.md for how the UI and Hyprland config bridge (shared JSON state + IPC).
qs -c quantumfate # if symlinked into ~/.config/quickshell/quantumfate
qs -p ~/Projects/github/quantumfate/quickshell/shell.qmlInstall (symlink so edits are live):
ln -s ~/Projects/github/quantumfate/quickshell ~/.config/quickshell/quantumfateState files (team.json, theme.json) are self-seeded on first run from Store defaults, so a fresh checkout just works — no manual copying.
Two provisioning paths, each an importable "output" you can wire into a larger controller/config:
Ansible — ansible/. Run directly:
ansible-galaxy collection install -r ansible/requirements.yml
ansible-playbook ansible/playbook.yml --ask-become-passOr import the quickshell role from your own controller (see ansible/requirements.yml). Installs runtime packages (Arch), symlinks the config, ensures the state dir.
Nix flake — flake.nix. Import the modules (inputs.quantumfate-quickshell.url = "github:quantumfate/quickshell"):
# home-manager: deploy the config + zsh completions
imports = [ inputs.quantumfate-quickshell.homeManagerModules.quickshell ];
programs.quickshellDesktop.enable = true; # optional: .name = "quantumfate"
# NixOS: install the runtime packages
imports = [ inputs.quantumfate-quickshell.nixosModules.quickshell ];
programs.quickshellDesktop.enable = true;devShells.<system>.default gives quickshell + tools for nix develop.
Both handle the full manual setup — runtime packages (incl. xdotool for window rename), the config symlink, the _qs/_qfs zsh completions + fpath wiring — and rely on the shell self-seeding state, so neither copies data files. (qfs itself ships in the scripts repo; autostart lives in the hypr config.)
Completion/diagnostics come from the QML language server, qmlls. Two things matter:
Neovim (this repo's owner uses lspconfig):
qmlls = {
cmd = { "qmlls6", "-I", "/usr/lib/qt6/qml" },
filetypes = { "qml", "qmljs" },
root_markers = { ".qmlls.ini", "shell.qml", ".git" },
}When qs is running it also drops a .qmlls.ini symlink here pointing at its per-launch VFS buildDir, which gives qmlls type info for your own components and singletons on top of the installed modules. That file is git-ignored (the path is ephemeral); the stable, editor-agnostic setup is the -I flag above.
shell.qml root ShellRoot; wires each top-level widget/window services/ singletons = shared global state (one concern each) Config.qml paths & constants DofusState.qml Dofus team single source of truth (team.json bridge) modules/<feature>/ the widgets; PascalCase files auto-import within a dir dofus/ DofusTeam (window) + CharacterRow (delegate) scripts/ shell glue for non-QML consumers assets/ seeds, images, fonts
Convention: state lives in a services/ singleton, views live in modules/. Add a new feature = new modules/<name>/ + (if it owns global state) a singleton in services/, then drop the root widget into shell.qml.
State shared with the Hyprland Lua config goes through a Store: a JSON file in $XDG_STATE_HOME/<name>.json that is the single source of truth, mirrored reactively on both sides.
$XDG_STATE_HOME/<name>.json ← single source of truth
▲ FileView.watchChanges ▲ ▲ mtime-cached reload ▲
services/Store.qml (QML) hypr/lib/store.lua (Lua)
Rule of thumb: state → a Store (shared) or a singleton (QML-only); commands → IPC. A new shared feature = pick a name, Store.define it in Lua, Store {} it in QML. DofusState is the reference example.
Ordered team list drives turn order, F1–F8 activate, launch order, swap args. The order lives in one JSON file; everything else reads it.
~/.local/state/dofus/team.json (XDG_STATE_HOME) — the truth
↑ edit ↑ read
Quickshell UI Hyprland Lua config, dofus_swap.py, scripts
File directly (always works, even if the shell isn't running):
scripts/dofus-team names # ordered names, one per line
scripts/dofus-team titles # names prefixed with "Dofus "
scripts/dofus-team selected # active team keyor raw: jq -r '.teams[.selected][]' ~/.local/state/dofus/team.json
IPC into the running shell (sees unsaved in-memory edits):
qs -c quantumfate ipc call dofus team # ordered names
qs -c quantumfate ipc call dofus select duo # switch active team
qs -c quantumfate ipc call dofusPanel toggle # show/hide the HUDqs -c quantumfate ipc show # raw signatures of every target
qs -c quantumfate ipc call help all # annotated overview with examplesTargets: help, theme, dofus, dofusPanel, cheatsheet. When you add an IpcHandler, document it in modules/common/IpcHelp.qml.
qfs (in the scripts repo) wraps the IPC surface so you rarely type the long form:
qfs # annotated overview (ipc call help all)
qfs show # raw signatures (ipc show)
qfs theme cycle # ipc call theme cycle
qfs window rename "..." # ipc call window rename ...
qfs kill | log | list # passthrough to qs -c <config>Config name via $QFS_CONFIG (default quantumfate).
completions/_qs (for raw qs) and completions/_qfs (for qfs) both read qs ipc show live, so every target and function completes and never goes stale. Install by putting them on your $fpath:
mkdir -p ~/.local/share/zsh/site-functions
ln -s "$PWD/completions/_qs" ~/.local/share/zsh/site-functions/_qs
ln -s "$PWD/completions/_qfs" ~/.local/share/zsh/site-functions/_qfs
# ensure this dir is on $fpath before `compinit` in ~/.zshrc:
# fpath=(~/.local/share/zsh/site-functions $fpath)Writers (UI, scripts) edit the JSON; DofusState watches the file and reloads, so all consumers converge. Editing in the UI writes the file back.
hypr/services/dofus/common.lua currently hard-codes the team. Point it at the JSON instead so the Lua and the UI share one truth — read the file in common.lua and drop the hard-coded M.characters.
| Back | FazBrowse Home | New Git URL |