summaryrefslogtreecommitdiffhomepage
path: root/.rules/plan/phase-05-lifecycle.md
blob: 89f6a4563b3c7a5ec1c1dbff78b51d79370d4727 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# Phase 5 — Window Lifecycle Polish

---

## Step 5.1 — Graceful close (WM_DELETE_WINDOW)

When the user presses a keybind (e.g., `Mod4+Q`), check if the focused
window supports `WM_DELETE_WINDOW` in its `WM_PROTOCOLS` property. If yes,
send a `ClientMessage`. If no, call `XKillClient()`.

Register the keybind with `XGrabKey()`.

**Verify:** `Mod4+Q` closes `xterm` gracefully (it gets a chance to
confirm). Force-kills uncooperative clients.

---

## Step 5.2 — Handle UnmapNotify and DestroyNotify properly

On `UnmapNotify`:
- Free the pixmap and texture.
- Mark window as unmapped.
- Destroy the damage object.

On `DestroyNotify`:
- Remove the window from the managed list entirely.
- Clean up all resources.

Handle re-mapping (a window that was unmapped then mapped again) by
re-creating everything.

**Verify:** Close and reopen clients repeatedly. No memory leaks (watch
with `valgrind` or check texture count). No X errors. No stale windows
in the compositor view.

---

## Step 5.3 — Manage pre-existing windows on startup

After becoming the WM, call `XQueryTree()` to get all existing children
of root. For each that has `map_state == IsViewable`, treat it as if we
received a `MapRequest`: add to the list, set up pixmap, damage, texture.

**Verify:** Start some clients in `:1` *before* the WM. Then start the
WM. Pre-existing windows appear immediately in the composited view.