windowmaker-wl/WAYLAND_ROADMAP.md

11 KiB

WindowMaker Wayland Port — Roadmap

Last updated: 2026-05-14

Governing Principles

  1. No guards in the middle — the core (src/, wrlib/, WINGs/) never asks "am I on X11 or Wayland?" Backend-specific behavior lives exclusively in the backend that owns it. Zero #ifdef WAYLAND or runtime backend checks in shared code.

  2. Duplication over coupling — if both backends need similar-but-not-identical logic, each gets its own copy. Shared abstractions that leak backend details are forbidden. Clarity and independence beat DRY.

  3. Fail fast, fail loudly — no defensive null checks, no silent fallbacks, no "just in case" guards. If a precondition is violated, crash immediately with a clear signal. Defensive coding for the sake of being defensive is not acceptable.

  4. Perfect architecture over fewer lines — the right structure wins even if it means more files or duplicated code. Clean separation now buys simple reasoning forever.

┌─────────────┐     ┌─────────────────────────┐     ┌─────────────────┐
│ X11 Backend │◄────┤  Core / wrlib / WINGs   ├────►│ Wayland Backend │
└─────────────┘     └─────────────────────────┘     └─────────────────┘
        │                       │                           │
  backend-specific        pure policy,              backend-specific
  special cases           zero backend guards       special cases

Architecture

WindowMaker 0.96.0 uses a vtable-based backend abstraction (WMBackend struct in src/backend/backend.h) with ~150+ function pointer slots. Policy code calls wm_backend->operation(...) and never touches X11/Wayland APIs directly.

Two backends:

  • X11: src/backend/x11/x11_backend.c (150K)
  • Wayland: src/backend/wayland/wl_backend.c (316K, wlroots-based compositor)

Activation: WMAKER_USE_WAYLAND=1 env var. Nested mode: WMAKER_WAYLAND_NESTED=1.

Three major libraries:

  • src/ — WM core (policy layer, zero Xlib calls remaining)
  • WINGs/ — Widget toolkit ("WINGs Is Not GNUstep"), split into _x11.c / _wl.c backends
  • wrlib/ — Raster graphics library (image loading, manipulation, rendering)

Completed (as of 2026-05-14)

  • Backend vtable abstraction (150+ slots)
  • Policy layer fully X11-free (zero direct Xlib calls in WM core)
  • wlroots compositor (headless + nested modes)
  • XDG shell + XWayland bridge
  • Frame rendering (titlebar, buttons, resizebar) via pixman → wlr_scene_buffer
  • Menu rendering + highlighting + item activation
  • Root menu from config file
  • Dock rendering (SHM panel, icon slots, app tracking)
  • Clip rendering
  • Background rendering
  • Mouse input (motion, buttons, scroll, grabs)
  • Keyboard input (XKB, modifiers, keysym translation)
  • Interactive move/resize with edge detection + cursor changes
  • Click-to-focus via hit-testing
  • Run dialog (WINGs modal loop with compositor tick)
  • Window manage/unmanage lifecycle (XDG toplevel + XWayland)
  • Focus delivery (wlr_seat_keyboard_notify_enter)
  • WINGs Wayland backend (views, fonts/PangoFT2, events/ring buffer, rendering/pixman, colors)
  • Smoke test suite (30+ tests in tests/wl-smoke-test.sh)

Phase A: Core Window Management Gaps

Priority: HIGH — needed for daily-driver use.

# Task Key Files Complexity
A1 Stacking (raise/lower via scene graph) stacking.c, wlr_scene_node_raise/lower ✅ Done
A2 Window maximize actions.c, usable area calc ✅ Done
A3 Window shade (titlebar collapse) actions.c, frame buffer resize ✅ Done
A4 Workspace switching (create/destroy/switch) workspace.c, scene tree reparenting Medium
A5 Alt-Tab window cycling + switch panel cycling.c, switchpanel.c, vtable switchpanel_enter Medium
A6 Window iconification (minimize) + miniwindow icon.c, appicon.c, vtable icon_paint/icon_update_pixmap Done
A7 Window placement algorithms (smart/cascade/random) placement.c (may already work via vtable) Low

Phase B: Dock & App Icons

# Task Key Files Complexity
B1 App icon rendering (load .tiff/.png, render into dock) appicon.c, wrlib loaders, vtable appicon_show Medium
B2 Dock icon drag & drop (reorder, add/remove) dock.c DnD handlers Medium
B3 Dock auto-launch on login dock.c session restore Low
B4 Clip workspace indicator (number, arrows) dock.c clip paint Low
B5 Drawer support (horizontal dock extension) dock.c drawer subsystem Medium
B6 Icon bounce on launch vtable appicon_bounce Low

Phase C: Visual Polish & Animations

# Task Key Files Complexity
C1 Slide animations (iconify/deiconify zoom) vtable slide_window Medium
C2 Menu scrolling (long menus) menu.c scroll logic Low
C3 Balloon tooltips (dock icon hover) vtable balloon_show Low
C4 Cursor themes (xcursor loading) wlr_xcursor_manager Low
C5 Window opacity (NETWM alpha) vtable netwm_set_opacity Low

Phase D: WINGs Widgets (for Preferences & Inspectors)

