Commit Graph

257 Commits

Author SHA1 Message Date
Ollie 8ec338016a WINGs/wcolorpanel: gate magnifier via vtable callback dispatch
The magnifier is X11-backend-specific (screen capture). Instead of a
disguised is_x11 check, the view backend provides the callback directly:
- X11: .magnify_callback = W_ColorPanelMagnify (the magnifier impl)
- Wayland: .magnify_callback = NULL (button does nothing)

The button wiring uses the vtable value as the action callback.
No conditionals, no capability flags, pure vtable dispatch.

Also removes the screen_grab_image vtable slot that was a disguised check.
2026-05-23 16:15:03 +02:00
Ollie 0e26aa878c WINGs/wcolorpanel: replace pixmap/copy/fill X11 calls with render backend
Converts 60 X11 calls (XCreatePixmap, XFreePixmap, XCopyArea,
XFillRectangle) to render backend vtable dispatch. Remaining 40
calls are all in the magnifier feature (screen capture, inherently
platform-specific) and will be handled separately.
2026-05-23 16:09:10 +02:00
Ollie 9ccfd33971 WINGs: route selection acquire/release/request through vtable
- WMDeleteSelectionHandler: X11 grab/release replaced with selection_release vtable
- WMRequestSelection: XGetSelectionOwner+XConvertSelection replaced with selection_request vtable
- x11_selection_release: now properly releases ownership (was no-op)
- x11_selection_request: new vtable impl for X11 selection conversion
- Wayland selection_request: NULL (no-op, returns False)
2026-05-23 16:02:11 +02:00
Ollie 2dce45432d WINGs: route XOR drawing through vtable, remove X11 from wtextfield/wsplitview
- wsplitview.c: XFillRectangle+ixorGC replaced with xor_fill_rect vtable call
- wtextfield.c: removed Display *dpy and XRotateBuffers (cut buffer is dead)
- Added xor_fill_rect to W_ViewBackend (X11 impl, Wayland NULL/no-op)
2026-05-23 15:53:16 +02:00
Window Maker 9eecb2511c WINGs Phase D: port wballoon, wpopupbutton, wtext to vtable
New vtable slots: pointer_grab, pointer_ungrab, bell, balloon_draw, text_init
All implemented in X11 backend, no-ops in Wayland backend.

wballoon.c: XTranslateCoordinates -> get_screen_position, showText -> balloon_draw
wpopupbutton.c: all 7 Xlib calls replaced (grabs, coords, flush)
wtext.c: XMapWindow, XBell, XGrabPointer, XUngrabPointer, cursor, GC init all ported
2026-05-23 15:26:48 +02:00
Window Maker 264679a2d1 WINGs: port wwindow.c to vtable dispatch (Phase D)
Removes all direct Xlib calls from wwindow.c (25 calls eliminated).
ICCM/EWMH property setting dispatched through W_ViewBackend slots:
- window_set_title, window_set_icon_title, window_set_icon_image
- window_realize (WM_CLASS, WM_HINTS, WM_PROTOCOLS, transient-for)
- window_set_geometry (WM_NORMAL_HINTS)
- window_withdraw (XWithdrawWindow)

X11 backend implements full property setting.
Wayland backend is no-op (compositor-internal windows).
Struct moved to wwindow_p.h for backend access.
2026-05-23 15:19:52 +02:00
Window Maker 11c5625d1e WINGs: add Phase D vtable slots, port wballoon.c
Adds window_set_title, window_realize, window_set_geometry,
window_withdraw, pointer_grab, pointer_ungrab, bell, balloon_draw
slots to W_ViewBackend.

