windowmaker-wl/ROADMAP.md

9.4 KiB

WindowMaker Wayland Port — Roadmap

Current State (2026-05-28, updated)

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.

WPrefs.app launches on Wayland but crashes are still observed — the root cause is WINGs widget library, which still has 412 direct Xlib calls in 15 non-split widget files that bypass the vtable dispatch (see Priority 2).

DND progress: compositor-internal drag-and-drop (WINGs view ↔ WINGs view) is now fully functional. Drag images render as scene-graph overlays, cursor changes to "plus" over valid drop targets. Cross-client DND (external Wayland client ↔ WINGs) has basic wiring in place — accepts drags, tracks motion/drop — but needs MIME type routing to WINGs destination procs to be fully functional.

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.

  • 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.
  • Test: save session, restart compositor, verify window positions restored
  • 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.

  • Test copy/paste between native Wayland clients
  • Test copy/paste between XWayland and native clients
  • Test primary selection (middle-click paste)

1.4 Remaining Vtable Stubs

These vtable slots are stubs or partial implementations:

Slot Purpose Needed For
overlay_draw_* Pixman animation buffer Iconify zoom animation
client_snapshot Window thumbnail capture Switch panel thumbnails, icon preview
window_set_border Scene rect border nodes Window borders
client_synth_configure XDG configure scheduling Resize negotiation
pointer_change_grab Grab parameter update Menu tracking

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 Porting Strategy

  • DND subsystem (dragsource.c + dragdestination.c + dragcommon.c, 2437 LOC, 98 calls) — done. Compositor-internal DND fully functional (drag image, cursor feedback, hit-testing via W_FindViewAtPoint, modal drag loop in wl_drag_begin). Cross-client DND (wl_data_device) has basic wiring — needs MIME type → WINGs type routing to complete.

  • wcolorpanel.c (3556 LOC, 89 calls) — done. Split into three files: wcolorpanel.c (backend-neutral, 2997 lines), wcolorpanel_x11.c (X11 magnifying glass, 601 lines), wcolorpanel_wl.c (Wayland stub). Magnify button shows "not available" dialog on Wayland. All 89 X11 calls isolated to wcolorpanel_x11.c.

  1. wwindow.c + widgets.c (1849 LOC, 76 calls) — window property management needs backend dispatch (ICCCM is X11-only; Wayland properties differ).

  2. winputmethod.c (243 LOC, 40 calls) — replace XIM/XIC with zwp_text_input_v3 or use xkbcommon directly.

  3. selection.c (392 LOC, 21 calls) — replace X selection protocol with wl_data_device / zwp_primary_selection_v1.

  4. wballoon.c (476 LOC, 28 calls) — route drawing through W_RenderBackend.

  5. wtext.c + wtextfield.c (5577 LOC, 33 calls) — route clipboard and grabs through backends.


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