docs(wm): Phase 4 progress, Hyprland config reference, and keybindings

Add Phase 4 progress entry documenting windowrule syntax fix for
Hyprland 0.51 (stripping invalid ^(...)$ wrapping). Include CLAUDE.md
project instructions, version-aware Hyprland config reference docs,
and keybindings cheatsheet PDF for future reference.
This commit is contained in:
jared 2026-05-07 09:43:43 -04:00
parent 6d2638a3f4
commit e875f0ee97
7 changed files with 280 additions and 0 deletions

46
CLAUDE.md Normal file
View File

@ -0,0 +1,46 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## What this repo is
Documentation and planning for a GNOME → Hyprland migration on Fedora 43. No build system, no tests, no executables. The actual system configuration lives in `~/.dotfiles/` (separate Forgejo repo), managed with GNU Stow.
## Key locations outside this repo
| What | Where |
|------|-------|
| Hyprland config | `~/.dotfiles/hypr/.config/hypr/hyprland.conf` |
| DMS source configs | `~/.dotfiles/hypr/.config/hypr/dms/` |
| Symlink target | `~/.config/hypr/` → symlinked via `stow hypr` |
| Hyprland log | `~/.cache/hyprland/hyprland.log` |
| Dotfiles remote | `git@forgejo.swansoncloud.com:jared/dotfiles.git` |
## Hyprland configuration
**Installed version:** 0.51.1 (Fedora 43). See `docs/hyprland/version-history.md` before applying patterns from the official wiki — the wiki tracks git HEAD, which is ahead of the installed version.
**Window rule syntax for 0.480.51** (not the block syntax shown in current wiki):
```
windowrule = match:class classname, effect
windowrule = match:class classname, match:title titlepattern, effect1, effect2
```
Do NOT use `^(...)$` wrapping — Hyprland 0.51 rejects it as "Invalid rulev2". Use plain names or bare regexes (e.g. `^org\.gnome\.` for a prefix match).
**Block syntax** (`windowrule { }`) is 0.52+ only — do not use until after a Fedora upgrade.
## Docs structure
- `docs/window-manager/` — migration plan, phased progress log, keybindings cheatsheet
- `docs/hyprland/` — version-aware Hyprland config reference; update these when Hyprland is upgraded
## Project status
Phases 03 complete (install, config, dotfiles integration). Phase 4 (first successful Hyprland login and smoke tests) is in progress. Phase 5 (tuning) is deferred.
Known workaround in place: `hyprpolkitagent` replaced with `lxpolkit` due to Qt 6 ABI issue on Fedora 43.
## Hardware
- AMD Vega iGPU (primary display, Wayland)
- NVIDIA RTX 3060 dGPU (unused — `akmod-nvidia` intentionally not installed)

24
docs/hyprland/README.md Normal file
View File

@ -0,0 +1,24 @@
# Hyprland Reference
Quick-access docs for AI-assisted config work. Covers the version installed on this machine.
Update this index when upgrading Hyprland.
**Installed version:** 0.51.1 (Fedora 43, Sept 2025)
**Next expected upgrade path:** Fedora 44 → likely Hyprland 0.54+
## Index
| File | What it covers |
|------|---------------|
| [window-rules.md](window-rules.md) | windowrule syntax, effects, props — with version notes |
| [layer-rules.md](layer-rules.md) | layerrule syntax for bars, wallpapers, launchers |
| [version-history.md](version-history.md) | Breaking syntax changes across versions |
## Official sources (always check version)
- Wiki: https://wiki.hypr.land/Configuring/
- Example conf (HEAD/latest): https://github.com/hyprwm/Hyprland/blob/main/example/hyprland.conf
- Window Rules wiki: https://wiki.hypr.land/Configuring/Window-Rules/
> **Warning:** The wiki and example conf track the latest git HEAD, not the installed version.
> Always cross-reference with [version-history.md](version-history.md) before applying patterns from the wiki.

View File

