# 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 | Medium | | 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 |