From 8be00bc273b6d2444aff9f8a1fbfcfa6d6020a94 Mon Sep 17 00:00:00 2001 From: funman300 Date: Fri, 24 Apr 2026 12:56:58 -0700 Subject: [PATCH] Replace swaylock with gtklock; centralise theme palette - Replace swaylock with gtklock (username + password form lockscreen) - Add gtklock/config.ini and gtklock/style.css (Tomorrow Night theme) - Update niri keybindings and swayidle to invoke gtklock -d - Update packages.txt: swaylock -> gtklock - Update install.sh: add AUR helper detection (yay/paru), symlink gtklock configs - Add theme/colors.css (CSS custom properties) and theme/colors.json - Update waybar/style.css, wofi/style.css, gtklock/style.css to import shared palette - Update README.md with project summary and component table - Add ARCHITECTURE.md and CLAUDE.md --- ARCHITECTURE.md | 286 +++++++++++++++++++++++++++++++++++++++++++++ CLAUDE.md | 204 ++++++++++++++++++++++++++++++++ README.md | 19 +++ gtklock/config.ini | 4 + gtklock/style.css | 72 ++++++++++++ install.sh | 19 ++- niri/config.kdl | 4 +- packages.txt | 2 +- theme/colors.css | 22 ++++ theme/colors.json | 15 +++ waybar/style.css | 26 +++-- wofi/style.css | 26 +++-- 12 files changed, 668 insertions(+), 31 deletions(-) create mode 100644 ARCHITECTURE.md create mode 100644 CLAUDE.md create mode 100644 gtklock/config.ini create mode 100644 gtklock/style.css create mode 100644 theme/colors.css create mode 100644 theme/colors.json diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md new file mode 100644 index 0000000..17af766 --- /dev/null +++ b/ARCHITECTURE.md @@ -0,0 +1,286 @@ +# ARCHITECTURE.md + +## Overview + +This system is a **Wayland-first desktop environment** built around the **Niri compositor**, designed for: + +* Tiling workflow +* Keyboard-driven interaction +* Minimal background processes +* Clean separation between components + +--- + +## High-Level Architecture + +``` + ┌──────────────┐ + │ greetd │ + │ + regreet │ + └──────┬───────┘ + │ + ▼ + ┌──────────────┐ + │ Niri │ + │ Compositor │ + └──────┬───────┘ + ┌───────────────┼────────────────┐ + ▼ ▼ ▼ + ┌────────┐ ┌────────┐ ┌──────────┐ + │ Waybar │ │ Mako │ │ Wofi │ + └────────┘ └────────┘ └──────────┘ + │ │ │ + ▼ ▼ ▼ + Status UI Notifications App Launcher + + ┌────────────────────────────────────┐ + ▼ ▼ + Alacritty GTK Apps / CLI + │ + ▼ + Fish + Starship +``` + +--- + +## Component Responsibilities + +### Niri (Core) + +* Window management +* Input handling +* Layout control +* Workspace logic + +**Owns:** + +* Keybindings +* Window rules +* Focus behavior + +--- + +### Waybar (Status Layer) + +* Displays system info (time, CPU, network, etc.) +* Acts as visual feedback layer + +**Design constraints:** + +* No heavy scripts +* Prefer event-driven updates + +--- + +### Mako (Notifications) + +* Handles all desktop notifications + +**Rules:** + +* Short timeouts +* Minimal visual noise +* No stacking chaos + +--- + +### Wofi (Launcher) + +* Application launcher + runner + +**Usage modes:** + +* drun (desktop apps) +* run (commands) + +--- + +### Terminal Stack + +#### Alacritty + +* GPU-accelerated terminal +* No tabs (delegated to WM) + +#### Fish + +* Interactive shell + +#### Starship + +* Prompt renderer + +--- + +### Session & Login + +#### greetd + regreet + +* Lightweight login manager +* Starts Niri session + +--- + +### Lock Screen + +#### gtklock + +* Simple Wayland-native lockscreen + +--- + +### Background Services + +| Function | Tool | +| ----------- | ------------ | +| Wallpaper | swww | +| Screenshots | grim + slurp | +| Clipboard | cliphist | + +--- + +## Data Flow + +### Startup Sequence + +1. greetd starts +2. regreet authenticates user +3. Niri session launches +4. Autostart: + + * waybar + * mako + * swww + * cliphist (if enabled) + +--- + +### User Interaction Flow + +**Launching Apps** + +``` +Keybind → Wofi → Exec → Niri manages window +``` + +**Notifications** + +``` +App → DBus → Mako → Render +``` + +**Status Updates** + +``` +System → Waybar module → Display +``` + +--- + +## Configuration Strategy + +### Centralized via Symlinks + +``` +~/.config/ +├── niri/ +├── waybar/ +├── alacritty/ +├── fish/ +├── starship.toml +├── mako/ +├── wofi/ +└── gtklock/ +``` + +All configs are sourced from the repo via: + +``` +install.sh → ln -s +``` + +--- + +## Theming Architecture + +### Global Theme: Tomorrow Night + +Applied consistently across: + +* GTK (Materia-dark) +* Icons (Papirus) +* Terminal +* Waybar +* Wofi + +### Recommended Structure + +``` +theme/ +├── colors.json (optional future) +├── gtk.css +├── waybar.css +└── wofi.css +``` + +--- + +## Extensibility Model + +### Safe Extensions + +* Add Waybar modules (lightweight) +* Add Wofi modes +* Extend Niri keybindings +* Add CLI tools + +### Risky Extensions + +* Background daemons +* Polling scripts +* X11 compatibility layers +* Overly dynamic configs + +--- + +## Performance Considerations + +* Avoid blocking shell scripts +* Keep Waybar modules lightweight +* Minimize startup processes +* Prefer static config over runtime logic + +--- + +## Failure Modes + +| Issue | Likely Cause | +| --------------------- | ------------------- | +| Black screen on login | Niri config error | +| Missing bar | Waybar not launched | +| No notifications | Mako not running | +| Slow shell | Fish config bloat | + +--- + +## Future Improvements + +* Shared theme variables across all tools +* Config templating (optional, must stay transparent) +* Per-host overrides +* Optional feature flags (minimal) + +--- + +## Guiding Philosophy + +This system is: + +* **Predictable** +* **Minimal** +* **Fast** +* **Keyboard-first** + +Every addition must justify its existence. + +If it adds complexity without clear benefit, it should not be included. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..4c2bd10 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,204 @@ +# CLAUDE.md + +## Purpose + +This repository defines a complete Wayland desktop environment built around **Niri**, with a focus on: + +* Simplicity +* Reproducibility +* Fast startup +* Low cognitive overhead +* Clean separation of concerns + +Claude should act as a **systems engineer**, not just a script generator. + +--- + +## Core Principles + +### 1. Single Source of Truth + +* All configuration lives in `~/.config` via symlinks +* No duplication across tools +* Shared values (theme, fonts, gaps, etc.) should be centralized + +### 2. Idempotent Setup + +* `install.sh` must be safe to re-run +* No destructive operations without explicit flags +* Detect and skip existing correct state + +### 3. Composability + +* Each tool (waybar, mako, wofi, etc.) is independent +* No hidden coupling unless explicitly documented + +### 4. Declarative > Imperative + +* Prefer static config over runtime scripts +* Avoid background daemons unless required + +--- + +## Expected Claude Behavior + +When modifying this repo, Claude should: + +### Configuration Changes + +* Keep configs minimal and readable +* Avoid introducing magic or implicit behavior +* Prefer explicit keybindings and comments + +### Adding Features + +* Justify *why* the feature exists +* Ensure it fits Wayland + Niri workflow +* Avoid X11 dependencies unless unavoidable + +### Refactoring + +* Reduce duplication across configs +* Extract shared values (colors, fonts, spacing) +* Keep file structure intuitive + +--- + +## Directory Expectations + +``` +dotfiles/ +├── config/ +│ ├── niri/ +│ ├── waybar/ +│ ├── alacritty/ +│ ├── fish/ +│ ├── starship/ +│ ├── wofi/ +│ ├── mako/ +│ ├── gtklock/ +│ └── ... +├── install.sh +├── packages.txt +└── README.md +``` + +--- + +## Tooling Rules + +### Niri + +* All keybindings must be defined here +* Window rules must be deterministic +* Avoid runtime scripting where possible + +### Waybar + +* Keep modules minimal +* Prefer JSON config over scripts +* Avoid polling when event-based is possible + +### Fish + Starship + +* Fast startup is critical +* No blocking operations +* Avoid heavy plugins + +### Wofi + +* Keep styling consistent with GTK theme +* Avoid unnecessary wrappers + +### Mako + +* Notifications should be minimal and non-intrusive +* Timeout defaults should be short + +--- + +## Theming + +Theme: **Tomorrow Night** + +Ensure consistency across: + +* GTK (Materia-dark) +* Icons (Papirus) +* Terminal (Alacritty) +* Waybar +* Wofi + +Claude should: + +* Reuse the same color palette everywhere +* Avoid hardcoding colors in multiple places + +--- + +## Install Script Expectations + +`install.sh` must: + +1. Symlink configs into `~/.config` +2. Install packages from `packages.txt` +3. Detect distro (Arch-based assumed unless specified) +4. Fail fast on errors +5. Print clear status messages + +--- + +## Anti-Patterns (DO NOT DO) + +* ❌ Duplicate configs across tools +* ❌ Add large frameworks or dependencies +* ❌ Introduce race conditions in startup +* ❌ Use sleep-based timing hacks +* ❌ Hardcode machine-specific paths + +--- + +## Safe Enhancements + +Claude may suggest: + +* Shared theme variables +* Config generation (if simple and transparent) +* Modular config structure +* Performance improvements (startup, memory) + +--- + +## Testing Expectations + +After changes: + +* Niri starts without errors +* Waybar loads correctly +* No missing fonts/icons +* No broken keybindings +* No noticeable startup delay + +--- + +## Output Style + +When generating code: + +* Provide complete files (not fragments) +* Keep formatting clean +* Avoid unnecessary comments +* Prefer clarity over cleverness + +--- + +## Summary + +This is a **minimal, fast, reproducible Wayland environment**. + +Claude’s role is to: + +* Maintain clarity +* Prevent bloat +* Improve consistency +* Keep everything predictable diff --git a/README.md b/README.md index db143f4..7a5fa46 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,24 @@ # Dotfiles (Niri + Wayland) +A personal Wayland desktop configuration centered around the **Niri** tiling compositor. + +| Area | Tool | +|---|---| +| Compositor | niri | +| Bar | waybar | +| Terminal | alacritty | +| Shell | fish + starship | +| Launcher | wofi | +| Notifications | mako | +| Lockscreen | gtklock | +| Login/greeter | greetd + regreet | +| Wallpaper | swww | +| Screenshots | grim + slurp | +| Clipboard | cliphist | +| Theme | Tomorrow Night (GTK: Materia-dark, icons: Papirus) | + +Everything is symlinked into `~/.config` via `install.sh`, with packages listed in `packages.txt`. + ## Setup ```bash diff --git a/gtklock/config.ini b/gtklock/config.ini new file mode 100644 index 0000000..7ac568d --- /dev/null +++ b/gtklock/config.ini @@ -0,0 +1,4 @@ +[main] +gtk-theme=Materia-dark +style=/home/alex/.config/gtklock/style.css +follow-focus=true diff --git a/gtklock/style.css b/gtklock/style.css new file mode 100644 index 0000000..e772e9d --- /dev/null +++ b/gtklock/style.css @@ -0,0 +1,72 @@ +@import url("../theme/colors.css"); + +/* gtklock style - Tomorrow Night theme */ + +window { + background-color: var(--tn-bg); +} + +#body { + background-color: transparent; +} + +#clock-label { + color: var(--tn-fg); + font-family: "JetBrainsMono Nerd Font"; + font-size: 48px; + font-weight: bold; + margin-bottom: 8px; +} + +#date-label { + color: var(--tn-fg-dim); + font-family: "JetBrainsMono Nerd Font"; + font-size: 16px; + margin-bottom: 24px; +} + +#username-label { + color: var(--tn-fg); + font-family: "JetBrainsMono Nerd Font"; + font-size: 18px; + font-weight: bold; + margin-bottom: 12px; +} + +#input-box { + background-color: var(--tn-bg-alt); + border: 2px solid var(--tn-bg-high); + border-radius: 6px; + color: var(--tn-fg); + font-family: "JetBrainsMono Nerd Font"; + font-size: 14px; + padding: 8px 12px; + min-width: 280px; +} + +#input-box:focus { + border-color: var(--tn-blue); +} + +#error-label { + color: var(--tn-red); + font-family: "JetBrainsMono Nerd Font"; + font-size: 13px; + margin-top: 8px; +} + +#unlock-button { + background-color: var(--tn-bg-high); + border: none; + border-radius: 6px; + color: var(--tn-fg); + font-family: "JetBrainsMono Nerd Font"; + font-size: 14px; + padding: 8px 20px; + margin-top: 12px; +} + +#unlock-button:hover { + background-color: var(--tn-blue); + color: var(--tn-bg); +} diff --git a/install.sh b/install.sh index 071f11d..0c89223 100755 --- a/install.sh +++ b/install.sh @@ -2,11 +2,21 @@ set -e -echo "==> Installing packages" -sudo pacman -S --needed - < packages.txt +echo "==> Detecting AUR helper" +if command -v yay &>/dev/null; then + AUR_HELPER=yay +elif command -v paru &>/dev/null; then + AUR_HELPER=paru +else + echo "ERROR: No AUR helper found. Install yay or paru first." >&2 + exit 1 +fi + +echo "==> Installing packages (using $AUR_HELPER)" +$AUR_HELPER -S --needed - < packages.txt echo "==> Creating config directories" -mkdir -p ~/.config/{niri,waybar,wofi,mako,alacritty,gtk-3.0,gtk-4.0,swaylock,fish} ~/.config/environment.d ~/.config/xdg-desktop-portal +mkdir -p ~/.config/{niri,waybar,wofi,mako,alacritty,gtk-3.0,gtk-4.0,gtklock,fish} ~/.config/environment.d ~/.config/xdg-desktop-portal echo "==> Linking configs" @@ -18,7 +28,8 @@ ln -sf "$(pwd)/waybar/style.css" ~/.config/waybar/style.css ln -sf "$(pwd)/wofi/config" ~/.config/wofi/config ln -sf "$(pwd)/wofi/style.css" ~/.config/wofi/style.css ln -sf "$(pwd)/mako/config" ~/.config/mako/config -ln -sf "$(pwd)/swaylock/config" ~/.config/swaylock/config +ln -sf "$(pwd)/gtklock/config.ini" ~/.config/gtklock/config +ln -sf "$(pwd)/gtklock/style.css" ~/.config/gtklock/style.css ln -sf "$(pwd)/fish/config.fish" ~/.config/fish/config.fish ln -sf "$(pwd)/starship/starship.toml" ~/.config/starship.toml ln -sf "$(pwd)/alacritty/alacritty.toml" ~/.config/alacritty/alacritty.toml diff --git a/niri/config.kdl b/niri/config.kdl index d5d8ef6..45dd4d5 100644 --- a/niri/config.kdl +++ b/niri/config.kdl @@ -36,7 +36,7 @@ spawn-at-startup "mako" spawn-at-startup "swww-daemon" spawn-at-startup "nm-applet" "--indicator" spawn-at-startup "polkit-gnome-authentication-agent-1" -spawn-at-startup "swayidle" "-w" "timeout" "300" "niri msg action power-off-monitors" "timeout" "600" "swaylock" "timeout" "1800" "systemctl suspend" "before-sleep" "swaylock" +spawn-at-startup "swayidle" "-w" "timeout" "300" "niri msg action power-off-monitors" "timeout" "600" "gtklock" "-d" "timeout" "1800" "systemctl suspend" "before-sleep" "gtklock" "-d" spawn-at-startup "wl-paste" "--watch" "cliphist" "store" spawn-at-startup "blueman-applet" spawn-at-startup "wlsunset" "-l" "49.2" "-L" "-123.1" @@ -88,7 +88,7 @@ binds { Mod+M { move-window-to-workspace "minimized"; } Mod+Shift+M { focus-workspace "minimized"; } - Mod+Shift+E { spawn "swaylock"; } + Mod+Shift+E { spawn "gtklock" "-d"; } Mod+Shift+P { spawn "powermenu"; } Mod+Shift+C { spawn "clipboard-picker"; } Mod+Shift+X { quit; } diff --git a/packages.txt b/packages.txt index aef6d95..8923756 100644 --- a/packages.txt +++ b/packages.txt @@ -9,7 +9,7 @@ slurp wl-clipboard brightnessctl pamixer -swaylock +gtklock swayidle ttf-jetbrains-mono-nerd network-manager-applet diff --git a/theme/colors.css b/theme/colors.css new file mode 100644 index 0000000..56cef0c --- /dev/null +++ b/theme/colors.css @@ -0,0 +1,22 @@ +/* Tomorrow Night - shared color palette */ +/* @import this file from waybar, wofi, gtklock CSS */ + +* { + --tn-bg: #1d1f21; + --tn-bg-alt: #282a2e; + --tn-bg-high: #373b41; + --tn-fg: #c5c8c6; + --tn-fg-dim: #969896; + --tn-fg-muted: #707880; + --tn-blue: #81a2be; + --tn-green: #b5bd68; + --tn-yellow: #f0c674; + --tn-red: #cc6666; + --tn-magenta: #b294bb; + --tn-cyan: #8abeb7; + + /* Alpha variants */ + --tn-bg-a90: rgba(29, 31, 33, 0.90); + --tn-bg-a95: rgba(29, 31, 33, 0.95); + --tn-bg-a96: rgba(29, 31, 33, 0.96); +} diff --git a/theme/colors.json b/theme/colors.json new file mode 100644 index 0000000..54acb31 --- /dev/null +++ b/theme/colors.json @@ -0,0 +1,15 @@ +{ + "name": "Tomorrow Night", + "background": "#1d1f21", + "background_alt": "#282a2e", + "background_high": "#373b41", + "foreground": "#c5c8c6", + "foreground_dim": "#969896", + "foreground_muted": "#707880", + "blue": "#81a2be", + "green": "#b5bd68", + "yellow": "#f0c674", + "red": "#cc6666", + "magenta": "#b294bb", + "cyan": "#8abeb7" +} diff --git a/waybar/style.css b/waybar/style.css index 58548c2..c958b91 100644 --- a/waybar/style.css +++ b/waybar/style.css @@ -1,20 +1,22 @@ +@import url("../theme/colors.css"); + * { font-family: JetBrainsMono Nerd Font; font-size: 13px; } window#waybar { - background: rgba(29,31,33,0.9); - color: #c5c8c6; + background: var(--tn-bg-a90); + color: var(--tn-fg); } #workspaces button { padding: 0 8px; - color: #707880; + color: var(--tn-fg-muted); } #workspaces button.focused { - color: #81a2be; + color: var(--tn-blue); } #clock, #battery, #network, #pulseaudio, @@ -24,33 +26,33 @@ window#waybar { } #custom-power-profile.performance { - color: #f0c674; + color: var(--tn-yellow); } #custom-power-profile.power-saver { - color: #b5bd68; + color: var(--tn-green); } #battery.warning { - color: #f0c674; + color: var(--tn-yellow); } #battery.critical { - color: #cc6666; + color: var(--tn-red); } #cpu.warning { - color: #f0c674; + color: var(--tn-yellow); } #cpu.critical { - color: #cc6666; + color: var(--tn-red); } #temperature.warm { - color: #f0c674; + color: var(--tn-yellow); } #temperature.critical { - color: #cc6666; + color: var(--tn-red); } diff --git a/wofi/style.css b/wofi/style.css index 4d1adcd..286aa9c 100644 --- a/wofi/style.css +++ b/wofi/style.css @@ -1,29 +1,31 @@ +@import url("../theme/colors.css"); + * { font-family: JetBrainsMono Nerd Font; font-size: 14px; } window { - background-color: rgba(29, 31, 33, 0.96); - border: 1px solid #373b41; + background-color: var(--tn-bg-a96); + border: 1px solid var(--tn-bg-high); border-radius: 12px; - color: #c5c8c6; + color: var(--tn-fg); } #input { - background-color: #282a2e; - color: #c5c8c6; - border: 1px solid #373b41; + background-color: var(--tn-bg-alt); + color: var(--tn-fg); + border: 1px solid var(--tn-bg-high); border-radius: 8px; padding: 10px 14px; margin: 12px 12px 6px 12px; outline: none; font-size: 15px; - caret-color: #81a2be; + caret-color: var(--tn-blue); } #input:focus { - border-color: #81a2be; + border-color: var(--tn-blue); } #inner-box { @@ -46,17 +48,17 @@ window { } #entry:selected { - background-color: #282a2e; - border: 1px solid #81a2be; + background-color: var(--tn-bg-alt); + border: 1px solid var(--tn-blue); outline: none; } #text { - color: #c5c8c6; + color: var(--tn-fg); } #text:selected { - color: #81a2be; + color: var(--tn-blue); font-weight: bold; }