Ports wballoon.c:
- XTranslateCoordinates replaced with get_screen_position vtable
- showText replaced with balloon_draw vtable dispatch
- X11 backend calls existing rendering code
- Wayland backend is no-op (WM-level balloon handles dock tooltips)
2026-05-23 15:13:38 +02:00
Window Maker eeda48d24e Fix clipboard free mismatch: XFree -> wfree
x11_clipboard_fetch now returns wmalloc copy (XFree internally).
Callers use wfree uniformly on both backends. Prevents X11 regression
where XFree was called on wmalloc memory or vice versa.
2026-05-23 15:04:15 +02:00
Window Maker 0083654d2e WINGs: route DnD through view backend vtable
Adds drag_begin slot to W_ViewBackend. WMDragImageFromView dispatches
through it. X11 backend sets NULL (falls through to existing XDND
code). Wayland backend is a no-op — prevents crash without guards.
2026-05-23 15:02:30 +02:00
Window Maker cee271f2cd WINGs: cross-client clipboard via wlr_seat selection
Bridges WINGs internal clipboard to the Wayland seat selection so
copy/paste works between compositor-internal dialogs and real
Wayland clients. Store creates a wlr_data_source and sets seat
selection. Fetch reads from foreign selection sources via pipe.
2026-05-23 14:59:42 +02:00
Window Maker 0dc7e33e4b WINGs: route clipboard through view backend vtable
Adds clipboard_store/clipboard_fetch to W_ViewBackend. Replaces
direct XFetchBuffer/XStoreBuffer calls in wtextfield.c and wtext.c
with vtable dispatch. X11 backend wraps Xlib, Wayland backend uses
an internal buffer.
2026-05-23 14:55:59 +02:00
Window Maker e7427f08db WINGs Wayland: implement view ops (move, resize, unmap, raise, lower, reparent)
Replaces all no-ops in wview_wl.c with real implementations:
- move: updates pos, triggers parent redisplay
- resize: reallocates pixman buffer, triggers redisplay
- unmap/unmap_subviews: clears mapped flag, triggers parent redisplay
- raise: moves view to end of sibling list (drawn last = on top)
- lower: moves view to front of sibling list (drawn first = on bottom)
- reparent: moves between parent children lists
2026-05-23 14:51:07 +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 f3cb593d0f fix: button bevel colors derived from titlebar background
Hardcoded white/dark bevel looked wrong against colored titlebars.
Derive highlight and shadow colors from the actual titlebar background
color (+33% for highlight, -33% for shadow) to match the titlebar
bevel style.
2026-05-23 14:18:34 +02:00
lkn 5a4d989a78 fix: titlebar button rendering — proper colors and bevel
- Background: matches titlebar background (sampled)
- Foreground: uses title text color (the color parameter)
- Pressed state: swaps fg/bg (inverted colors)
- Border: raised bevel when normal, sunken when pushed
- Icon pixels rendered in fg color (not raw XPM colors)
2026-05-23 14:16:44 +02:00
lkn a34d8281b9 fix: raise button scene_bufs above titlebar after painting
Buttons and titlebar are siblings in the same scene tree. The titlebar
scene_buf is created after buttons, so it sits on top and occludes them.
Raise button nodes to top after enabling them in wl_frame_paint_button.
2026-05-23 14:12:34 +02:00
lkn 0cf867d548 fix: enable titlebar button scene_bufs for click and visibility
Buttons were rendered into the titlebar buffer with their own scene_buf
nodes disabled. This made them invisible to wlr_scene_node_at and
required a fragile coordinate-based hit-test (frame_buf_button_at).

Switch to rendering each button into its own frame_buf image and
enabling its scene_buf node. This makes buttons:
- Visible as independent scene nodes
- Directly hittable by wlr_scene_node_at
- Properly clickable via the normal frame_buf_at path

Update frame_buf_button_at to use a size threshold (<=30px) instead
of the disabled-node check to identify button sub-windows.
2026-05-23 14:08:34 +02:00
lkn 9ed1c19d6b B5: drawer icon renders directional arrow on Wayland
Replace the one-liner wl_drawer_icon_paint with a full implementation
that draws a filled triangle arrow pointing toward the drawer expansion
direction (left when on_right_side, right otherwise), matching X11.
2026-05-23 14:03:33 +02:00
lkn 3687ff0533 B4: clip icon renders workspace number and name on Wayland
Replace the one-liner wl_clip_icon_paint (which only painted the base
tile) with a full implementation that overlays the workspace number at
top-center and workspace name at bottom, matching the X11 behavior.

Also adds workspace.h and dock.h includes for WWorkspace/WDock types.
2026-05-23 14:02:28 +02:00
lkn 3d1008529b B2: create dock_shadow frame_buf for icon drag ghost overlay
The dock icon drag code (appicon.c, dock.c) uses scr->dock_shadow as a
visual ghost showing the target dock slot. On X11 this is an InputOutput
window; on Wayland it was never created, making all drag shadow
operations no-ops.

