diff --git a/.claude/skills/kde-config/lessons/window-rules.md b/.claude/skills/kde-config/lessons/window-rules.md index 64a391c..c6abbfc 100644 --- a/.claude/skills/kde-config/lessons/window-rules.md +++ b/.claude/skills/kde-config/lessons/window-rules.md @@ -51,9 +51,28 @@ All from `src/rules.h`: | `sizerule`, `positionrule`, … (`*rule` for set-type properties) | `Rules::SetRule` (anonymous base enum) | 0 Unused, 1 DontAffect, 2 Force, 3 Apply ("Apply initially"), 4 Remember, 5 ApplyNow, 6 ForceTemporarily | | `types` | `NET::WindowTypeMask` bitmask (`/usr/include/KF6/KWindowSystem/netwm_def.h`) | 1 Normal, default `AllTypesMask` (all bits) | | `wmclasscomplete` | Bool | `true` = match whole window class | +| `fullscreen`, `maximizevert`, `maximizehoriz` | Bool (`src/rulesettings.kcfg`) | `true` + a `*rule` companion (`fullscreenrule`, `maximizevertrule`, `maximizehorizrule`) | `size` is a `QSize` serialised as `width,height`. +## Initial-state order for a new window + +`XdgToplevelWindow::initialize()` (`src/xdgshellwindow.cpp`) applies the +`Apply` rules in a fixed order: position and size first, then maximize, +then fullscreen, then activities, desktops, and the rest. A fullscreen +rule therefore wins over a size rule at mapping time; the size only +matters again if the window later leaves fullscreen. Fullscreen and +maximized are distinct properties: fullscreen hides the panel and the +title bar, maximized keeps both. + +## Dropping a property + +`ini_file` only writes the keys it is given, so a property dropped from +`kde_window_rules` stays in `kwinrulesrc` on a machine that already had +it. That is by design: provisioning is never backward compatible +(`CLAUDE.md` rule 8), so no cleanup task exists. Delete the stale key by +hand or reprovision a fresh machine. + ## "Detect Window Properties" leaves inert keys behind The KCM's property detector copies the window's title into `title=` even diff --git a/CLAUDE.md b/CLAUDE.md index 7e25e50..c1803a4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -11,6 +11,8 @@ CachyOS system provisioner powered by Ansible. 5. Don't install packages already in the CachyOS base image. Verify against `cachyos/cachyos:latest` (`pacman -Qe`) before adding to a role's package list. 6. Variables defined inside a role use the role name as prefix (ansible-lint `var-naming[no-role-prefix]` rule). E.g., inside `roles/tools` use `tools_uv_tool_list`, not `uv_tool_list`. Variables shared by multiple roles are defined at play scope in `playbook.yml`, never in one role. 7. AUR packages are never managed by Ansible: the set lives in `bin/hanzo-aur` and installs through Shelly, with human review of every package. AUR installation precedes the playbook, so roles may configure AUR packages but never install them. +8. Never be backward compatible. Provisioning targets a fresh, clean machine, so a change replaces what it supersedes outright: no migration or cleanup tasks for state an earlier version wrote, and no compatibility shims for existing installs. +9. When a PR that changes provisioned state is merged, ask the user whether to apply the change to the current machine by hand. `hanzo` never runs on the host (see Security: Prohibited Commands), so the agent reproduces the change's end state directly: the file written, the service restarted, the setting applied. Before touching anything, describe the plan step by step, wait for the user's confirmation, and execute only what was confirmed. ## Commands diff --git a/roles/kde/defaults/main.yml b/roles/kde/defaults/main.yml index 1b566ae..f786c5b 100644 --- a/roles/kde/defaults/main.yml +++ b/roles/kde/defaults/main.yml @@ -55,8 +55,8 @@ kde_window_rules: wmclasscomplete: "true" wmclassmatch: 1 types: 1 - size: 1600,1001 - sizerule: 3 + fullscreen: "true" + fullscreenrule: 3 # Session restore at login. One of restorePreviousLogout, # restoreSavedSession, emptySession — the ksmserver loginMode names.