quickshell: wallpaper switcher with per-wallpaper palettes

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
rope 2026-08-19 13:45:56 +01:00
parent 9d4b1f8c93
commit 965e9af5cf
2 changed files with 22 additions and 11 deletions

View file

@ -14,6 +14,7 @@ This is a NixOS flake-based configuration for multiple hosts:
- `home-manager/` — Home Manager configuration (via NixOS module) - `home-manager/` — Home Manager configuration (via NixOS module)
- `services/` — modular service definitions, gated by hostname with `lib.mkIf` - `services/` — modular service definitions, gated by hostname with `lib.mkIf`
- `settings/` — shared settings (desktop, hyprland, quickshell, stylix, …) - `settings/` — shared settings (desktop, hyprland, quickshell, stylix, …)
- `walls/` — wallpapers. Each gets a dark base16 palette generated at build time; the shell picks one at runtime (bar button → `settings/quickshell.nix`), so switching re-tints the shell without a rebuild. `walls/wallpaper.png` stays the build-time stylix scheme for everything else.
- `modules/crowdsec/` — vendored crowdsec modules from nixpkgs PR #446307; delete once that PR lands in the pinned channel - `modules/crowdsec/` — vendored crowdsec modules from nixpkgs PR #446307; delete once that PR lands in the pinned channel
- `ports.toml` — WAN → LAN port forwards consumed by `services/router.nix` - `ports.toml` — WAN → LAN port forwards consumed by `services/router.nix`

View file

@ -469,12 +469,26 @@ in
wallFile.writeAdapter(); wallFile.writeAdapter();
} }
property var pal: ({}) // The live palette. A JsonAdapter rather than a manual
// JSON.parse: its properties ARE QML properties, so a path
// change reloads the file and every colour binding below
// re-fires on its own. Defaults are stylix's build-time
// scheme (walls/wallpaper.png), which is also what shows if
// a palette file is ever missing or malformed.
property FileView palFile: FileView { property FileView palFile: FileView {
path: theme.currentWall ? theme.currentWall.palette : "" path: theme.currentWall ? theme.currentWall.palette : ""
printErrors: false printErrors: false
// Synchronous: an async first read paints a frame in the
// previous scheme on every switch.
blockLoading: true blockLoading: true
onLoaded: theme.pal = JSON.parse(text()) adapter: JsonAdapter {
id: pal
property string base00: "${c.base00}"
property string base03: "${c.base03}"
property string base04: "${c.base04}"
property string base05: "${c.base05}"
property string base0D: "${c.base0D}"
}
} }
// Surfaces: one hue, three steps. base01/base02 are tints of // Surfaces: one hue, three steps. base01/base02 are tints of
@ -483,20 +497,16 @@ in
// purple card floating over a slate bar. Tinting keeps // purple card floating over a slate bar. Tinting keeps
// bar card hover reading as one stack. Two numbers, and // bar card hover reading as one stack. Two numbers, and
// they are the whole surface ladder. // they are the whole surface ladder.
// readonly property color base00: "#" + pal.base00
// The "#${c.base00}" fallbacks are stylix's build-time scheme
// (walls/wallpaper.png): what shows for the frame or two
// before palFile lands, and if a palette file ever goes bad.
readonly property color base00: "#" + (pal.base00 || "${c.base00}")
readonly property color base01: Qt.lighter(base00, 1.7) // card readonly property color base01: Qt.lighter(base00, 1.7) // card
readonly property color base02: Qt.lighter(base00, 2.4) // hover / chip / track readonly property color base02: Qt.lighter(base00, 2.4) // hover / chip / track
// Ink, wallpaper-derived: base05 primary, base04 muted, // Ink, wallpaper-derived: base05 primary, base04 muted,
// base03 disabled (also the border colour). // base03 disabled (also the border colour).
readonly property color base03: "#" + (pal.base03 || "${c.base03}") readonly property color base03: "#" + pal.base03
readonly property color base04: "#" + (pal.base04 || "${c.base04}") readonly property color base04: "#" + pal.base04
readonly property color base05: "#" + (pal.base05 || "${c.base05}") readonly property color base05: "#" + pal.base05
// The one themed accent: active, focused, selected, filled. // The one themed accent: active, focused, selected, filled.
readonly property color base0D: "#" + (pal.base0D || "${c.base0D}") readonly property color base0D: "#" + pal.base0D
// Status colours: fixed hues, pulled toward the theme. // Status colours: fixed hues, pulled toward the theme.
// Sourcing these from stylix doesn't work base08-base0F all // Sourcing these from stylix doesn't work base08-base0F all