diff --git a/ACTION_PLAN.md b/ACTION_PLAN.md index 11cc944..f5cbdbd 100644 --- a/ACTION_PLAN.md +++ b/ACTION_PLAN.md @@ -41,6 +41,36 @@ All 8 signature change tasks completed (changes since commit 9943c05): --- +## Wave 2 Complete (2026-05-18) + +All 4 mechanical elimination tasks completed (changes since commit 0950b22): + +| Task | Description | Status | +|------|-------------|--------| +| A4.1 | `workspace.c`: remove 5 `USE_XINERAMA` guards | ✅ | +| B.1 | `appicon.c`: `XClearArea` → `wm_backend->window_clear` | ✅ | +| R.5 | `usermenu.c`: `XStringToKeysym` → `xkb_keysym_from_name`, `XSendEvent` → `dpy` guard | ✅ | +| R.7 | `window.c`: remove 4 `USE_XSHAPE` guards | ✅ | + +**Results:** +- `_x11_raw` sites in `src/`: 9 → 9 (no new _x11_raw; these tasks eliminated X11 calls, not _x11_raw) +- Build verified clean (no new warnings, no regressions) +- C.1 skipped: XOR rubber-band drawing in `moveres.c` is inside `#if 0` — dead code, no action needed + +--- + +## Bug Fixes + +### Native XDG client rendering fix (commit 8d963e7) + +**Problem:** Native XDG clients (e.g. foot terminal, gedit) would render once on initial map but never re-render on buffer commits. The compositor received `wl_surface.commit` events but did not schedule output frame refreshes. + +**Root cause:** `surface_commit_listener` in `wl_backend.c` was registered but did not call `wlr_output_schedule_frame()`. Without this call, the compositor never redrew the output after the initial frame. + +**Fix:** The `surface_commit_listener` callback now calls `wlr_output_schedule_frame()` on every buffer commit, ensuring the compositor redraws the output and picks up the new buffer content. + +--- + ## Phase F: wrlib Wayland Integration *Do this first — other phases depend on wrlib working without X11.* @@ -109,7 +139,7 @@ Key architecture point: wrlib's `convert_image` function pointer (`context->conv ### A4: Workspace Switching -#### A4.1 Eliminate `USE_XINERAMA` guards in `workspace.c` +#### A4.1 ~~Eliminate `USE_XINERAMA` guards in `workspace.c`~~ ✅ - **File**: `src/workspace.c` — 5 `#ifdef USE_XINERAMA` sites (lines 252, 280, 295, 303, 328) - **Operation**: Each guard selects between per-monitor and whole-screen geometry for workspace name display. The monitor geometry should come from `WScreen` fields (already populated by the backend), not from Xinerama calls. For each site: 1. Read the `#ifdef USE_XINERAMA` block and the `#else` block @@ -143,7 +173,7 @@ Key architecture point: wrlib's `convert_image` function pointer (`context->conv ## Phase B: Dock & App Icons -### B.1 Eliminate `XClearArea` in `appicon.c` +### B.1 ~~Eliminate `XClearArea` in `appicon.c`~~ ✅ - **File**: `src/appicon.c:371` - **Operation**: Replace `XClearArea(dpy, dicon->icon->core->window, 2, 2, 50, ...)` with `wm_backend->window_clear_area(dicon->icon->core->window, 2, 2, 50, ...)` or `wm_backend->frame_paint(...)` to trigger a repaint. Check if a `window_clear_area` vtable slot exists; if not, use `frame_paint` on the icon's frame. - **Xlib calls eliminated**: 1 @@ -168,7 +198,7 @@ Key architecture point: wrlib's `convert_image` function pointer (`context->conv ## Phase C: Visual Polish & Animations -### C.1 Eliminate XOR rubber-band drawing in `moveres.c` +### C.1 ~~Eliminate XOR rubber-band drawing in `moveres.c`~~ ⏭️ (inside `#if 0` — dead code, skip) - **File**: `src/moveres.c` — 6 Xlib calls (lines 145-151) - **Operation**: Replace `XSetForeground` + `XDrawLine` calls with `wm_backend->overlay_draw_line()` vtable calls (slot exists at `backend.h:797`): ```c @@ -443,7 +473,7 @@ Key architecture point: wrlib's `convert_image` function pointer (`context->conv - **Operation**: Replace with `wm_backend->keysym_to_keycode()` (vtable slot exists) and `wm_backend->key_lookup_string()` (may need new slot). - **Blocked by**: nothing -### R.5 Eliminate X11 in `usermenu.c` +### R.5 ~~Eliminate X11 in `usermenu.c`~~ ✅ - **File**: `src/usermenu.c` — 4 Xlib calls (`XSendEvent`, `XStringToKeysym`) - **Operation**: Replace `XSendEvent` with `wm_backend->client_send_key_event()` or equivalent vtable slot. Replace `XStringToKeysym` with `xkb_keysym_from_name()` (libxkbcommon, already linked). - **Blocked by**: nothing @@ -453,7 +483,7 @@ Key architecture point: wrlib's `convert_image` function pointer (`context->conv - **Operation**: This file detects keyboard modifier mappings. On Wayland, modifiers come from `xkb_keymap`. The X11 path should remain for X11 backend. Guard the entire file with `if (dpy)` or move to `backend/x11/`. - **Blocked by**: nothing -### R.7 Eliminate `USE_XSHAPE` guards in `window.c` +### R.7 ~~Eliminate `USE_XSHAPE` guards in `window.c`~~ ✅ - **File**: `src/window.c` — 4 `#ifdef USE_XSHAPE` sites - **Operation**: Shape extension queries should be behind the backend. Move `XShapeQueryExtents` calls into `wm_backend->window_get_shape()` or similar vtable slot. The X11 backend implements it; the Wayland backend returns "no shape" (Wayland surfaces handle their own shape via alpha). - **Blocked by**: nothing @@ -486,12 +516,12 @@ IMMEDIATE (unblocks everything else): ~~F.5 Wayland-safe XPM loading~~ ✅ WAVE 1 (independent, no prerequisites): - A4.1 workspace.c USE_XINERAMA → backend-neutral + ~~A4.1 workspace.c USE_XINERAMA → backend-neutral~~ ✅ A5.1 ~~switchpanel.c XEvent* → WMEvent*~~ ✅ - B.1 appicon.c XClearArea → vtable + ~~B.1 appicon.c XClearArea → vtable~~ ✅ B.2 appicon.c USE_DOCK_XDND → backend B.3 ~~dock.c/h XEvent* → WMEvent*~~ ✅ - C.1 moveres.c XDrawLine → overlay vtable + ~~C.1 moveres.c XDrawLine → overlay vtable~~ ⏭️ (inside `#if 0` — dead code, skip) D.1 widgets.c screen init → backend guard D.3 winputmethod.c → _x11/_wl split D.5 selection.c → _x11/_wl split @@ -505,9 +535,9 @@ WAVE 1 (independent, no prerequisites): R.2 ~~icon.c _x11_raw → WMEvent~~ ✅ R.3 ~~menu.c _x11_raw → WMEvent~~ ✅ R.4 misc.c Xlib → vtable - R.5 usermenu.c Xlib → vtable + ~~R.5 usermenu.c Xlib → vtable~~ ✅ R.6 xmodifier.c → backend guard - R.7 window.c USE_XSHAPE → vtable + ~~R.7 window.c USE_XSHAPE → vtable~~ ✅ G.2 defaults.c XColor → vtable I.1 wmspec.c — verify X11-only paths I.2 xdnd.c — verify X11-only paths diff --git a/WAYLAND_ROADMAP.md b/WAYLAND_ROADMAP.md index e04697b..0ecabb6 100644 --- a/WAYLAND_ROADMAP.md +++ b/WAYLAND_ROADMAP.md @@ -77,6 +77,9 @@ Three major libraries: - Crash regression fixed: use-after-free on modal dialog close — `W_IsValidView()` validates stale `_view_target` against `view_table` at fetch boundary in `wevent_wl.c`; defense-in-depth in `wview.c` and `wevent.c` - Scene graph cleanup: WINGs toplevel close destroys `wlr_scene_node` and drops buffer via `W_ViewDestroyBackingFn` → `wl_view_destroy_backing_impl()` - XEvent synthesis block deleted in `cycling.c` +- **Wave 2 complete**: 4 mechanical elimination tasks (A4.1, B.1, R.5, R.7) +- C.1 skipped: XOR rubber-band drawing in `moveres.c` is inside `#if 0` — dead code +- Native XDG client rendering fix: `surface_commit_listener` calls `wlr_output_schedule_frame()` on every buffer commit (commit 8d963e7) ---