docs: plan the hyprland desktop epic (spec, ADR, tasks)
Add the hyprland-desktop spec, ADR 0003 recording the compositor choice over Sway/KDE/niri, and the task breakdown (0021-0030) that decomposes the desktop into granular grouped modules. Record the corrected host GPU facts (zeus is AMD, raichu the sole Nvidia machine) in CLAUDE.md.
This commit is contained in:
34
.claude/adr/0003-hyprland-compositor.md
Normal file
34
.claude/adr/0003-hyprland-compositor.md
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
status: accepted
|
||||
---
|
||||
|
||||
# Hyprland as the keyboard-driven desktop compositor
|
||||
|
||||
The graphical desktop is built on **Hyprland**, a keyboard-driven Wayland tiling compositor, as a single choice serving both the laptop (neogaia) and the future desktop (zeus).
|
||||
It matches how the operator already works: an i3 model of numbered workspaces and manual tiling, ported to bindings reachable entirely on a 60% keyboard.
|
||||
Among true tilers it comes closest to "just works" through its cohesive first-party companion tools (lock, idle, wallpaper, portal) and a large ecosystem, which buys down the assembly-and-breakage cost that made past minimal tiling setups expensive for the operator.
|
||||
|
||||
The gaming and driver dimension does not constrain the choice, because both Hosts drive Wayland without caveats: neogaia is Intel and zeus is AMD.
|
||||
Notably zeus is AMD, not Nvidia — Raichu is the only Nvidia machine, and it is a server with no desktop — so no Nvidia-on-Wayland pressure shapes the decision.
|
||||
With gaming survival off the table, the choice rests on workflow and low-friction rather than on tolerating a hostile driver.
|
||||
|
||||
## Considered Options
|
||||
|
||||
- **Sway.** Rejected: its i3-faithful minimalism is precisely what historically cost the operator hours of assembly and breakage.
|
||||
On AMD it games fine, but its only remaining edge over Hyprland was stability and purity — which the repo's pinning already provides, and which the operator's stated "just works" priority actively discounts.
|
||||
- **KDE Plasma.** Rejected: the most integrated and lowest-friction option, the best AMD gaming desktop, and the operator's prior environment — but mouse-first at its core and only keyboard-navigable at the margins, which works against the primary keyboard-first requirement.
|
||||
Its custom-tile-layout feature is an approximation of tiling on a floating desktop, not real automatic tiling.
|
||||
- **niri.** Rejected: its scrollable-tiling paradigm abandons numbered workspaces, which breaks the operator's core muscle memory of switching by number.
|
||||
It also has the smallest community of the candidates, a low-friction risk for a daily-driver desktop.
|
||||
- **A different compositor per Host** (a keyboard-pure laptop plus a separate gaming desktop). Rejected: it doubles the configuration and maintenance and defeats the goal of one transferable setup.
|
||||
It is unnecessary once AMD removes any gaming penalty from a keyboard-first compositor.
|
||||
|
||||
## Consequences
|
||||
|
||||
- One desktop Module set serves both Hosts.
|
||||
zeus adopts the identical desktop by enabling a single flag, with battery-sensitive knobs such as blur flipped on for its AMD headroom.
|
||||
- Hyprland's churn and occasional breakage are absorbed by the pinned, declarative, reversible configuration rather than by live fixing, so upgrades happen on the operator's schedule.
|
||||
- The desktop's lock, idle, keybind syntax, and portal are Hyprland-specific, so a future move to another compositor would be a rewrite rather than a swap.
|
||||
This is the accepted cost of the first-party-cohesion benefit.
|
||||
- Hyprland is taken from nixpkgs, with no compositor plugins this pass.
|
||||
Adopting the upstream Hyprland flake later, for a plugin or a bleeding-edge feature, is a contained change that mirrors the existing chaotic-nyx input pattern (an input that must not follow nixpkgs, carrying its own binary cache).
|
||||
173
.claude/spec/hyprland-desktop.md
Normal file
173
.claude/spec/hyprland-desktop.md
Normal file
@@ -0,0 +1,173 @@
|
||||
## Problem Statement
|
||||
|
||||
Neogaia currently boots to a console only.
|
||||
The laptop minimum viable install deliberately deferred everything graphical, so the operator works entirely from the terminal (fish, tmux, nvim, Claude Code) with no desktop to live in.
|
||||
|
||||
The operator wants a graphical desktop, and it must be primarily keyboard-driven.
|
||||
Their mental model is i3: numbered workspaces, `Super`+number to switch, manual tiling.
|
||||
They type on a 60% keyboard where arrow keys and the navigation cluster live behind a layer, so a keyboard-first workflow that never reaches for those keys matters.
|
||||
|
||||
The same desktop has to transfer to the future desktop Host (zeus), which must game well and stay low-friction in general.
|
||||
The operator previously ran KDE Plasma 6 bent into an i3 imitation and valued above all that it "just worked", but remembers past i3/Sway minimalism costing hours of fixing random breakage.
|
||||
That concern is now largely mitigated: NixOS makes the whole stack declarative, pinned, and reversible, and the agent absorbs the discovery and debugging that used to eat evenings.
|
||||
|
||||
## Solution
|
||||
|
||||
Add a keyboard-driven Wayland desktop built on Hyprland, expressed as a new grouped set of Modules.
|
||||
Enable it on neogaia now, and design it Host-agnostic so zeus adopts the identical desktop later by flipping a single flag.
|
||||
|
||||
Deliver a complete, daily-drivable session in one pass rather than a bare stub, because unlike the reimage this is fully reversible ("edit and rebuild"), so there is no safety reason to under-scope.
|
||||
The session covers the compositor, a text login, Nord theming, a status bar, a launcher, notifications, lock and idle, a wallpaper, clipboard history, screenshots, screen recording, and the desktop portals, together with the operator's ported keybinds and input tuning.
|
||||
|
||||
Theme the whole graphical layer Nord from a single source (Stylix), scoped so it owns only the new graphical surface and leaves the existing terminal Modules' hand-themes untouched.
|
||||
Leave gaming out entirely; it belongs to a future zeus-oriented Module, and neogaia is not a gaming machine.
|
||||
|
||||
## User Stories
|
||||
|
||||
1. As the operator, I want neogaia to boot into a keyboard-driven Hyprland session, so that I can live in a graphical desktop without leaving my keyboard-first workflow.
|
||||
2. As the operator, I want the desktop expressed as Host-agnostic Modules enabled by a single flag, so that zeus can adopt the identical desktop later without rework.
|
||||
3. As the operator, I want a text-based login, so that I log in mouse-free without a heavy graphical display manager.
|
||||
4. As the operator, I want the whole graphical layer themed Nord from one source, so that GTK, Qt, the bar, the lock screen, and the launcher cohere without me hand-theming each, while my existing nvim, tmux, and fish themes stay exactly as they are.
|
||||
5. As the operator, I want a fast modern terminal launched on `Super+Return`, so that my tmux and nvim stack has a clean frame and my old muscle memory for opening a terminal carries over.
|
||||
6. As the operator, I want a status bar showing workspaces with per-application icons, clock, battery, network, audio, media controls, and a do-not-disturb toggle, so that I can read system state at a glance.
|
||||
7. As the operator, I want a search-everything launcher covering applications, open windows, math evaluation, and emoji, reused as the frontend for clipboard history and a power menu, so that one keybound tool handles launching and utility menus.
|
||||
8. As the operator, I want notification toasts with do-not-disturb and history recall, so that I see notifications and can retrieve ones I missed.
|
||||
9. As the operator, I want a secure lock screen and idle management, so that going idle, suspending, or closing the lid always lands me at a locked screen, and the lock survives even if the locker process crashes.
|
||||
10. As the operator, I want a single static Nord wallpaper, so that the desktop looks coherent with no extra moving parts and no battery cost.
|
||||
11. As the operator, I want clipboard history picked through the launcher, so that I can paste from recent copies entirely by keyboard.
|
||||
12. As the operator, I want keyboard-driven screenshots for a region, the active window, or the full screen that open in an annotation editor by default and land in both the clipboard and a file, so that capturing and marking up is a single reflex.
|
||||
13. As the operator, I want a keybound screen recorder that selects a region and then toggles recording, so that capturing demos becomes a habit.
|
||||
14. As the operator, I want screen sharing to work inside applications, so that video calls and browser screen-share function.
|
||||
15. As the operator, I want my keybinds ported from my KDE/i3 scheme but expressed entirely in `hjkl` and letters with no arrow or navigation-cluster keys, so that every binding is reachable on my 60% keyboard.
|
||||
16. As the operator, I want numbered-workspace bindings, so that my i3 muscle memory of `Super`+number to switch and `Super`+`Shift`+number to move carries over unchanged.
|
||||
17. As the operator, I want Caps mapped to Escape, a US-only layout, snappy key-repeat, and touchpad tap-to-click, natural scroll, and disable-while-typing with flat mouse acceleration, so that input feels like home on the laptop.
|
||||
18. As the operator, I want subtle animations with rounding and small gaps but no blur on the laptop, so that the desktop feels modern without draining the battery.
|
||||
19. As the operator, I want the desktop built from granular single-purpose Modules grouped together with an explicit aggregator, so that a Host enables the whole desktop with one flag yet can still override any single piece.
|
||||
20. As the operator, I want gaming deliberately excluded from this pass, so that neogaia's desktop stays focused and the gaming stack lands with zeus.
|
||||
21. As the operator, I want the whole Host to still build green under the existing check, so that I gain confidence before switching a live machine.
|
||||
|
||||
## Implementation Decisions
|
||||
|
||||
**Direction and compositor**
|
||||
|
||||
- Hyprland is the compositor, on neogaia now and zeus later, chosen as a single keyboard-driven tiler that serves both Hosts.
|
||||
It matches the operator's i3 workflow (numbered workspaces, manual tiling) while getting closest to "just works" among true tilers through its cohesive first-party companion tools and large ecosystem.
|
||||
- The choice was made over Sway (its minimalism is the very thing that cost the operator evenings), KDE Plasma (mouse-first at heart), and niri (its scrollable-tiling paradigm abandons numbered workspaces and so breaks the operator's core muscle memory).
|
||||
- The gaming/driver dimension does not discriminate here: neogaia is Intel and zeus is AMD, both of which drive Wayland flawlessly, so the decision rested on workflow and low-friction rather than on surviving a hostile driver.
|
||||
This corrects a stale assumption in the laptop spec (see Further Notes).
|
||||
- Hyprland is sourced from nixpkgs rather than the upstream Hyprland flake.
|
||||
The NixOS-level program integration owns the session, portals, and polkit, and home-manager owns the user configuration, sharing one Hyprland package so there is never a version split.
|
||||
The session is launched through the universal Wayland session manager from the greeter for clean systemd session and environment integration.
|
||||
No compositor plugins are adopted this pass, which removes the main reason to take the flake; moving to the flake later is a contained change that mirrors the existing chaotic-nyx pattern (an input that must not follow nixpkgs, with its own binary cache).
|
||||
|
||||
**Session and theming**
|
||||
|
||||
- Login uses greetd with the tuigreet text greeter.
|
||||
This is mouse-free and lightweight, avoiding a heavy graphical display manager and its Qt/GTK weight.
|
||||
- Theming uses Stylix, scoped to the graphical layer.
|
||||
A single Nord base16 scheme drives colors, system fonts, cursor, and the static wallpaper across the new graphical surface (GTK, Qt, bar, lock, launcher, notifications, compositor colors).
|
||||
Stylix targets for the existing terminal tools (nvim, tmux, fish) are left off so their established hand-themes stand unchanged.
|
||||
The terminal is themed by Stylix where its target is mature, with hand-written Nord as a fallback otherwise.
|
||||
This decision is highly reversible: Stylix toggles per target, so the graphical layer can migrate toward or away from manual theming later at low cost.
|
||||
|
||||
**Components**
|
||||
|
||||
- Terminal: Ghostty.
|
||||
- Status bar: Waybar, showing workspaces with per-application icons plus clock, battery, network, audio, MPRIS media controls, and a do-not-disturb toggle.
|
||||
No overview/exposé plugin is used; the workspace indicators are sufficient.
|
||||
- Launcher: rofi (the Wayland fork), combining application-run, binary-run, and window-switch modes into one prompt, plus math-evaluation and emoji modes.
|
||||
It is reused as the dmenu-style frontend for clipboard history and a power menu, so one tool serves several jobs.
|
||||
- Notifications: mako, with do-not-disturb and history recall.
|
||||
Media controls and the do-not-disturb toggle live in the bar rather than in a separate notification center.
|
||||
- Lock and idle: hyprlock and hypridle.
|
||||
hyprlock uses the compositor session-lock protocol, so the lock surface is owned by the compositor and survives a locker crash.
|
||||
hypridle is wired for lock-on-idle, screen-off, lock-before-suspend, and lid-close, with tunable timeouts.
|
||||
- Wallpaper: a single static image set by Stylix.
|
||||
- Clipboard: cliphist with wl-clipboard, storing text and image history, picked through rofi.
|
||||
- Screenshots: grim and slurp wrapped by grimblast, routed through the satty annotation editor so that annotation is the default on region, active-window, and full-screen captures, each exporting to both the clipboard and a file.
|
||||
- Screen recording: wf-recorder, region-select-first and video-only (no audio), toggled by a keybind with a bar recording indicator and notifications.
|
||||
- Portals: the Hyprland desktop portal (screencast, screenshot, global shortcuts) plus the GTK portal (file dialogs and appearance).
|
||||
Screen sharing in applications depends on these regardless of whether the recorder is present.
|
||||
|
||||
**Keybinds**
|
||||
|
||||
The scheme ports the operator's KDE/i3 bindings but is expressed entirely in `hjkl` and letters, with no arrow or navigation-cluster keys, so it is fully reachable on a 60% keyboard.
|
||||
Bindings that were quick-tile-to-half on the floating KDE desktop are reclaimed for real tiling actions, because that gesture is meaningless in an automatic tiler.
|
||||
|
||||
| Action | Bind |
|
||||
|---|---|
|
||||
| Switch to workspace N | `Super`+`1`..`9` |
|
||||
| Move window to workspace N | `Super`+`Shift`+`1`..`9` |
|
||||
| Move focus | `Super`+`h`/`j`/`k`/`l` |
|
||||
| Move window in layout | `Super`+`Shift`+`h`/`j`/`k`/`l` |
|
||||
| Resize | `Super`+`Alt`+`h`/`j`/`k`/`l` |
|
||||
| Terminal | `Super`+`Return` |
|
||||
| Launcher | `Super`+`R` |
|
||||
| Lock | `Super`+`X` |
|
||||
| Toggle floating | `Super`+`Space` |
|
||||
| Fullscreen | `Super`+`F` |
|
||||
| Toggle split | `Super`+`T` |
|
||||
| Close window | `Super`+`Shift`+`Q` |
|
||||
| Force-kill | `Super`+`Ctrl`+`Q` |
|
||||
| Screenshot region / window / full (to satty) | `Super`+`L` / `Super`+`Shift`+`L` / `Super`+`Ctrl`+`L` |
|
||||
| Clipboard history | `Super`+`Shift`+`V` |
|
||||
| Record toggle (region first) | `Super`+`Shift`+`R` |
|
||||
| Volume / brightness / media | `XF86` hardware keys |
|
||||
|
||||
**Input**
|
||||
|
||||
- US-only keyboard layout, with no layout switcher.
|
||||
- Caps mapped to Escape, with Shift+Caps still producing a real CapsLock.
|
||||
- Key-repeat tuned snappy (a short delay before repeat begins, a fast repeat rate).
|
||||
- Touchpad with tap-to-click, natural scroll, and disable-while-typing.
|
||||
- Mouse with flat acceleration.
|
||||
|
||||
**Feel**
|
||||
|
||||
- Tasteful, subtle animations with modest rounding and small gaps.
|
||||
- Blur is off on the laptop, where it is the single biggest battery cost; it remains a knob a Host such as zeus can enable.
|
||||
|
||||
**Module structure**
|
||||
|
||||
- The desktop is a set of granular, single-purpose Modules grouped under a desktop directory, each independently toggleable so pieces stay reusable and the files stay focused.
|
||||
The tightly coupled Hyprland-native pieces (compositor, lock, idle) are grouped in a subdirectory within that group.
|
||||
- An explicit aggregator Module turns the desktop on.
|
||||
Guarded by its own enable, it sets each piece's enable at default priority so that a Host enables the whole desktop with one flag while retaining the ability to override any single piece.
|
||||
The aggregator hand-lists the pieces it enables rather than scanning the directory, so a newly added file stays inert until deliberately added to that list; this keeps the whole desktop legible from one file.
|
||||
- The desktop's enable options are namespaced under a single desktop group, so a Host's checklist gains one desktop entry and the aggregator itself reads as the sub-checklist of what that entry means.
|
||||
- This uses the existing recursive Auto-loader as-is: every file in the group is imported unconditionally (inert until enabled), so no Skeleton change is needed.
|
||||
The aggregator/namespaced-group pattern is a deliberate evolution of the flat Module plus Host-as-checklist convention (see Further Notes).
|
||||
|
||||
## Testing Decisions
|
||||
|
||||
- A good test asserts externally-observable evaluation and build success of the whole Host, not the internals of any individual Module.
|
||||
This mirrors the laptop MVI's stance, where the config-merge model makes the whole-Host build the meaningful unit and the highest available seam.
|
||||
- Primary seam (required, existing): the neogaia Host evaluates and its system toplevel builds under the flake check.
|
||||
Building the toplevel drives the Auto-loader discovering the new Modules, the aggregator fan-out, home-manager integration, the full Stylix wiring, the Hyprland program integration, and package availability, surfacing nearly all config-authoring errors short of rendering a frame.
|
||||
- Cheap targeted checks: evaluate specific configuration paths to confirm the desktop aggregator fans out, the Stylix scheme resolves to Nord, and Hyprland is enabled, reusing the repo's existing lightweight eval-probe pattern.
|
||||
- No Module-level unit tests are added; there is no seam below the whole-Host build worth testing here, and the prior art is the laptop MVI's build-the-toplevel check.
|
||||
- The genuine end-to-end confirmation is manual and irreducible: switch the configuration on neogaia, log in through the greeter, and exercise the live session (keybinds, lock, screenshot, clipboard, launcher).
|
||||
A graphical session cannot self-test headless, but unlike the reimage this is reversible, so verification is done by living in it with a safety net (roll back a generation, drop to a console, or disable the desktop flag).
|
||||
- VM-based graphical CI (boot assertions under a NixOS test) is deferred, consistent with the laptop MVI's stated stance.
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- The gaming stack (Steam, gamescope, Proton, replay-buffer recording, OBS), which belongs to a future zeus-oriented Module.
|
||||
- The zeus Host itself, and multi-monitor/output configuration, since there is no second display to design against yet; monitor focus and move bindings are deferred with it.
|
||||
- Any non-Hyprland desktop; KDE, Sway, and niri were considered and rejected.
|
||||
- The upstream Hyprland flake and compositor plugins, including workspace-overview/exposé, which are explicitly not adopted this pass.
|
||||
- Migrating the existing nvim, tmux, and fish themes into Stylix; they stay hand-themed.
|
||||
- Dynamic, animated, or video wallpaper, and wallpaper cycling.
|
||||
- Screen-recording audio and a full-screen recording variant.
|
||||
- A slide-out notification-center panel and a batteries-included desktop panel; both were considered and rejected in favor of the minimal, Stylix-coherent stack.
|
||||
- Any change to the Skeleton or the Auto-loader; the structure uses them unchanged.
|
||||
- Any secret wiring.
|
||||
|
||||
## Further Notes
|
||||
|
||||
- The compositor decision (Hyprland over Sway, KDE, and niri) is hard to reverse and the result of a real trade-off, so it should be recorded as an ADR.
|
||||
- The aggregator plus namespaced-group Module pattern is a deliberate departure from the flat, Host-as-full-checklist convention, and is worth recording as a short ADR or a conventions note so its intent is not relearned.
|
||||
- The laptop MVI's out-of-scope line attributing Nvidia to zeus is factually wrong: zeus runs an AMD GPU, and Raichu (a server with no desktop) is the only Nvidia machine.
|
||||
The laptop MVI is a historical document and is left unchanged, so the accurate fact is recorded here and in ADR 0003 instead.
|
||||
- The ported keybind scheme is derived from the operator's prior KDE Plasma 6 configuration (nine numbered desktops, `Super`+number bindings, a terminal on `Super`+`Return`, Caps mapped to Escape, and custom per-desktop tile layouts), which lives in this repo's git history under the old reference config.
|
||||
- Neogaia is Intel and zeus is AMD, both of which drive Wayland without driver caveats; this is what lets one keyboard-first compositor serve both Hosts rather than forcing a per-Host divergence.
|
||||
34
.claude/tasks/0021-desktop-group-and-hyprland-session.md
Normal file
34
.claude/tasks/0021-desktop-group-and-hyprland-session.md
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
spec: hyprland-desktop
|
||||
---
|
||||
|
||||
## What to build
|
||||
|
||||
The tracer bullet for the whole desktop: a keyboard-driven Hyprland session that neogaia can log into and open a terminal in.
|
||||
|
||||
Create the `modules/desktop/` group with an explicit aggregator, guarded by its own `modules.desktop.enable`, that hand-lists and turns on each piece at default priority so a host enables the whole desktop with one flag yet can still override any single piece.
|
||||
Namespace every desktop enable under one desktop group so a host's checklist gains one entry.
|
||||
Place the tightly coupled Hyprland-native pieces (starting with the compositor) in a subdirectory within the group.
|
||||
|
||||
Wire Hyprland from nixpkgs: the NixOS program integration owns the session and polkit, home-manager owns the user configuration, and both share one Hyprland package so there is never a version split.
|
||||
The session is launched through the universal Wayland session manager from the greeter.
|
||||
Login is greetd with the tuigreet text greeter, mouse-free and lightweight.
|
||||
|
||||
Port the operator's KDE/i3 keybinds expressed entirely in `hjkl` and letters with no arrow or navigation-cluster keys: numbered-workspace switch and move, focus and window movement, resize, terminal, floating, fullscreen, split, close, and force-kill, per the spec's keybind table.
|
||||
Tune input: US-only layout with no switcher, Caps mapped to Escape with Shift+Caps still producing CapsLock, snappy key-repeat, touchpad tap-to-click plus natural scroll plus disable-while-typing, and flat mouse acceleration.
|
||||
Set the feel: subtle animations, modest rounding, small gaps, and blur off (left as a knob a host such as zeus can enable).
|
||||
Install Ghostty as the terminal on `Super+Return`.
|
||||
|
||||
Enable the desktop on neogaia.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- [ ] `modules/desktop/` exists with an aggregator exposing `modules.desktop.enable` that hand-lists and enables its pieces at default priority, each piece independently overridable.
|
||||
- [ ] Desktop enable options are namespaced under a single desktop group; the Hyprland-native compositor lives in a subdirectory of the group.
|
||||
- [ ] Hyprland is sourced from nixpkgs; the NixOS integration and the home-manager user config share one Hyprland package.
|
||||
- [ ] The session launches through the universal Wayland session manager from a greetd/tuigreet text login.
|
||||
- [ ] Keybinds match the spec's table, using only `hjkl`, letters, and number rows — no arrow or navigation-cluster keys.
|
||||
- [ ] Input is tuned: US-only layout, Caps→Escape (Shift+Caps = CapsLock), snappy key-repeat, touchpad tap-to-click + natural scroll + disable-while-typing, flat mouse acceleration.
|
||||
- [ ] Animations, rounding, and small gaps are on; blur is off and remains host-overridable.
|
||||
- [ ] Ghostty opens on `Super+Return`.
|
||||
- [ ] neogaia enables `modules.desktop` and builds green under `nix flake check`.
|
||||
20
.claude/tasks/0022-stylix-nord-theming.md
Normal file
20
.claude/tasks/0022-stylix-nord-theming.md
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
spec: hyprland-desktop
|
||||
blocked-by: 0021-desktop-group-and-hyprland-session
|
||||
---
|
||||
|
||||
## What to build
|
||||
|
||||
Theme the whole new graphical layer Nord from a single source, and set the wallpaper.
|
||||
|
||||
Add Stylix as a flake input and a desktop theming module that drives colors, system fonts, and cursor from one Nord base16 scheme across the graphical surface (GTK, Qt, and the compositor colors), plus a single static Nord wallpaper set by Stylix.
|
||||
Scope Stylix to the graphical layer only: leave its targets for the existing terminal tools (nvim, tmux, fish) off so their established hand-themes stand unchanged.
|
||||
The theming is reversible per target, so individual surfaces can migrate toward or away from manual theming later.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- [ ] Stylix is a flake input, wired into the host build.
|
||||
- [ ] A desktop theming module resolves a single Nord base16 scheme and applies it to GTK, Qt, cursor, and system fonts.
|
||||
- [ ] A single static Nord wallpaper is set by Stylix; no dynamic, animated, or cycling wallpaper.
|
||||
- [ ] Stylix targets for nvim, tmux, and fish are off, leaving their existing themes untouched.
|
||||
- [ ] neogaia builds green under `nix flake check`, and an eval probe confirms the resolved scheme is Nord.
|
||||
19
.claude/tasks/0023-waybar-status-bar.md
Normal file
19
.claude/tasks/0023-waybar-status-bar.md
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
spec: hyprland-desktop
|
||||
blocked-by: 0021-desktop-group-and-hyprland-session
|
||||
---
|
||||
|
||||
## What to build
|
||||
|
||||
A Waybar status bar that reads system state at a glance.
|
||||
|
||||
Add a Waybar module to the desktop group, enabled through the aggregator, showing workspaces with per-application icons plus a clock, battery, network, audio, MPRIS media controls, and a do-not-disturb toggle.
|
||||
No overview/exposé plugin: the workspace indicators are sufficient.
|
||||
The do-not-disturb toggle and media controls live in the bar rather than in a separate notification center.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- [ ] A Waybar module exists in the desktop group and is enabled by the aggregator.
|
||||
- [ ] The bar shows workspaces with per-application icons, a clock, battery, network, audio, MPRIS media controls, and a do-not-disturb toggle.
|
||||
- [ ] No overview/exposé plugin is used.
|
||||
- [ ] neogaia builds green under `nix flake check`.
|
||||
20
.claude/tasks/0024-rofi-launcher.md
Normal file
20
.claude/tasks/0024-rofi-launcher.md
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
spec: hyprland-desktop
|
||||
blocked-by: 0021-desktop-group-and-hyprland-session
|
||||
---
|
||||
|
||||
## What to build
|
||||
|
||||
A search-everything launcher, so one keybound tool handles launching and utility menus.
|
||||
|
||||
Add a rofi (Wayland fork) module to the desktop group, enabled through the aggregator, combining application-run, binary-run, and window-switch into one prompt, plus math-evaluation and emoji modes.
|
||||
Bind it on `Super+R`.
|
||||
Structure it so it is reusable as the dmenu-style frontend for later utility menus (clipboard history, power menu), and provide a power menu that uses it.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- [ ] A rofi module exists in the desktop group and is enabled by the aggregator.
|
||||
- [ ] rofi combines application-run, binary-run, and window-switch modes, plus math evaluation and emoji.
|
||||
- [ ] rofi opens on `Super+R`.
|
||||
- [ ] rofi is usable as a dmenu-style frontend for utility menus, and a power menu is provided through it.
|
||||
- [ ] neogaia builds green under `nix flake check`.
|
||||
18
.claude/tasks/0025-mako-notifications.md
Normal file
18
.claude/tasks/0025-mako-notifications.md
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
spec: hyprland-desktop
|
||||
blocked-by: 0021-desktop-group-and-hyprland-session
|
||||
---
|
||||
|
||||
## What to build
|
||||
|
||||
Notification toasts with do-not-disturb and history recall, so missed notifications can be retrieved.
|
||||
|
||||
Add a mako module to the desktop group, enabled through the aggregator, rendering notification toasts with a do-not-disturb mode and history recall.
|
||||
The do-not-disturb toggle and media controls live in the bar, not in a separate notification-center panel.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- [ ] A mako module exists in the desktop group and is enabled by the aggregator.
|
||||
- [ ] Notification toasts appear, with do-not-disturb and history recall.
|
||||
- [ ] No separate slide-out notification-center panel is added.
|
||||
- [ ] neogaia builds green under `nix flake check`.
|
||||
21
.claude/tasks/0026-hyprlock-and-hypridle.md
Normal file
21
.claude/tasks/0026-hyprlock-and-hypridle.md
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
spec: hyprland-desktop
|
||||
blocked-by: 0021-desktop-group-and-hyprland-session
|
||||
---
|
||||
|
||||
## What to build
|
||||
|
||||
A secure lock screen and idle management, so going idle, suspending, or closing the lid always lands at a locked screen.
|
||||
|
||||
Add hyprlock and hypridle modules in the Hyprland-native subdirectory of the desktop group, enabled through the aggregator.
|
||||
hyprlock uses the compositor session-lock protocol so the lock surface is owned by the compositor and survives a locker crash.
|
||||
hypridle is wired for lock-on-idle, screen-off, lock-before-suspend, and lid-close, with tunable timeouts.
|
||||
Bind lock on `Super+X`.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- [ ] hyprlock and hypridle modules exist in the Hyprland-native subdirectory and are enabled by the aggregator.
|
||||
- [ ] hyprlock uses the compositor session-lock protocol.
|
||||
- [ ] hypridle triggers lock-on-idle, screen-off, lock-before-suspend, and lid-close, with tunable timeouts.
|
||||
- [ ] Lock is bound on `Super+X`.
|
||||
- [ ] neogaia builds green under `nix flake check`.
|
||||
18
.claude/tasks/0027-cliphist-clipboard-history.md
Normal file
18
.claude/tasks/0027-cliphist-clipboard-history.md
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
spec: hyprland-desktop
|
||||
blocked-by: 0024-rofi-launcher
|
||||
---
|
||||
|
||||
## What to build
|
||||
|
||||
Clipboard history picked entirely by keyboard.
|
||||
|
||||
Add a cliphist module (with wl-clipboard) to the desktop group, enabled through the aggregator, storing both text and image history and picked through rofi.
|
||||
Bind the picker on `Super+Shift+V`.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- [ ] A cliphist module (with wl-clipboard) exists in the desktop group and is enabled by the aggregator.
|
||||
- [ ] Text and image copies are recorded to history.
|
||||
- [ ] The history is picked through rofi and bound on `Super+Shift+V`.
|
||||
- [ ] neogaia builds green under `nix flake check`.
|
||||
19
.claude/tasks/0028-screenshot-capture.md
Normal file
19
.claude/tasks/0028-screenshot-capture.md
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
spec: hyprland-desktop
|
||||
blocked-by: 0021-desktop-group-and-hyprland-session
|
||||
---
|
||||
|
||||
## What to build
|
||||
|
||||
Keyboard-driven screenshots that open in an annotation editor by default and land in both the clipboard and a file.
|
||||
|
||||
Add a screenshot module to the desktop group, enabled through the aggregator, using grim and slurp wrapped by grimblast and routed through the satty annotation editor so annotation is the default.
|
||||
Cover region, active-window, and full-screen captures, each exporting to both the clipboard and a file.
|
||||
Bind region on `Super+L`, active window on `Super+Shift+L`, and full screen on `Super+Ctrl+L`.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- [ ] A screenshot module exists in the desktop group and is enabled by the aggregator.
|
||||
- [ ] Region, active-window, and full-screen captures work, each opening in satty and exporting to both clipboard and file.
|
||||
- [ ] Captures are bound on `Super+L`, `Super+Shift+L`, and `Super+Ctrl+L`.
|
||||
- [ ] neogaia builds green under `nix flake check`.
|
||||
20
.claude/tasks/0029-screen-recording.md
Normal file
20
.claude/tasks/0029-screen-recording.md
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
spec: hyprland-desktop
|
||||
blocked-by: [0023-waybar-status-bar, 0025-mako-notifications]
|
||||
---
|
||||
|
||||
## What to build
|
||||
|
||||
A keybound screen recorder that selects a region and then toggles recording.
|
||||
|
||||
Add a wf-recorder module to the desktop group, enabled through the aggregator, that selects a region first and then toggles video-only recording (no audio), bound on `Super+Shift+R`.
|
||||
Surface a recording indicator in the Waybar bar and notification toasts on start and stop.
|
||||
No audio capture and no full-screen recording variant.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- [ ] A wf-recorder module exists in the desktop group and is enabled by the aggregator.
|
||||
- [ ] The recorder selects a region first, then toggles video-only recording on `Super+Shift+R`.
|
||||
- [ ] A recording indicator appears in the bar, and notifications fire on start and stop.
|
||||
- [ ] No audio is captured and no full-screen variant is provided.
|
||||
- [ ] neogaia builds green under `nix flake check`.
|
||||
18
.claude/tasks/0030-desktop-portals.md
Normal file
18
.claude/tasks/0030-desktop-portals.md
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
spec: hyprland-desktop
|
||||
blocked-by: 0021-desktop-group-and-hyprland-session
|
||||
---
|
||||
|
||||
## What to build
|
||||
|
||||
Screen sharing that works inside applications, so video calls and browser screen-share function.
|
||||
|
||||
Add a portals module to the desktop group, enabled through the aggregator, wiring the Hyprland desktop portal (screencast, screenshot, global shortcuts) plus the GTK portal (file dialogs and appearance).
|
||||
In-app screen sharing depends on these regardless of whether the recorder is present.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- [ ] A portals module exists in the desktop group and is enabled by the aggregator.
|
||||
- [ ] The Hyprland desktop portal (screencast, screenshot, global shortcuts) and the GTK portal (file dialogs, appearance) are both configured.
|
||||
- [ ] In-app screen sharing is available independent of the screen recorder.
|
||||
- [ ] neogaia builds green under `nix flake check`.
|
||||
@@ -94,3 +94,7 @@ The domain model (Host, Module, Skeleton, Auto-loader, Enable convention, overla
|
||||
The interpolated key makes it a dynamic attribute, which nix will not merge the way it merges static paths.
|
||||
Nest both under a single `home-manager.users.${user} = { ... }`.
|
||||
- **Verifying a nixvim change headless:** `programs.nixvim.build.package`'s wrapper has **no `-u`**, so running `$OUT/bin/nvim` loads the caller's `~/.config/nvim` (the dev host's real config), *not* the built config — silently. To exercise the built config, launch with `-u "$(nix build --no-link --print-out-paths .#…programs.nixvim.build.initFile)"` and a scratch `HOME`/`XDG_CONFIG_HOME`. `conceallevel` is window-local: set it with `opt_local`/`vim.wo`, never `vim.bo[buf]` (which errors).
|
||||
- Host GPUs: `neogaia` is Intel and `zeus` (the desktop) is **AMD**.
|
||||
`raichu`, a server with no desktop, is the only Nvidia machine.
|
||||
`laptop-mvi.md`'s out-of-scope line calls zeus Nvidia, but that is stale and the document is kept historical and unchanged, so do not infer any host's GPU from it.
|
||||
The corrected fact lives in ADR 0003 and the `hyprland-desktop` spec.
|
||||
|
||||
Reference in New Issue
Block a user