Create dock_shadow as a wl_frame_buf with a scene_buffer in the overlay
layer, starting disabled. All existing vtable ops (window_move, map,
unmap, set_background_pixmap, stacking_restack) already handle
frame_bufs, so no additional plumbing needed.
2026-05-23 13:58:23 +02:00
lkn 403ee93ec4 fix: WINGs dialog click-to-focus lookup
The WINGs view ID is not in the context table — only the fake leader
(parent frame_buf) is registered. Walk up to parent_id for the
context_find lookup so the WWindow is found correctly.

Also removed the ID >= 0x20000000 guard so any frame_buf click
(including WM frames without a toplevel surface) triggers focus.
2026-05-23 13:53:39 +02:00
lkn 7fe8121913 fix: clicking WINGs dialog surface now focuses the window
The click-to-focus code only checked wl_toplevel_view surfaces
(real Wayland/XWayland clients). WINGs dialogs are frame_bufs,
not toplevel views, so view_surface_at returned NULL and focus
was never set.

Add fallback: when no toplevel surface is under the pointer,
check if a WINGs dialog frame_buf (ID >= 0x20000000) was hit
and focus its associated WWindow.
2026-05-23 13:51:45 +02:00
lkn ee8489e3a1 fix: WINGs widget clicks on Wayland (child view hit-testing)
On Wayland, all WINGs child widgets composite into a single scene_buf
for the toplevel dialog. Clicks always arrived with the toplevel window
ID, so WMHandleEvent delivered them to the toplevel view which has no
ButtonPressMask handler. Child widget handlers never fired.

Fix: add W_FindViewAtPoint() to walk the view tree and find the deepest
mapped child at click coordinates. In handle_pointer_button, resolve the
child view for WINGs surfaces and pass it as the direct target to
W_WL_EnqueueEvent. WMHandleEvent then delivers directly to the widget.
2026-05-23 13:50:00 +02:00
lkn 68d4301b9f fix: modal dialogs not receiving mouse clicks on Wayland
frame_buf_at() could not find WINGs dialog frame_bufs because they
have no tree wrapper (only a bare scene_buf in WL_LAYER_FLOATING).
After the walk-up stops at the level_tree bucket, Step 4 only checks
fb->tree, missing tree-less frame_bufs entirely.

Add Step 5: match tree-less frame_bufs whose scene_buf node is a
direct child of a level_tree bucket. This resolves clicks on WINGs
modal dialogs (Run dialog, info panels, etc.).
2026-05-23 13:37:11 +02:00
lkn 8fb4083416 fix: titlebar buttons not responding to clicks on Wayland
frame_buf_button_at() used fb->scene_buf->buffer as the filter to
distinguish invisible button sub-windows from visible titlebar/resizebar
nodes. But wlr_scene_buffer_create() sets an initial buffer reference,
so scene_buf->buffer was never NULL for buttons — causing the hit-test
to skip all of them.

The correct distinguisher is node.enabled: buttons have their scene
node disabled (they are composited into the titlebar buffer by
wl_frame_paint_button), while titlebars/resizebars have enabled nodes.
2026-05-23 13:31:44 +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
lkn de0300d0fe A4: workspace switching badge for Wayland backend
Workspace switching (map/unmap) already worked via the vtable.
This commit adds the workspace name badge overlay:

- Create badge frame_buf in WL_LAYER_OVERLAY during screen init
- Implement wl_workspace_badge_render (pixman text rendering)
- Implement wl_workspace_badge_update (scene buffer refresh)
- Add workspace_badge_get_background vtable slot
- X11 backend: captures root window background (RGetXImage)
- Wayland backend: returns solid dark background
- workspace.c: replace direct RGetXImage/RCreateImageFromXImage
  with vtable call (zero backend guards in policy code)
2026-05-23 13:24:58 +02:00
Window Maker cc9fc26817 fix: event.c compile error — remove _x11_raw dependency in unmap handler
Replace broken xev->u.unmap.send_event check (WMEvent has no unmap
member) with unconditional withdraw=True when event comes from root.
Also remove unused XEvent variable in handleExpose.
2026-05-23 13:01:37 +02:00
Window Maker ce8783c0d4 fix: X11 backend rendering — frame paint pipeline and icon recursion
- x11_frame_paint_impl: delegate to wFrameWindowPaint() which handles
  texture remake, background setup, bevel drawing, and title/button paint.
  The old implementation only drew title text and resizebar lines, missing
  all background/texture setup.

