Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .claude/skills/kde-config/lessons/window-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

## Retiring a property

`ini_file` only writes the keys it is given, so dropping a property from
`kde_window_rules` leaves the old key on every machine that already had
it. Set the property to `null` instead: the rule task then removes the
key (`state: absent`), with real change detection under `--check`. Keep
the null entry until every machine has converged, then delete it.

## "Detect Window Properties" leaves inert keys behind

The KCM's property detector copies the window's title into `title=` even
Expand Down
9 changes: 6 additions & 3 deletions roles/kde/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,19 @@ kde_panel_layout_file: "{{ ansible_facts.env.HOME }}/.local/share/hanzo/panel-la
# enums: *match is Rules::StringMatch (1 = exact), *rule is
# Rules::SetRule (3 = apply initially), types is a NET::WindowTypeMask
# bitmask (1 = normal window). Booleans are quoted: KConfig reads
# lowercase true|false.
# lowercase true|false. A null value removes the key from the group:
# that is how a property Hanzo once wrote is retired on every machine.
kde_window_rules:
hanzo-ghostty:
Description: Window settings for com.mitchellh.ghostty
wmclass: ghostty com.mitchellh.ghostty
wmclasscomplete: "true"
wmclassmatch: 1
types: 1
size: 1600,1001
sizerule: 3
fullscreen: "true"
fullscreenrule: 3
size: ~
Comment thread
palazzem marked this conversation as resolved.
Outdated
sizerule: ~

# Session restore at login. One of restorePreviousLogout,
# restoreSavedSession, emptySession — the ksmserver loginMode names.
Expand Down
4 changes: 3 additions & 1 deletion roles/kde/tasks/window-rule.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
---
# One kwinrulesrc group per rule. kde_window_rule is the {key: group,
# value: properties} item supplied by the including loop.
# value: properties} item supplied by the including loop. A property
# with a null value is removed from the group instead of written.

- name: Write window rule {{ kde_window_rule.key }}
community.general.ini_file:
path: "{{ ansible_facts.env.HOME }}/.config/kwinrulesrc"
section: "{{ kde_window_rule.key }}"
option: "{{ item.key }}"
value: "{{ item.value }}"
state: "{{ 'absent' if item.value is none else 'present' }}"
no_extra_spaces: true
mode: "0644"
loop: "{{ kde_window_rule.value | dict2items }}"
Expand Down