Commit Graph

17 Commits

Author SHA1 Message Date
Ollie 130fd760b5 docs: mark Phase D complete, add src/ audit results
Phase D (WINGs widget X11 elimination) is complete with 7 commits.
The src/ core audit confirms all X11 is already routed through
wm_backend-> dispatch. The entire codebase has zero X11 executing
on the Wayland path.
2026-05-23 16:31:45 +02:00
Window Maker 4c5f07f9ec Phase C complete: balloon tooltips + window opacity
C1 (slide animations): already works - misc.c calls vtable window_move
C2 (menu scrolling): pure policy code, already works
C3 (balloon tooltips): pixman text render to wlr_scene_buffer overlay
C4 (cursor themes): wlr_xcursor_manager already in place
C5 (window opacity): read _NET_WM_WINDOW_OPACITY, apply to frame +
    child buffers + client surface via wlr_scene_buffer_set_opacity
2026-05-23 14:46:18 +02:00
Window Maker a0a27b56d5 Update ACTION_PLAN.md and WAYLAND_ROADMAP.md 2026-05-23 14:30:29 +02:00
lkn 57a6497137 B1: fix appicon_show for Wayland (was no-op, icons never placed)
The Wayland backend already had full wl_appicon_paint and wl_icon_paint
implementations (tile + image composite + text + scene commit), but
appicon_show was a no-op stub. This meant app icons were never initially
placed or mapped when applications launched.

Fix: wl_appicon_show now calls paint_app_icon() (pure policy code that
handles PlaceIcon + wAppIconMove + wLowerFrame + window_map via vtable),
identical to the X11 backend.

Also mark A7 (placement) as verified — pure policy, zero backend calls.
2026-05-23 13:29:12 +02:00
lkn 1e4caddb9f docs: mark A4 workspace switching as complete 2026-05-23 13:25:38 +02:00
WindowMaker Dev e41dcc7d38 docs: update ACTION_PLAN.md and WAYLAND_ROADMAP.md for Wave 2 and rendering fix 2026-05-18 01:21:24 +02:00
ollie 6628d74d38 Wave 1 complete: XEvent* → WMEvent* signature changes + crash fixes
All 8 signature change tasks done:
  A5.1  wSwitchPanelHandleEvent: XEvent* → WMEvent*
  A5.2  Remove XEvent synthesis in cycling.c
  B.3   wDockReceiveDNDDrop: XEvent* → WMEvent*
  E.3   wRootMenuPerformShortcut: XEvent* → WMEvent*
  E.4   wClientConfigure/wClientCheckProperty: X11 types → WMEvent*
  R.1   framewin.c: _x11_raw → WMEvent
  R.2   icon.c: _x11_raw → WMEvent
  R.3   menu.c: _x11_raw → WMEvent

Results:
- _x11_raw sites in src/: 16 → 9 (7 eliminated in policy code)
- Build verified clean
- Crash regression (use-after-free on dialog close) fixed:
  W_IsValidView() validates stale _view_target against view_table
  Scene graph nodes destroyed when WINGs toplevels close

Update ACTION_PLAN.md and WAYLAND_ROADMAP.md to mark Wave 1 complete.
2026-05-17 19:43:58 +02:00
ollie 9943c05b4a docs: mark signature changes and _x11_raw eliminations complete 2026-05-17 17:43:47 +02:00
Window Maker a737831ea8 phase f done 2026-05-17 16:40:47 +02:00
Levi Neely 10c90ff6ce docs: add comprehensive semantic mapping appendix to roadmap 2026-05-16 06:09:45 +00:00
Window Maker 5c6fa776a9 wayland: implement alt-tab window cycling and switch panel (A5)
Vtable slots implemented in wl_backend.c:
- window_set_background_pixmap: composite pixman image into frame_buf/WINGs view
- window_clear: fill frame_buf/WINGs view with transparent black
- pixmap_free: pixman_image_unref
- shape_combine_mask: wlr_scene_buffer_set_opaque_region from mask pixman image
- switchpanel_send_enter: focus-guard flag to suppress spurious focus on panel destroy
- keyboard_grab/keyboard_ungrab: suppress client key forwarding during alt-tab loop

WINGs view backing: wl_window_clear and wl_window_set_background_pixmap
fall back to W_GetViewBacking() for WINGs window IDs when frame_buf_find fails.

cycling.c: synthesize XEvent when _x11_raw is NULL (Wayland native events)
to prevent segfault in switchpanel event handling.

Alt-tab cycling works. Switch panel rendering still needs investigation.
2026-05-16 00:49:29 +02:00
Window Maker 245d0077b5 wayland: implement correct stacking model with scene-graph level trees
Three interlocking problems were present in the Wayland stacking
implementation.

1. Wrong scene-graph nodes targeted by stacking operations

Each managed window groups its frame pixels and client surface under a
single wlr_scene_tree (fb->tree):

  fb->tree
    fb->scene_buf       (frame decoration pixels)
    child_frame_bufs    (titlebar / resizebar sub-frames)
    v->scene_node       (client surface, reparented in)

wl_stacking_restack was raising fb->scene_buf -- a child inside fb->tree
-- instead of fb->tree itself, a no-op for inter-window ordering. Three
redundant loops then tried to separately raise the client surface and child
frames, also to no effect. wl_stacking_lower had the same bug.

Fix: raise/lower fb->tree in both functions so the entire window assembly
moves as one atomic unit.

2. Flat scene graph -- no structural level ordering

All nodes were direct children of scene->tree, so creation order and
raise_to_top calls determined Z-order. A normal window could accidentally
render above a floating window after any CommitStacking call.