@ -0,0 +1,37 @@
# Layer Rules — Hyprland 0.480.51
Layers are non-window surfaces: status bars, wallpapers, launchers, notifications.
## Syntax (current: 0.480.51)
```
layerrule = match:namespace ^(regex)$, effect
```
Use `hyprctl layers` to find a layer's namespace.
## Effects
| Effect | Notes |
|--------|-------|
| `no_anim` | Disable animations |
| `blur` | Enable blur |
| `blur_popups` | Blur popups too |
| `dim_around` | Dim everything behind layer |
| `animation style` | Override animation style |
## Our rules
```
layerrule = match:namespace ^(quickshell)$, no_anim
layerrule = match:namespace ^dms:.*, no_anim
```
## 0.52+ block syntax (not yet installed)
```
layerrule {
match:namespace = ^(quickshell)$
no_anim = on
}
```

View File

@ -0,0 +1,78 @@
# Hyprland Version History — Breaking Config Changes
Focus: syntax changes that affect our config. Not a full changelog.
## Installed: 0.51.1 (Sept 2025)
## windowrule syntax timeline
### Pre-0.48 (old — do not use)
```
windowrule = float, ^(class-regex)$ # v1: positional class, no prefix
windowrulev2 = float, class:^(regex)$ # v2: explicit class: prefix
```
### 0.480.51 (CURRENT — use this)
Both `windowrule` and `windowrulev2` keywords work, but `windowrulev2` is deprecated.
Use `windowrule` with `match:` prefixed props. Patterns are plain strings or bare regexes —
do NOT use the old rulev2 `^(...)$` wrapping; Hyprland 0.51 rejects it as "Invalid rulev2".
```
windowrule = match:class classname, effect
windowrule = match:class classname, match:title titlepattern, effect1, effect2
windowrule = match:class ^org\.gnome\., rounding 12 # prefix regex — anchor ok, no outer ()
```
Props can come in any order relative to effects.
Boolean effects: `float`, `tile`, `pin`, `no_initial_focus` (no "on" suffix needed)
Value effects: `rounding 12`, `opacity 0.9`
### 0.52+ (not yet installed — do not use until upgrade)
Block syntax introduced:
```
windowrule {
name = optional-name
match:class = ^(regex)$
float = yes
rounding = 12
}
```
Anonymous flat block syntax also available:
```
windowrule = match:class regex, effect value
```
## layerrule syntax timeline
### Pre-0.48 (old)
```
layerrule = no_anim, ^(namespace)$ # positional namespace
```
### 0.480.51 (CURRENT — use this)
```
layerrule = match:namespace namespacename, no_anim
```
Same rule as windowrule: plain string or bare regex, no `^(...)$` wrapping.
### 0.52+ (block syntax)
```
layerrule {
match:namespace = ^(regex)$
no_anim = on
}
```
## Other notable changes
| Version | Change |
|---------|--------|
| 0.48 | `windowrulev2` deprecated; new `windowrule` with `match:` prefix |
| 0.48 | `layerrule` updated to use `match:namespace` prefix |
| 0.52+ | Block syntax for `windowrule` and `layerrule` |
## Upgrade checklist
When upgrading Hyprland:
1. Check `hyprland --version` (or `rpm -q hyprland`)
2. Scan release notes for "windowrule", "layerrule", "deprecated"
3. Update this file
4. Update the comment in `hyprland.conf` window rules section

View File

