# Phase 2 — Become a Window Manager --- ## Step 2.1 — Open an Xlib display connection alongside raylib Before `InitWindow()`, call `XOpenDisplay(NULL)` to get a `Display*`. Store it globally. Get the root window with `DefaultRootWindow()`. After the raylib loop exits, `XCloseDisplay()`. Print the display name and root window ID to confirm. **Verify:** The output prints something like `Display: :1, Root: 0x...`. Raylib window still works as before. --- ## Step 2.2 — Register as the window manager (SubstructureRedirect) After opening the display, call: ```c XSelectInput(dpy, root, SubstructureRedirectMask | SubstructureNotifyMask | StructureNotifyMask); XSync(dpy, False); ``` Set a custom X error handler that catches `BadAccess` (another WM is already running) and prints a clear message. **Verify:** Running in Xephyr succeeds (no other WM). Running a second instance prints "Another window manager is already running" and exits. --- ## Step 2.3 — Process X events in the raylib loop Inside the raylib `while (!WindowShouldClose())` loop, add a non-blocking X event drain: ```c while (XPending(dpy) > 0) { XEvent ev; XNextEvent(dpy, &ev); printf("Event: %d\n", ev.type); } ``` **Verify:** `./bin/run.sh --clients` — launching `xeyes` or `xterm` into `:1` prints `MapRequest`, `ConfigureRequest`, etc. to the terminal. The clients don't appear yet (because we don't handle `MapRequest`). --- ## Step 2.4 — Handle MapRequest and ConfigureRequest (basic) Add a simple event handler: - **`MapRequest`** → call `XMapWindow(dpy, ev.xmaprequest.window)`. - **`ConfigureRequest`** → honor the request by calling `XConfigureWindow()` with the requested values. **Verify:** `./bin/run.sh --clients` — `xeyes`, `xclock`, and `xterm` now appear inside the Xephyr window. They're drawn by X directly (not composited yet), floating on top of/beside the raylib window. You can type in `xterm`. --- ## Step 2.5 — Track managed windows in a list Create a simple dynamic array (or linked list) of `WmWindow` structs: ```c typedef struct { Window xwin; int x, y; unsigned int width, height; bool mapped; } WmWindow; ``` - On `MapRequest`: add the window to the list, then `XMapWindow`. - On `UnmapNotify`: mark `mapped = false`. - On `DestroyNotify`: remove from the list. - On `ConfigureRequest`: update stored geometry, then `XConfigureWindow`. Print the window list count on each change. **Verify:** Spawn/close clients in `:1`. The log shows windows being added and removed. Count matches what's visible.