Core rendering backends exist. Complex widgets need verification/porting:

Widget Needed For Notes
WMList File panels, icon chooser Test
WMBrowser File browser in dialogs Test
WMColorPanel Color picker in prefs May need porting
WMFontPanel Font selection May need porting
WMFilePanel Open/save dialogs Test
WMTabView Preferences app tabs Test
WMScroller/WMScrollView Scrollable content Test
WMSlider Preference sliders Test
WMPopUpButton Dropdown menus in prefs Test
WMTextField (advanced) Multi-line editing Test
Drag & Drop Icon DnD, file DnD Likely needs porting

Phase E: Dialogs & Panels

# Task Key Files Complexity
E1 Window Inspector (per-window attributes) winspector.c High (many widgets)
E2 Info Panel (about dialog) dialog.c Low
E3 Crash Dialog (recovery UI) dialog.c Low
E4 Icon Chooser (browse icon files) dialog.c Medium
E5 Preferences App (full GUI) WPrefs.app/ High

Phase F: wrlib Wayland Integration

# Task Description Complexity
F1 RContext for Wayland pixman-backed RContext without X11 Display Medium
F2 RImage → pixman_image conversion Direct path without XImage Low (may exist)
F3 Texture rendering verification Solid, gradient, pixmap textures Verify
F4 Image format loaders PNG/JPEG/GIF/WebP (X11-independent) Verify

Phase G: Session & Persistence

# Task Key Files Complexity
G1 Session save/restore (positions, workspaces) session.c Medium
G2 Dock state persistence (icon layout) dock.c state files Low (may work)
G3 Defaults database (~/GNUstep/Defaults/) defaults.c Verify
G4 Autostart (launch apps from session) startup.c Low

Phase H: Advanced Compositor Features

# Task Description Complexity
H1 Multi-monitor (output layout, per-output workspaces) wlr_output_layout, screen.c High
H2 HiDPI / output scaling wlr_output_set_scale, buffer scaling Medium
H3 Gamma control (night light) Already advertised, wire up Low
H4 Screen lock integration ext-session-lock-v1 protocol Medium
H5 Clipboard (copy/paste between clients) wl_data_device (may work via wlroots) Verify
H6 Primary selection Already advertised Verify
H7 Screencopy (screenshots) Already advertised Verify
H8 DMA-BUF (GPU buffer sharing) Already advertised Verify
H9 Input method (IME support) Already advertised Medium

Phase I: EWMH / Foreign Toplevel

# Task Description Complexity
I1 Foreign toplevel list (taskbar integration) Already advertised, verify events Low
I2 XDG activation (focus stealing prevention) Wire to policy Low
I3 Idle inhibit (prevent blank during video) Already advertised Low

Phase J: DRM/KMS Backend (Native)

For running without a host compositor:

# Task Description Complexity
J1 DRM backend wlr_backend_autocreate Medium
J2 libinput (real hardware input) wlroots handles this Low
J3 VT switching wlr_session Low
J4 Multi-GPU Secondary GPU rendering High

Suggested Implementation Order

NOW (daily-driver basics):
  A1. Stacking (raise/lower)
  A2. ~~Maximize~~ ✅
  A3. ~~Shade~~ ✅
  A4. Workspace switching
  A5. Alt-Tab cycling
  A6. Icon/minimize
  A7. Placement (verify)

NEXT (visual completeness):
  B1. App icon rendering (wrlib → pixman)
  F1. wrlib RContext for Wayland
  C1. Slide animations
  C3. Balloon tooltips

THEN (full feature parity):
  D*. Test all WINGs widgets
  E1. Window Inspector
  E4. Icon Chooser
  G*. Session persistence
  B2-B6. Full dock features

LATER (production-ready):
  H1. Multi-monitor
  H2. HiDPI
  J*. DRM/KMS native backend
  E5. WPrefs app

Technical Notes

  1. Rendering pattern: pixman_image_t → wlr_scene_buffer → position in scene graph
  2. wrlib is mostly X11-independent — only context.c and convert.c touch X11
  3. WINGs complex widgets are the hardest remaining work (subtle X11 assumptions in events/coords)
  4. wlroots handles compositor plumbing — protocols advertised, work is wiring to policy
  5. wl_backend.c (316K) should be split into wl_frame.c, wl_menu.c, wl_input.c, wl_toplevel.c, wl_output.c as complexity grows
  6. Many vtable slots are no-ops — stubs exist, need implementation following the pixman→scene pattern

Key Source Files Reference

File Size Purpose
src/backend/backend.h 74K Vtable definition
src/backend/backend_types.h 16K Backend-neutral types
src/backend/wayland/wl_backend.c 316K Wayland compositor
src/backend/x11/x11_backend.c 150K X11 backend
src/window.c 83K Window management
src/dock.c 130K Dock/Clip/Drawers
src/menu.c 61K Menu system
src/actions.c 68K Window actions
src/defaults.c 102K Preferences/config
src/event.c 61K Event dispatch
src/moveres.c 67K Move/resize
src/wmspec.c 61K EWMH compliance
src/main.c 22K Entry point
WINGs/WINGs.h 56K Toolkit public API
wrlib/wraster.h 17K Raster lib public API