Fix: introduce 9 wlr_scene_tree level buckets created at scene init time
in bottom-to-top order:

  0 WL_LAYER_BACKGROUND  background rect / wallpaper
  1 WL_LAYER_DESKTOP     WMDesktopLevel
  2 WL_LAYER_SUNKEN      WMSunkenLevel
  3 WL_LAYER_NORMAL      WMNormalLevel  (default for new frames)
  4 WL_LAYER_FLOATING    WMFloatingLevel / WINGs dialogs
  5 WL_LAYER_MENU        WMMainMenuWindowLevel / OR-redirect windows
  6 WL_LAYER_DOCK        WMStatusWindowLevel / dock panel surface
  7 WL_LAYER_FULLSCREEN  WMFullscreenLevel
  8 WL_LAYER_OVERLAY     WMModalPanel / WMPopUp / XOR overlay

Every scene node is assigned to the correct bucket at creation.
A new stacking_set_level vtable slot called from AddToStackList moves
fb->tree to the right bucket whenever a window is added or its level
changes via ChangeStackingLevel. X11 backend implements it as a no-op.

3. XDG client surface not reparented into fb->tree

For XDG toplevels the map handler called wManageWindow before creating
view->scene_node, so the reparent inside wl_client_reparent was a no-op.
The client surface then lived as a flat sibling of fb->tree in
WL_LAYER_NORMAL, never moving with its frame during stacking operations.

Fix: after creating view->scene_node, check if frame_id is already set
and do the deferred reparent immediately.

4. Hit-testing broken by level-tree hierarchy

frame_buf_at walked up from the hit scene node to the first direct child
of scene->tree. With level buckets that stopped at the level_tree node
instead of fb->tree, making every window in the same bucket appear to be
the same window. Client surfaces were not blocking clicks on frames
beneath them, and titlebar sub-frames were not distinguished from the
top-level frame, breaking move and resize initiation.

Fix: rewrite frame_buf_at with a two-pass approach:
  Pass 1 -- exact match: check if the topmost node is a child frame_buf
    scene_buf such as titlebar, resizebar, or button; return it directly.
  Pass 2 -- walk up stopping when parent is a level_tree bucket, then
    match that window-root node to a top-level frame_buf tree.
  Return NULL if the hit was on a client surface.

ROADMAP: mark A1 done.
2026-05-15 09:11:46 +02:00
lkn 0e6f2f60e8 wl_backend: fix frame button click dispatch (close/iconify)
frame_buf_at was preferring parent frame_bufs over smaller children
(buttons), so clicks on the close/iconify button area were dispatched
to the titlebar instead. Fix by preferring the smallest frame_buf
that contains the pointer position.
2026-05-14 23:36:34 +02:00
lkn 2148671fb6 roadmap: mark A2 (Maximize) done 2026-05-14 23:30:24 +02:00
lkn 98f3175895 wl_backend: fix client resize and frame lifecycle
- Send frame_done after configure so clients can render at new size
- Set activated state on toplevel configure
- Dispatch idle callbacks to flush configure immediately
- Add client_set_maximized vtable entry for XDG toplevel state
- Re-enable frame_buf scene node on unshade
- Raise client scene node on window_map (fixes unshade visibility)
- Reposition client and children in frame_configure
- Schedule output frame after frame_paint
- Remove debug wwarnings from wl_window_resize

This fixes:
- Window shade/unshade (resizebar + client surface visibility)
- Client surface receiving configure events and rendering
- Frame decoration updates on resize/maximize
2026-05-14 23:08:37 +02:00
Levi Neely 6dfdc5a108 wayland: fix frame/client desync and titlebar offset
Three issues fixed:

1. Frame and client surface moved independently during interactive
   window move. The client surface (wl_toplevel_view) and frame
   decorations (wl_frame_buf) are independent scene graph nodes —
   unlike X11 where reparenting creates an implicit parent-child
   relationship. Added frame_id/frame_rel_x/frame_rel_y to
   wl_toplevel_view so wl_window_move keeps them in sync.

2. window_move(client_win, x, y) treated coordinates as absolute,
   but the WM core passes relative-to-frame coordinates (matching
   X11 child window semantics). Now detected via frame_id and
   converted to absolute scene positions.

3. Titlebar scene node was offset by left_button_width because
   updateTitlebar() configures it for X11 layout (separate
   overlapping windows). Since the Wayland backend composites
   buttons directly into the titlebar buffer, override the
   titlebar position to frame origin during wl_frame_paint.
2026-05-14 12:59:39 +02:00
Levi Neely 288d2ad3a7 Phase 82: wlroots 0.19 compatibility + native Wayland client support
- Add wlr_subcompositor global (required by all modern Wayland clients)
- Switch from xdg_shell new_surface to new_toplevel signal (wlroots 0.19
  fires new_surface with role=NONE before get_toplevel assigns the role)
- Defer initial xdg_surface configure to first client commit via
  surface->events.commit listener (surface must be initialized first)
- Defer xdg_decoration set_mode to first commit (set_mode internally
  calls schedule_configure which asserts initialized)
- Wire destroy_listener to toplevel->events.destroy instead of
  xdg_surface->events.destroy (wlroots asserts toplevel event lists
  are empty before the toplevel is freed)
- Log DISPLAY and WAYLAND_DISPLAY env vars at startup
- Add WAYLAND_ROADMAP.md

Native Wayland clients (foot, etc.) can now connect, render, and
disconnect without crashing the compositor.
2026-05-14 11:57:15 +02:00