sync up, add qshell functinality, memo mockup

This commit is contained in:
David Aizenberg
2026-02-15 00:54:03 +01:00
parent 9d239329c0
commit 8a1cc1cd2f
4 changed files with 1604 additions and 99 deletions

115
AGENTS.md
View File

@@ -1,93 +1,66 @@
# AGENTS Guide: Dotfiles Repository # AGENTS Guide: Dotfiles Repository
Chezmoi-managed dotfiles with device-adaptive templates. Source files in `~/dotfiles/`, deployed to `~/` via `chezmoi apply`. Chezmoi-managed dotfiles. Source in `~/dotfiles/`, deployed via `chezmoi apply`.
## Device Profiles ## Device Profiles
| Profile | Hostname | Primary Monitor | Has Touchpad | Has Battery | | Profile | Hostname | Primary Monitor | Touchpad | Battery |
|---------|----------|-----------------|--------------|-------------| |---------|----------|-----------------|----------|---------|
| desktop | box | DP-2 | No | No | | desktop | box | DP-2 | No | No |
| laptop | bluefin | eDP-1 | Yes | Yes | | laptop | bluefin | eDP-1 | Yes | Yes |
## Template Variables ## Template Variables
```go `{{ .deviceProfile }}` (desktop/laptop), `{{ .hostname }}`, `{{ .primaryMonitor }}`, `{{ .hasTouchpad }}`, `{{ .hasBattery }}`, `{{ .idleTimeout }}` (300/180), `{{ .secretsPath }}` (~/secrets)
{{ .deviceProfile }} // "desktop" or "laptop"
{{ .hostname }} // "box" or "bluefin"
{{ .primaryMonitor }} // "DP-2" or "eDP-1"
{{ .hasTouchpad }} // boolean
{{ .hasBattery }} // boolean
{{ .idleTimeout }} // 300 (desktop) or 180 (laptop)
{{ .secretsPath }} // "~/secrets"
```
## File Naming Conventions ## File Naming
| Pattern | Effect | - `private_dot_*` — hidden, 700 perms
|---------|--------| - `dot_*` — hidden, 755 perms
| `private_dot_*` | Hidden file with 700 permissions | - `executable_*` — 755
| `dot_*` | Hidden file with 755 permissions | - `*.tmpl` — Go template
| `executable_*` | Executable (755) |
| `*.tmpl` | Processed as Go template |
## Directory Structure ## Structure
``` ```
home/ home/
├── private_dot_config/ # ~/.config/ ├── private_dot_config/ # hypr/, fish/, waybar/, ghostty/, quickshell/
│ ├── hypr/ # Hyprland configs ├── dot_local/bin/ # scripts
│ ├── fish/ # Shell └── .chezmoiscripts/ # one-time setup
│ ├── waybar/ # Status bar
│ └── ghostty/ # Terminal
├── dot_local/bin/ # ~/.local/bin/ scripts
└── .chezmoiscripts/ # One-time setup scripts
``` ```
## Hyprland Config Files ## Hyprland (`home/private_dot_config/hypr/`)
All in `home/private_dot_config/hypr/`: `hyprland.conf.tmpl` (main/keybinds/rules), `monitors.conf.tmpl`, `autostart.conf.tmpl`, `colors.conf`, `workspaces.conf`, `hyprpaper.conf.tmpl`, `hypridle.conf.tmpl`, `hyprlock.conf`
| File | Purpose |
|------|---------|
| `hyprland.conf.tmpl` | Main config, keybindings, window rules |
| `monitors.conf.tmpl` | Monitor setup |
| `autostart.conf.tmpl` | Startup applications |
| `colors.conf` | Color palette |
| `workspaces.conf` | Workspace definitions |
| `hyprpaper.conf.tmpl` | Wallpaper |
| `hypridle.conf.tmpl` | Idle/power management |
| `hyprlock.conf` | Lock screen |
## Template Conditionals
```go
{{- if eq .deviceProfile "desktop" }}
# Desktop only
{{- else if eq .deviceProfile "laptop" }}
# Laptop only
{{- end }}
{{- if .hasBattery }}
# Battery-dependent (laptop brightness keys, etc.)
{{- end }}
{{- if .hasTouchpad }}
# Touchpad settings
{{- end }}
```
## Key Commands
```bash
chezmoi apply # Deploy changes
chezmoi diff # Preview changes
chezmoi edit <file> # Edit managed file
chezmoi add <file> # Add new file to management
```
## Standards ## Standards
- Scripts: `#!/usr/bin/env bash` with `set -euo pipefail` - Scripts: `#!/usr/bin/env bash` + `set -euo pipefail`
- Secrets: Store in `~/secrets/`, reference via `{{ .secretsPath }}` - Secrets via `{{ .secretsPath }}`
- Window rules: Use `windowrulev2` (not deprecated `windowrule`) - Use `windowrulev2` (not `windowrule`)
- Whitespace: Use `{{-` to trim in templates - Use `{{-` to trim whitespace in templates
## QuickShell (`home/private_dot_config/quickshell/shell.qml.tmpl`)
Single-file bottom bar + popups. VPN scripts in `dot_local/bin/executable_vpn-{status,switcher,helper}`.
### Design Language
- **Theme**: dark, minimal, no rounded corners (`radius: 0` on modules)
- **Colors**: bg `#0f0f0f`, module bg `#1a1a1a`, fg `#e0e0e0`, dim `#888888`, accent `#e67e22`, ok `#2ecc71`, warn `#f1c40f`, crit `#e74c3c`, border `#333333`
- **Font**: `"Terminus, IBM Plex Mono, JetBrainsMono Nerd Font, monospace"` at 12px (11px for section headers)
- **Text-only indicators** — no icons. Prefixed labels: `VOL 85%`, `MIC muted`, `NET eth 10.0.0.5`, `CPU 12%`, `MEM 34%`, `BAT 72%`, `BRT 50%`, `TIME 2025-01-15 14:30`
- **Bar**: bottom-anchored, 34px total height, 4px outer margin, 6px inner row padding
- **Modules**: `ModuleBox` component — `#1a1a1a` bg, 1px border, 22px height, content padded 12px wide
- **Layout**: left group (workspaces) + flexible spacer + right group (vpn, vol, mic, net, [bat, brt on laptop], cpu, mem, clock, tray), 6px spacing between modules
- **Popups**: item rows 24px, hover `#2a2a2a`, `●` active / `○` inactive, section headers `━━ Title ━━` in dim color
### QuickShell Patterns
- **Popups**: fullscreen transparent overlay `PanelWindow` (all anchors true, `ExclusionMode.Ignore`), NOT a second positioned PanelWindow. Three mouse layers: background dismiss, absorb on popup rect, content Column `z: 1`
- **Cross-window positioning**: `mapToItem(null, 0, 0)` only maps within own window. Compute popup X from layout math against `rightGroup.implicitWidth`
- **Process sync**: pending counter, decrement in each `onStreamFinished`, combine at 0
- **Bash safety**: `command -v foo &>/dev/null && foo || echo '{}'`. Use `---TAG---` separators for JS parsing
- **QML reactivity**: assign NEW object (`Object.assign({}, old, changes)`) to trigger bindings
- **Keyboard input in popups**: set `focusable: true` on the PanelWindow
- **PulseAudio**: `pactl list sinks` (not `short`) for descriptions; filter sources with `grep -v '\.monitor'`

