231 lines
9.5 KiB
Markdown
231 lines
9.5 KiB
Markdown
# WindowMaker Wayland Port — Roadmap
|
|
|
|
## Current State (2026-05-28, final)
|
|
|
|
The backend abstraction is complete. The `src/` policy layer has zero direct Xlib
|
|
calls and zero `_x11_raw` references. The Wayland backend (wlroots-based, 10K lines)
|
|
implements all core window management: stacking, maximize, shade, workspaces,
|
|
alt-tab, dock/clip, menus, move/resize, focus, and frame rendering.
|
|
|
|
**WINGs X11 call isolation is complete.** All 412+ direct Xlib calls that previously
|
|
lived in shared widget code have been isolated to per-backend `_x11.c` files with
|
|
Wayland stubs in `wstubs_no_x11.c`. The remaining work is feature implementation,
|
|
not leak cleanup.
|
|
|
|
**What works on Wayland:**
|
|
- Window management (stacking, maximize, shade, workspaces, alt-tab, move/resize)
|
|
- DND (compositor-internal with drag image overlay + cursor feedback; cross-client
|
|
via wl_data_device with basic MIME routing)
|
|
- Clipboard + primary selection (copy/paste between Wayland native and XWayland)
|
|
- Session persistence (save/restore for native Wayland clients)
|
|
- Balloon tooltips (proper leave tracking + multi-line text)
|
|
- Window thumbnails (client_snapshot via buffer read)
|
|
- XWayland client support (DISPLAY=:1 via eager mode startup)
|
|
- WPrefs.app (all preference panels — crashes fixed by X11 call isolation)
|
|
|
|
The smoke test suite passes for core WM features.
|
|
|
|
What remains is **feature completion and production hardening**.
|
|
|
|
---
|
|
|
|
## Priority 1: Daily-Driver Gaps
|
|
|
|
These block using the Wayland backend as a primary desktop.
|
|
|
|
### 1.1 Session Persistence
|
|
|
|
`src/session.c` (614 lines) — verify save/restore works on Wayland. Window
|
|
positions are tracked in `WWindow` (backend-neutral). The only concern is
|
|
matching restored sessions to native XDG clients via `app_id` instead of
|
|
`WM_CLASS`.
|
|
|
|
- [x] Save/restore state for Wayland native clients: `PropGetWMClass` already
|
|
returns the XDG `app_id` on Wayland. Session save no longer bails when
|
|
`GetCommandForWindow` returns NULL (external Wayland clients have no ICCCM
|
|
command). Restore matches by `app_id` via instance+class without requiring
|
|
a command.
|
|
- [x] Save/restore works for Wayland native clients (foot). XWayland (xterm) needs WM_COMMAND matching — lower priority.
|
|
- [ ] Verify dock state persistence (icon layout in `~/GNUstep/Defaults/`)
|
|
|
|
### 1.2 Multi-Monitor
|
|
|
|
Currently single-output only. wlroots provides `wlr_output_layout` and
|
|
`new_output` signal.
|
|
|
|
- [ ] Populate `WScreen.heads[]` from `wlr_output_layout_get_box` in `screen_open`
|
|
- [ ] Handle output hotplug (migrate windows on disconnect)
|
|
- [ ] Per-head usable area calculation (dock margins)
|
|
- [ ] Test with nested multi-output (`WMAKER_WAYLAND_NESTED=1` + `wlr-randr`)
|
|
|
|
### 1.3 Clipboard
|
|
|
|
wlroots advertises `wl_data_device_manager` and `zwp_primary_selection_v1`.
|
|
XWayland bridge auto-syncs. Needs verification.
|
|
|
|
- [x] Copy/paste between native Wayland clients — works
|
|
- [x] Copy/paste between XWayland and native clients — works
|
|
- [x] Primary selection (middle-click paste) — works (both directions)
|
|
|
|
### 1.4 Remaining Vtable Stubs
|
|
|
|
| Slot | Status |
|
|
|------|--------|
|
|
| `overlay_draw_*` | ✅ Done — real pixman overlay implementation |
|
|
| `client_snapshot` | ✅ Done — buffer read for native, XGetImage for XWayland |
|
|
| `window_set_border` | ✅ No-op (borders drawn into frame buffer) |
|
|
| `client_synth_configure` | ✅ Done — XDG configure + XWayland configure |
|
|
| `pointer_change_grab` | ✅ Done — sets cursor + establishes grab state during move/resize (fix: was not setting grab_type for opaque moves, causing cursor to reset to arrow on every motion event) |
|
|
|
|
---
|
|
|
|
## Priority 2: WPrefs.app Full Port
|
|
|
|
### Status: Direct X11 Calls Resolved
|
|
|
|
All 11 direct Xlib calls previously reported in WPrefs.app have been audited:
|
|
|
|
| File | Previously Reported | Actual Status |
|
|
|------|-------------------|--------------|
|
|
| `TexturePanel.c` | 7 calls | **0 active** — all inside `#if 0` dead code blocks |
|
|
| `Expert.c` | 1 (XGetDefault) | **0 active** — call already removed |
|
|
| `MouseSettings.c` | 1 (XChangePointerControl) | **0 active** — call already removed |
|
|
| `xmodifier.c` | 1 (XGetModifierMapping) | **0 active** — only in a comment |
|
|
|
|
WPrefs.app itself now has **zero direct Xlib calls**. The crash source is in
|
|
WINGs widget library, which WPrefs links against.
|
|
|
|
### Root Cause: WINGs X11 Leaks (412 calls)
|
|
|
|
WINGs still has **412 direct Xlib calls** across 15 non-split widget files that
|
|
bypass the 5-vtable dispatch (`W_ViewBackend`, `W_EventBackend`, `W_RenderBackend`,
|
|
`W_FontBackend`, `W_ColorBackend`). These are the crash sites when WPrefs calls
|
|
WINGs APIs on the Wayland path.
|
|
|
|
| WINGs File | X11 Calls | What It Does |
|
|
|------------|-----------|-------------|
|
|
| `wcolorpanel.c` | 89 | Pixmap manipulation, `XGetImage`, pointer grabs, cursor recoloring |
|
|
| `dragsource.c` | 45 | XDND protocol (`XSendEvent`, `XInternAtom`, grabs) |
|
|
| `wwindow.c` | 41 | ICCCM window properties (`XSetWMName`, `XSetWMHints`, etc.) |
|
|
| `winputmethod.c` | 40 | XIM/XIC lifecycle (`XOpenIM`, `XCreateIC`, `XLookupString`) |
|
|
| `dragdestination.c` | 37 | XDND protocol (receive side) |
|
|
| `widgets.c` | 35 | Screen init, GC/cursor creation, modifier mapping |
|
|
| `wballoon.c` | 28 | Tooltip drawing, shape extension |
|
|
| `wtext.c` | 23 | Clipboard, grabs |
|
|
| `selection.c` | 21 | X selection protocol |
|
|
| `dragcommon.c` | 16 | XDND shared atom/property helpers |
|
|
| `wappresource.c` | 15 | App icon property reading |
|
|
| `wtextfield.c` | 10 | Clipboard, grabs |
|
|
| `wpopupbutton.c` | 7 | Pointer grabs |
|
|
| `wruler.c` | 3 | `XRectangle` type usage |
|
|
| `wmisc.c` | 2 | Coordinate translation |
|
|
|
|
These files need backend abstraction — either routing through the existing
|
|
5 vtables, or adding new vtables for DND, selection, and input methods.
|
|
|
|
### WINGs X11 Call Isolation — COMPLETE
|
|
|
|
All 412+ direct Xlib calls in WINGs have been isolated to `_x11.c` backend files.
|
|
No active X11 calls remain in non-backend WINGs source files.
|
|
|
|
| File | LOC | X11 Calls | Status |
|
|
|------|-----|-----------|--------|
|
|
| DND (drag*source/destination/common) | 2437 | 98 | Isolated — internal DND works, cross-client
|
|
via wl_data_device with basic MIME routing |
|
|
| `wcolorpanel.c` | 3556 | 89 | Split into `wcolorpanel.c` + `_x11.c` + `_wl.c` |
|
|
| `wwindow.c` + `widgets.c` | 1849 | 76 | Already clean — all via vtable dispatch |
|
|
| `winputmethod_x11.c` | 243 | 40 | Isolated — Wayland stub in wstubs_no_x11.c |
|
|
| `selection_x11.c` | 392 | 21 | Push + fetch via clipboard hooks; synchronous
|
|
fetch path on Wayland |
|
|
| `wballoon_x11.c` | 476 | 28 | Wayland balloon_draw in wview_wl.c renders
|
|
yellow tooltip with multi-line support |
|
|
| `wtext.c` + `wtextfield.c` | 5577 | 33 | Already clean — all via vtable dispatch |
|
|
| All other `_x11.c` files | ~2000 | ~27 | Isolated — stubs in wstubs_no_x11.c |
|
|
|
|
---
|
|
|
|
## Priority 3: Visual Completeness
|
|
|
|
### 3.1 Iconify/Deiconify Zoom Animation
|
|
|
|
The X11 path uses XOR GC rubber-band rectangles (`XGrabServer` + `XDrawRectangle`).
|
|
On Wayland, implement as per-frame pixman overlay buffer.
|
|
|
|
- [ ] Implement `overlay_draw_rect` in wl_backend.c using a transient `wlr_scene_buffer`
|
|
- [ ] Wire `animateResize()` in actions.c to use the vtable
|
|
|
|
### 3.2 Client Snapshot (Window Thumbnails)
|
|
|
|
Used by switch panel and icon preview. X11 uses `XGetImage`. Wayland options:
|
|
- Render last committed `wlr_texture` into an RImage via pixman blit
|
|
- Use `wlr_screencopy_manager_v1`
|
|
|
|
- [ ] Implement `client_snapshot` vtable slot using last-committed texture
|
|
|
|
### 3.3 Window Inspector
|
|
|
|
`src/winspector.c` — WINGs-based dialog. Should work on Wayland since WINGs
|
|
widgets are ported. Needs testing.
|
|
|
|
- [ ] Test window inspector opens and displays attributes
|
|
- [ ] Test attribute changes apply correctly
|
|
|
|
---
|
|
|
|
## Priority 4: HiDPI & Scaling
|
|
|
|
- [ ] Set `wlr_output_set_scale` per output
|
|
- [ ] Multiply pixman buffer allocations by scale factor
|
|
- [ ] Set PangoFT2 DPI from `output.scale * 96.0`
|
|
- [ ] Ensure `WScreen.width/height` remain logical coordinates
|
|
- [ ] Test at 2x scale
|
|
|
|
---
|
|
|
|
## Priority 5: Protocol Wiring
|
|
|
|
wlroots already advertises these protocols. Wire them to policy:
|
|
|
|
| Protocol | Purpose | Effort |
|
|
|----------|---------|--------|
|
|
| `ext-session-lock-v1` | Screen lock | Medium |
|
|
| `xdg_activation_v1` | Focus stealing prevention | Low |
|
|
| `zwp_idle_inhibit_manager_v1` | Prevent blank during video | Low |
|
|
| `ext-foreign-toplevel-list-v1` | Taskbar integration | Low |
|
|
| `zwp_input_method_v2` | IME support | Medium |
|
|
| `wlr_gamma_control_v1` | Night light | Low |
|
|
|
|
---
|
|
|
|
## Priority 6: DRM/KMS Native Backend
|
|
|
|
For running without a host compositor:
|
|
|
|
- [ ] Use `wlr_backend_autocreate` (replaces headless/nested)
|
|
- [ ] libinput for real hardware input (wlroots handles this)
|
|
- [ ] VT switching via `wlr_session`
|
|
- [ ] Test on real hardware
|
|
|
|
---
|
|
|
|
## Architecture Notes
|
|
|
|
- **Rendering pattern**: pixman_image_t → wlr_scene_buffer → scene graph position
|
|
- **Event flow**: wlroots signals → wl_backend.c handlers → WMEvent → DispatchEvent
|
|
- **WINGs on Wayland**: compositor-internal views (not wl_surfaces), pixman-rendered,
|
|
events via ring buffer from compositor hit-testing
|
|
- **wl_backend.c (420K) should be split** into wl_frame.c, wl_menu.c, wl_input.c,
|
|
wl_toplevel.c, wl_output.c as complexity grows
|
|
|
|
---
|
|
|
|
## Reference Documents
|
|
|
|
| Document | Purpose |
|
|
|----------|---------|
|
|
| `ARCHITECTURE.md` | Codebase structure, data flow, key types |
|
|
| `BACKEND_ABSTRACTION.md` | Historical analysis of X11 leaks (all resolved) |
|
|
| `X11_IMPLEMENTATION.md` | How X11 path works (correctness reference) |
|
|
| `ACTION_PLAN_PROMPTS.md` | Task templates for mechanical porting work |
|
|
| `tools/wm-port/` | Agent-assisted task dispatch tooling |
|