@ -0,0 +1,87 @@
# Window Rules — Hyprland 0.480.51
Reference for the syntax currently used on this machine.
See [version-history.md](version-history.md) for what changes on upgrade.
## Syntax (current: 0.480.51)
```
windowrule = match:class classname, effect
windowrule = match:class classname, match:title titlepattern, effect1, effect2
```
Patterns are plain names or bare regexes. **Do NOT use `^(...)$` wrapping** — Hyprland 0.51
rejects it as "Invalid rulev2" (that was the old windowrulev2 class-matching format).
Anchors are fine without outer grouping: `^org\.gnome\.` matches any GNOME reverse-DNS class.
Multiple props and effects can be on one line, comma-separated, any order.
## Match props (filtering)
| Prop | Example | Notes |
|------|---------|-------|
| `match:class` | `match:class firefox` | Window class (app ID) |
| `match:title` | `match:title Picture-in-Picture` | Window title |
| `match:xwayland` | `match:xwayland true` | XWayland windows only |
| `match:float` | `match:float true` | Currently floating |
| `match:fullscreen` | `match:fullscreen true` | Currently fullscreen |
Use `hyprctl clients` to find a window's class and title.
## Static effects (applied once at window open)
| Effect | Example | Notes |
|--------|---------|-------|
| `float` | `float` | Force float |
| `tile` | `tile` | Force tile |
| `fullscreen` | `fullscreen` | Force fullscreen |
| `maximize` | `maximize` | Force maximize |
| `rounding` | `rounding 12` | Pixel rounding (overrides global) |
| `no_initial_focus` | `no_initial_focus` | Don't steal focus on open |
| `pin` | `pin` | Show on all workspaces (float only) |
| `move` | `move 100 200` | Position (float only) |
| `size` | `size 800 600` | Size (float only) |
| `workspace` | `workspace 2` | Open on specific workspace |
| `monitor` | `monitor 1` | Open on specific monitor |
| `suppress_event` | `suppress_event maximize` | Ignore window events |
## Dynamic effects (re-evaluated on change)
| Effect | Example |
|--------|---------|
| `opacity` | `opacity 0.9` or `opacity 0.9 0.7` (active inactive) |
| `border_color` | `border_color rgb(FF0000)` |
| `no_blur` | `no_blur` |
| `no_shadow` | `no_shadow` |
| `no_anim` | `no_anim` |
| `no_focus` | `no_focus` |
| `idle_inhibit` | `idle_inhibit always` |
## Our rules (reference)
```
# Force-tile apps that default to floating
windowrule = match:class gnome-control-center, tile
windowrule = match:class pavucontrol, tile
# Force-float small utilities
windowrule = match:class gnome-calculator, float
windowrule = match:class org\.gnome\.Nautilus, float
# Rounded corners for all GNOME apps (prefix match)
windowrule = match:class ^org\.gnome\., rounding 12
# Multi-prop (steam toasts)
windowrule = match:class steam, match:title notificationtoasts, no_initial_focus, pin
# Firefox PiP
windowrule = match:class firefox, match:title Picture-in-Picture, float
```
## Finding window class/title
```bash
hyprctl clients | grep -E "class:|title:"
# or run this in a terminal, then open the window:
hyprctl -j clients | jq '.[] | {class, title}'
```

Binary file not shown.

View File

@ -81,3 +81,11 @@ GNOME and Sway stay installed as GDM fallback sessions.
- Created ~/.config/hypr/hyprpaper.conf; hyprpaper added to autostart; ~/Pictures/wallpapers/ created (drop default.jpg there before first login) - Created ~/.config/hypr/hyprpaper.conf; hyprpaper added to autostart; ~/Pictures/wallpapers/ created (drop default.jpg there before first login)
- Moved hypr config into ~/.dotfiles/hypr stow package; symlink verified; committed 60f57df to dotfiles repo - Moved hypr config into ~/.dotfiles/hypr stow package; symlink verified; committed 60f57df to dotfiles repo
- DMS config will be added to stow after confirming dms setup output is stable (per plan note) - DMS config will be added to stow after confirming dms setup output is stable (per plan note)
## 2026-04-19 — Phase 4: windowrule syntax fix
- On first Hyprland login: config errors on all windowrule lines — "Invalid rulev2 found: match:class ^(...)$"
- Root cause: `^(...)$` wrapping was the old windowrulev2 regex format; Hyprland 0.51 explicitly rejects it even with the new `windowrule` keyword. Correct 0.51 syntax uses plain names or bare regexes with no outer grouping parens.
- Fixed all windowrule and layerrule patterns in hyprland.conf (stripped `^(...)$`; kept `^org\.gnome\.` prefix anchor without outer group).
- Updated docs: CLAUDE.md, docs/hyprland/version-history.md, docs/hyprland/window-rules.md all corrected to show actual 0.51 syntax.
- Noted: solopasha COPR still at 0.51.1 for Fedora 43; upstream latest is 0.54.0. Upgrade deferred until COPR catches up.