- x11_icon_paint: add recursion guard. wIconPaint() calls icon_paint()
  which called wIconPaint() again — infinite recursion causing stack
  overflow crash on first dock/clip icon paint (blank desktop).

- Remove debug wwarning lines from wevent_x11.c and menu.c.
2026-05-23 12:56:43 +02:00
Window Maker a519435bfa x11 doc 2026-05-23 11:10:25 +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
Window Maker 8d963e79ac fix: native XDG client rendering — schedule frame on surface commit
Added permanent surface_commit_listener to wl_toplevel_view that calls wlr_output_schedule_frame on every client buffer commit.
Previously only the initial-commit listener existed, which removed itself after sending the first configure — subsequent buffer updates (typing in foot/xterm) were not triggering re-renders.
2026-05-17 20:59:31 +02:00
Window Maker 0950b228af feat: Wave 2 — eliminate direct Xlib calls and #ifdef guards
- R.5: usermenu.c: XStringToKeysym→xkb_keysym_from_name, XSendEvent guarded
- B.1: appicon.c: XClearArea→wm_backend->window_clear
- A4.1: workspace.c: remove 5 USE_XINERAMA guards, unified backend-neutral
- R.7: window.c: remove 4 USE_XSHAPE guards, vtable dispatch
2026-05-17 20:26:43 +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 3f9182b24a fix: destroy scene graph nodes when WINGs views close on Wayland
When a WINGs toplevel (modal dialog, info panel, etc.) is destroyed,
   wl_destroy() now calls W_ViewDestroyBackingFn, which invokes
   wl_view_destroy_backing_impl() to remove the frame_buf from the
   frame list and destroy the wlr_scene_node. This ensures closed
   WINGs windows actually disappear from screen.
2026-05-17 19:34:30 +02:00
Window Maker 15bec04b1b fix: eliminate use-after-free crash on modal dialog close
- wevent_wl.c: W_IsValidView() validates _view_target against view_table
     at fetch boundary (wl_fetch, wl_check_mask, wl_check_typed_window);
     nulls target before returning event if view was destroyed
   - wevent_wl.c: W_WL_InvalidateView() nulls queue entries at destroy time
   - wview.c: set view->screen=NULL before wfree(view)
   - wevent.c: defense-in-depth: check !view->screen || alreadyDead before use
2026-05-17 19:16:32 +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
Window Maker 1273962a95 complete F.2-5 2026-05-16 13:54:44 +02:00
Window Maker f20ecbc699 tool updates 2026-05-16 13:26:41 +02:00
Window Maker 0a295350cd ollie tools for wayland task execution 2026-05-16 13:06:18 +02:00
Window Maker a818db8a19 F.1: remove gratuitous Xlib.h includes from pure files 2026-05-16 12:30:12 +02:00
Window Maker 3af95550a2 cleanup 2026-05-16 12:29:14 +02:00
Window Maker f289ad7a8d wl impl planning 2026-05-16 12:28:44 +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 37ecea7c07 wayland: implement pointer grab for icon drag-and-move
Implement wl_pointer_grab (type 3 WM policy grab) that suppresses
client pointer focus delivery during WM-internal drags while letting
WME_MOTION events flow to WMMaskEvent. Implement wl_pointer_ungrab
and wl_pointer_change_cursor (maps WCUR_* to xcursor names).

Fix button release handler to not terminate type 3 grabs early —
the policy code calls pointer_ungrab itself.

Fix overlay surface blocking hit-testing: the iconify animation's
full-screen overlay (WL_LAYER_OVERLAY) was left enabled after the
animation completed, causing wlr_scene_node_at to hit it instead of
frame_bufs. Now server_ungrab disables the overlay node after flush.
2026-05-15 23:36:17 +02:00
Window Maker 6d42151d2e wayland: iconify/deiconify and post_dispatch struct field
- Remove !wwin->frame early exits in wIconifyWindow/wDeiconifyWindow
- Guard frame-dependent code with wwin->frame checks
- Implement wl_client_set_state (scene node enable/disable)
- Add post_dispatch to W_EventBackend struct (.h + .h.in)
- Fix client_snapshot, animateResize, and frame refs for Wayland
2026-05-15 18:55:14 +02:00