Commit Graph

10 Commits

Author SHA1 Message Date
lkn 859c4d8e78 wl_backend: fix unshade — re-enable and raise client surface and frame
On shade, the client scene node was lowered and disabled, and the
frame_buf scene node was disabled. On unshade, the frame_buf node
was not re-enabled, and the client node was enabled but remained
behind the frame (at bottom of Z-order from stacking_lower).

Fix: re-enable frame_buf node when show_resizebar is true, and
raise the client scene node to top on window_map so it's above
the frame background.
2026-05-14 22:26:07 +02:00
Levi Neely 9cfe322573 Phase 80b: eliminate if(dpy) guards and replace X11 calls with vtable dispatch
- Remove all 20 'if (dpy &&' guards from policy files
- Replace XMapWindow, XUnmapWindow, XMoveWindow, XClearWindow,
  XFreePixmap, XFlush, XSync, XResizeWindow, XSetWindowBackground,
  XSetWindowBackgroundPixmap, XMoveResizeWindow, XSelectInput,
  XMapRaised, XUngrabPointer, XUngrabKeyboard, XGrabKeyboard,
  XGrabServer, XUngrabServer, XRestackWindows, XDestroyWindow,
  XReparentWindow, XAddToSaveSet, XSetWindowBorderWidth
  with vtable dispatch across all policy files
- Make wFrameWindowPaint mechanism code: X11 backend's frame_paint
  now calls it; all policy call sites dispatch through vtable
- Replace dpy feature-gating in main.c/startup.c with is_wayland

Remaining: 278 dpy refs in policy files, mostly in rendering functions
(wIconPaint, wAppIconPaint, paintEntry, drawFrame, balloon, dock,
dialog, superfluous, event) that are X11 mechanism code reachable
only through the X11 backend path.
2026-05-13 10:21:00 +02:00
Levi Neely 553d2ca0ba Phase 80: eliminate all 43 if(!dpy) return guards via vtable dispatch
Remove every 'if (!dpy) return' guard from policy files by moving
X11 mechanism code behind WMBackend vtable slots. Call sites now
dispatch through wm_backend->slot(), the X11 backend implements the
mechanism, and the Wayland backend provides no-ops or Wayland-native
implementations.

New vtable slots added to backend.h:
- Frame: frame_alloc_border_pixel, frame_update_texture, frame_paint_button
- NETWM: netwm_init, netwm_cleanup, netwm_update_desktop,
  netwm_get_current_desktop, netwm_update_opacity, netwm_update_actions,
  netwm_check_client_hints, netwm_check_initial_state, netwm_get_pid,
  netwm_cleanup_frame_extents
- Properties: prop_get_protocols, prop_get_check_property,
  prop_set_wmaker_protocols, prop_set_icon_tile, prop_cleanup
- Client: client_restore, client_set_state, client_send_protocol,
  client_kill, client_get_colormap_windows
- Misc: eat_expose, move_window, slide_windows, get_text_selection,
  get_shortcut_string, get_command_for_window
- Icon: icon_update_pixmap, icon_paint
- AppIcon: appicon_show, appicon_paint, appicon_bounce
- Shutdown: restore_desktop, wipe_desktop
- Resources: get_color_for_colormap, free_color, colormap_install
- Protocol: xdnd_init, motif_get_hints
- Startup: manage_all_windows
- Event: event_handle_signal_exit

Structural changes:
- MWMHints moved from motif.c local typedef to motif.h
- WProtocols given struct tag for forward declaration
- Static functions made non-static: wGetTextSelection, wGetCommandForWindow,
  wGetMWMHints, wWipeDesktop, wManageAllWindows, wNETWMUpdateWindowOpacity