View File

@@ -222,9 +222,9 @@ bind = SUPER, F12, exec, ~/.local/bin/workspace-pin 1337
bind = SUPER, A, togglespecialworkspace, org bind = SUPER, A, togglespecialworkspace, org
bind = SUPER SHIFT, A, movetoworkspace, special:org bind = SUPER SHIFT, A, movetoworkspace, special:org
# Quick Memo (jax-bot integration) # Quick Memo (QuickShell)
bind = , F12, exec, ~/.local/bin/quick-memo --input bind = , F12, exec, touch /tmp/qs-memo-input
bind = SHIFT, F12, exec, ~/.local/bin/quick-memo --clipboard bind = SHIFT, F12, exec, touch /tmp/qs-memo-clip
bind = SUPER, X, workspace, name:media bind = SUPER, X, workspace, name:media
bind = SUPER SHIFT, X, movetoworkspace, name:media bind = SUPER SHIFT, X, movetoworkspace, name:media
bind = SUPER SHIFT, C, movetoworkspace, name:tg bind = SUPER SHIFT, C, movetoworkspace, name:tg
@@ -304,8 +304,8 @@ windowrule = match:class ^$, match:title ^$, match:xwayland true, match:float tr
plugin { plugin {
hyprexpo { hyprexpo {
columns = 3 columns = 4
gap_size = 5 gap_size = 0
bg_col = rgb(0f0f0f) bg_col = rgb(0f0f0f)
workspace_method = first 1 workspace_method = first 1
{{- if .hasTouchpad }} {{- if .hasTouchpad }}

View File

@@ -9,6 +9,11 @@ workspace = 7, name:DOC
workspace = 8, name:GAME workspace = 8, name:GAME
workspace = 9, name:MISC workspace = 9, name:MISC
workspace = 10, name:TMP workspace = 10, name:TMP
workspace = 11, name:AUX1
workspace = 12, name:AUX2
workspace = 13, name:AUX3
workspace = 14, name:AUX4
workspace = 15, name:AUX5
# Smart gaps rules # Smart gaps rules
workspace = w[tv1], gapsout:0, gapsin:0 workspace = w[tv1], gapsout:0, gapsin:0

File diff suppressed because it is too large Load Diff