Verification: grep -rn 'if (!dpy)' src/*.c returns zero results.
nm wl_backend.o confirms no new X11 symbols in Wayland path.
2026-05-13 10:01:57 +02:00
Levi Neely f772c79ff5 wayland: Phase 73 — frame NULL guards in wmspec.c and winmenu.c
Guard wNETFrameExtents (returns early when !dpy || !frame), so it
does not try to set X11 properties or dereference titlebar/resizebar
for Wayland windows.

Guard OpenWindowMenu, execWindowOptionCommand, and updateOptionsMenu
in winmenu.c so that the window menu and its KeepOnTop/KeepAtBottom
stacking callbacks do not crash when wwin->frame is NULL.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 09:56:44 +01:00
Levi Neely c2c4f699f3 wayland: Phase 70 — apply WIN_WORKSPACE macro to all frame->workspace reads
Mechanically replace all remaining wwin->frame->workspace reads (41
occurrences across 9 source files) with the WIN_WORKSPACE(w) macro
introduced in Phase 69.  Write sites (inside if-dpy or if-frame guards)
retain direct frame->workspace assignments as they cannot reach Wayland.

Also fixes two sed-introduced malformations:
  - actions.c: tmp->WIN_WORKSPACE(prev) → WIN_WORKSPACE(tmp->prev)
  - placement.c: ((WIcon*)parent)->WIN_WORKSPACE(owner) → correct form

Files changed: actions.c cycling.c event.c moveres.c placement.c
               switchpanel.c window.c wmspec.c workspace.c

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 09:46:35 +01:00
Levi Neely b0728c7048 wayland: Phase 48 — guard NETWM init/update/cleanup functions against NULL dpy
Add if (!dpy) return guards to wNETWMInitStuff, wNETWMCleanup,
wNETWMUpdateDesktop, wNETWMGetCurrentDesktopFromHint,
wNETWMUpdateActions, and updateWindowOpacity so the Wayland backend
path does not crash calling XChangeProperty/XDeleteProperty/
XGetWindowProperty on a NULL display.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 06:54:35 +01:00
Levi Neely 490ecb34ff wayland: Phase 40 — wire toplevel unmap to wUnmanageWindow
Guard all dpy==NULL / frame==NULL crash sites in the unmanage path:
  - wUnmanageWindow (window.c): frame ptr set to NULL-safe expression;
    window_unmap, raise_delay timer, and owner border change all
    guarded on frame != NULL
  - wSelectWindow (actions.c): early return if !wwin->frame
  - wNETCleanupFrameExtents (wmspec.c): early return if !dpy
  - wClientRestore (client.c): early return if !dpy

Wire handle_toplevel_unmap → context_find → wUnmanageWindow(destroyed=True)
so XDG toplevels are removed from scr->focused_window on client disconnect.

Smoke test: add Phase 40 check — grep "toplevel unmapped".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 06:34:15 +01:00
Levi Neely ca09635129 wayland: Phase 39 — wire toplevel map to wManageWindow
Guard all dpy==NULL crash sites reached from wManageWindow:
  - wNETWMGetPidForWindow (wmspec.c) — XGetWindowProperty with NULL dpy
  - wNETWMCheckClientHints (wmspec.c) — XGetWindowProperty
  - wNETWMCheckInitialClientState (wmspec.c) — XChangeProperty chain
  - getMWMHints (motif.c) — XInternAtom before NULL dpy check
  - wClientSetState (client.c) — XChangeProperty
  - wColormapInstallForWindow (colormap.c) — XGetWindowAttributes
  - wWindowSetKeyGrabs (window.c) — frame->core->window dereference

Wire handle_toplevel_map → wManageWindow(scr, view->id) so mapped
XDG toplevels appear in scr->focused_window.  Log success via
"wl_backend: wManageWindow succeeded id=0x%lx".

Smoke test: add Phase 39 check — grep "wManageWindow succeeded".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 06:23:23 +01:00
Levi Neely a486329b52 Wayland backend abstraction: WMBackend vtable (Phases 0–30)
Introduce a display-system-agnostic WMBackend vtable that routes all
display operations through function pointers, making the WM policy
layer independent of X11.  The X11 implementation is preserved in
src/backend/x11/ and behaviour is unchanged.

Key structural changes
──────────────────────
• src/backend/backend_types.h — backend-neutral type definitions:
    WNativeWindow, WKeyCode, WContextKey, WBackendScreen,
    WBackendEvent (+typed fields), WNormalHints, WWMHints,
    WNETWindowType, WHeadGeometry, WClientAttributes, WClientVisual,
    WSegment, WPoint, WM_KEY_* keysym constants, WA_* atom IDs,
    WKB_GROUP*_INDEX, WCUR_NONE

• src/backend/backend.h — WMBackend vtable (~100 function-pointer
    slots) covering: frame/context lifecycle, stacking, focus, grabs,
    pointer, keyboard, overlays, properties, ICCCM, EWMH/NETWM,
    monitors, screen setup, cursors, extensions, error handlers.
    No <X11/> headers remain in this file after Phase 30.

• src/backend/x11/ — X11 backend implementation:
    x11_backend.c  full vtable; all display calls confined here
    x11_props.c    WM_NORMAL_HINTS / WM_HINTS translation
    x11_event.c    XEvent → WBackendEvent translation
    x11_monitor.c  Xinerama / RandR monitor query

Policy files cleaned
────────────────────
All 47 files in WM_POLICY_CLEAN_FILES pass check-no-x11-policy
(no direct #include <X11/> anywhere).  X11 types that still appear
in policy structs (Visual*, Colormap, Window, Atom …) arrive only
transitively via WINGs.h; the vtable boundary itself is X11-free.

Tests
─────
• tests/smoke-test.sh — full Xvfb lifecycle test (PASS)
• tests/test_geom.c   — geometry / constraint unit tests
• tests/test_x11_event.c — WBackendEvent field extraction tests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 19:20:00 +01:00
Levi Neely fcee811b99 WindowMaker 0.96.0 upstream source 2026-03-26 15:38:49 +01:00