Commit Graph

75 Commits

Author SHA1 Message Date
Window Maker ef06f5ad8e wings: phases δ + ε — drop X11/Xlib.h from public WINGs headers
Major architectural milestone: WINGs Wayland-only files now have ZERO
transitive X11 header dependency at the preprocessor level (verified by
gcc -E grep: 0 mentions of X11/Xlib.h after preprocessing).

Changes:

  1. WUtil.h, WINGs.h: stop including <X11/Xlib.h>.  wnative.h provides
     forward declarations for Display, GC, XftDraw, XftFont; opaque
     pointer-only typedefs that don't conflict with Xlib.h's actual
     definitions when the X11 backend later includes it.

  2. WINGsP.h.in: stop including <X11/Xlib.h>, <X11/Xutil.h>.  Drop or
     re-route every X11-typed prototype:
       - W_HandleDNDClientMessage / W_DragSourceStateHandler /
         W_DragDestinationStoreEnterMsgInfo / etc.
         → moved to new private header WINGs/WINGsX11.h
       - W_HandleSelectionEvent → moved
       - W_LookupString / W_KeycodeToKeysym → moved
       - W_DndState typedef → moved (renamed to W_X11DndState)
       - XClientMessageEvent / XEvent / XKeyPressedEvent in prototypes
         → use void * in shared protos, cast in WINGsX11.h

  3. W_View struct: replaces XSetWindowAttributes by-value field with a
     small backend-neutral 'attribs' struct holding only the fields
     wmaker/WPrefs actually use (background_pixmap, background_pixel,
     border_pixel, colormap, cursor, override_redirect, save_under,
     event_mask, do_not_propagate_mask).  The X11 view backend
     translates to XSetWindowAttributes when calling XCreateWindow.
     XIC xic field replaced with void *xic.

  4. W_Color struct: replaces XColor by-value with a same-layout
     anonymous struct (pixel/red/green/blue/flags/pad).  X11 backend
     uses memcpy to populate from XColor.

  5. WINGs/WINGsX11.h (new): private header for X11 backend.  Includes
     <X11/Xlib.h>, declares X11-typed internal prototypes used by drag*,
     selection, IME, x11_backend, KeyboardShortcuts.  Required by every
     *_x11.c file plus a handful of cross-component callers
     (KeyboardShortcuts.c, MouseSettings.c, xmodifier.c, wmiv.c,
     x11_backend.c).

  6. wraster.h.in: gain a WRASTER_NO_XLIB compile-time switch.  When
     defined the header skips <X11/Xlib.h> and provides forward decls
     for Display/Visual/XImage/GC/XftFont/etc.  All Wayland-only WINGs
     files (wclient_wl.c, w*_wl.c) define WRASTER_NO_XLIB on line 1.

  7. wfont.c: adds W_ParseXLFDToFcPattern (a hand-written XLFD parser)
     replacing XftXlfdParse.  Removes <X11/Xft/Xft.h> include from the
     shared font dispatcher (and from wfontpanel.c too).

Verification:

  $ for f in WINGs/.libs/{*_wl.o,wclient_wl.o}; do
        nm $f | awk '$1=="U"{print $2}' | grep -cE '^X[A-Z][a-z]'
    done
  0 for every Wayland file

  $ for f in WINGs/.libs/*.o; do
        case $f in *_x11.o|*_wl.o|wclient_wl.o) continue;; esac
        c=$(nm $f | awk '$1=="U"{print $2}' | grep -cE '^X[A-Z][a-z]')
        [ $c -gt 0 ] && echo "$c $f"
    done
  (empty — no shared file leaks an X11 symbol either)

  $ gcc -E ... wclient_wl.c | grep -c X11/Xlib.h
  0 (no transitive Xlib include)

The library still pulls libX11 through the *_x11.c files when those are
linked in.  A future configure flag --disable-x11-backend will exclude
*_x11.c entirely; at that point libWINGs will be a pure-Wayland library
with zero libX11 dependency.
2026-05-24 11:37:18 +02:00
Window Maker 70d8a068e6 wings: route wtextfield XInternAtom through W_NativeInternAtom
Last X11 symbol leak in shared WINGs code: wtextfield.c's selection
request handler called XInternAtom directly to look up TEXT,
COMPOUND_TEXT, and TARGETS atoms.

Replaced with W_NativeInternAtom(scr, name) — implemented in
widgets_x11.c as a thin XInternAtom wrapper.  The Wayland-only
build (future) will provide a stub that returns WM_NATIVE_NONE,
making the requestHandler's downstream comparisons all fall through
to 'no match' cleanly.

Architectural verification: every WINGs shared object file (i.e.
not *_x11.o, not *_wl.o) now has ZERO undefined X11 symbols:

  $ for f in WINGs/.libs/*.o; do
      case $f in *_x11.o|*_wl.o) continue;; esac
      nm $f | awk '$1=="U" {print $2}' | grep -c '^X[A-Z][a-z]'
    done | sort -u
  0

Combined with the *_wl.c files already verified to have zero X11
deps, the WINGs library now cleanly partitions: shared code is
backend-neutral, X11 backend code lives in *_x11.c, Wayland backend
code lives in *_wl.c.  A --disable-x11-backend configure option can
now be added that drops *_x11.c from the build for pure-Wayland
WINGs apps.
2026-05-24 11:13:11 +02:00
Window Maker f7a7142889 wings: drop libXft from wfont.c / wfontpanel.c
The only Xft API used in shared font code was XftXlfdParse — used
to convert legacy X11 XLFD font names to fontconfig FcPatterns so
old WINGs config files keep working.

Replaced with a hand-written parser W_ParseXLFDToFcPattern (defined
in wfont.c, declared in WINGsP.h) that walks the 14 dash-separated
XLFD fields and pulls out family / weight / slant / pixelsize.
This is enough for every XLFD that wmaker / WPrefs has ever used
in practice (~14 different names across all defaults).

Both wfont.c and wfontpanel.c now use W_ParseXLFDToFcPattern, and
neither file includes <X11/Xft/Xft.h> any more.  libXft is now only
pulled in by the X11 font backend (wfont_x11.c), as it should be.

Build clean.  Wayland-only files still have zero X11 symbol
dependencies (verified via nm).
2026-05-24 11:09:39 +02:00
Window Maker 32377afed9 wings: rename wcolorpanel.c → wcolorpanel_x11.c
The color picker dialog uses XGetImage / XGrabPointer / XShape /
XPutImage / XCopyArea to implement the magnify-glass screen picker.
Wayland intentionally does not allow reading pixels from other
windows (security), so the screen-pick feature has no Wayland
equivalent.  The whole file is therefore X11-only.

A future commit will provide a stub that returns a wwarning when
WMShowColorPanel is called in Wayland mode.
2026-05-24 11:04:33 +02:00
Window Maker d2b11eec4c wings: phase γ — rename X11-only files to *_x11.c
Mechanical rename to make architectural intent visible:

  dragsource.c       → dragsource_x11.c
  dragdestination.c  → dragdestination_x11.c
  selection.c        → selection_x11.c
  winputmethod.c     → winputmethod_x11.c
  wballoon.c         → wballoon_x11.c
  wappresource.c     → wappresource_x11.c

Each is essentially a wrapper around X11 features (XDND, X11
selection, XIM, XShape, X11 WM hints) with no Wayland equivalent
yet.  These files keep providing their public WINGs API symbols
unchanged, so build+link is identical at this point.

A future commit will add Wayland counterparts (or no-op stubs) and
wire a configure option that conditionally excludes *_x11.c when
the build is Wayland-client-only.  Doing this now would force a
choice between linkable but Wayland-broken (no stubs) or partial
double-implementation (some functions stubbed); the right answer
needs vtable dispatchers in shared *.c files for each, which is
the next round of surgery.
2026-05-24 11:01:50 +02:00
Window Maker 9545320f9c wings: phase γ (dragcommon) — split X11 XDND wire code into _x11
dragcommon.c now contains only backend-neutral helpers
(WMCreateDragOperationArray/Item, accessors, W_FreeViewXdndPart).

dragcommon_x11.c is new and owns:
  - W_OperationToAction/W_ActionToOperation atom translation
  - windowExists / handleNoWindowXError probe
  - W_SendDnDClientMessage XSendEvent path
  - W_HandleDNDClientMessage XDND wire dispatch
  - handleLeaveMessage

These touch scr->xdnd*Atom fields and call XSendEvent / XGetAtomName /
XSetErrorHandler etc. — strictly X11.  Wayland DnD will be added later
through wl_data_device.

dragsource.c and dragdestination.c still contain Xlib calls; those
splits come next.
2026-05-24 10:58:22 +02:00
Window Maker b5c46870aa wings: phase γ (widgets.c) — split Xlib calls into widgets_x11.c
WINGs/widgets.c is now Xlib-call-free.  All Xlib code moved to a new
WINGs/widgets_x11.c:

  * W_X11PlatformInit (~178 lines): GC creation, modifier-mask probe,
    cut-buffer setup, cursor/atom/IM init.  Hooked from
    W_ViewBackendX11.platform_init exactly as before.
  * W_X11OpenDisplay: XOpenDisplay + WMCreateSimpleApplicationScreen.
    WMOpenScreen() in widgets.c now calls this for the X11 path.

Dead code removed: the static renderPixmap that nothing called and
that was the last X11-direct-draw path in widgets.c.

X11 includes dropped from widgets.c.  Display * typedef still resolves
through WINGsP.h transitively until phase ε removes that.

Build verified clean, wmaker still links and runs.
2026-05-24 10:55:30 +02:00
Window Maker 0f839a9c6d wings: phase β — rename X11 typedefs in shared/Wayland code
Sed pass restricted to files outside src/backend/x11 and outside
*_x11.c — i.e. all code that should not depend on X11 typedefs.

  Window     → WNativeWindow      (existing typedef in WMEvent.h)
  Atom       → WMNativeAtom
  Pixmap     → WMNativePixmap
  Cursor     → WMNativeCursor
  Drawable   → WMDrawable          (existing typedef)
  KeySym     → WMNativeKeysym
  Colormap   → WMNativeColormap

X11 backend files keep using the original Xlib type names because
they make Xlib API calls that take those types.  All typedefs are
ultimately 'unsigned long' so values pass through opaquely between
shared code and the backend.

Public WINGs API affected: WMSelectionCallback, WMSelectionProcs,
and a handful of widget signatures that took Atom/Window arguments
now take WMNativeAtom/WNativeWindow.  Source-compatible at the
binary level; consumers must rebuild.

Time and XID typedefs left for a follow-up — both are heavily used
in field/variable names that need careful auditing.  Display* and
GC stay in W_Screen for now; phase δ moves them into an X11-only
sub-struct.
2026-05-24 10:49:47 +02:00
Window Maker 1a49d6b857 wings: phase α.3 — rename X11 enum/macro values to WM_*
Mass rename of X11 enum values used in shared/Wayland code, with the
numeric values preserved so the wire layout of WMEvent fields and
the X11-backend translation tables remain unchanged.

  NotifyNormal/Grab/Ungrab/WhileGrabbed     → WM_NOTIFY_*
  NotifyAncestor/Virtual/Inferior/Nonlinear/
    NonlinearVirtual/Pointer/PointerRoot/
    DetailNone                              → WM_NOTIFY_*
  PropertyNewValue/Delete                   → WM_PROPERTY_*
  MappingModifier/Keyboard/Pointer          → WM_MAPPING_*
  VisibilityUnobscured/PartiallyObscured/
    FullyObscured                           → WM_VISIBILITY_*
  GrabModeAsync/Sync, GrabSuccess           → WM_GRAB_*
  RevertToParent/PointerRoot/None           → WM_REVERT_TO_*
  CurrentTime                               → WM_CURRENT_TIME
  None                                      → WM_NATIVE_NONE

The 'None' rename was done with conservative regex passes restricted
to clear C-context patterns (= None;, , None,, !=None, etc.) so that
'"None"' string literals in defaults and XPM 'c None' colour names
are preserved untouched.  Comments containing the English word 'None'
are also left alone.  X11 backend files that legitimately use the
X11 macros (Xlib calls returning None, etc.) are unchanged.

Build clean across WINGs, src, WPrefs.app.
2026-05-24 10:47:37 +02:00
Window Maker 82e3c3b65d wings: phase α.2 — rename X11 event masks to WM_EVMASK_*
Sed pass.  KeyPressMask, KeyReleaseMask, ButtonPressMask,
ButtonReleaseMask, EnterWindowMask, LeaveWindowMask,
PointerMotionMask, PointerMotionHintMask, Button{1..5}MotionMask,
ButtonMotionMask, KeymapStateMask, ExposureMask,
VisibilityChangeMask, StructureNotifyMask, ResizeRedirectMask,
SubstructureNotifyMask, SubstructureRedirectMask, FocusChangeMask,
PropertyChangeMask, ColormapChangeMask all renamed to the
corresponding WM_EVMASK_* names defined in wnative.h.

Numeric values still match the X11 layout, so wevent_x11.c's
matching tables and any code that masks bits keep working
unchanged.  Build clean across WINGs/, src/, WPrefs.app/.
2026-05-24 10:43:23 +02:00
Window Maker 5f65867974 wings: introduce wnative.h; phase α.1 (modifier/button masks)
WINGs API surgery, step 1.

New public header WINGs/WINGs/wnative.h declares WINGs-native types
and constants with no X11 header dependency:

  - WMNativePixmap/Atom/Cursor/Keysym/Time/XID/Colormap/Bool typedefs
    (all 'unsigned long' — compatible with the existing wire ABI).
  - WM_MOD_SHIFT/LOCK/CONTROL/MOD{1..5} modifier mask bits.
  - WM_BUTTON{1..5}_MASK pointer button mask bits.
  - WM_ANY_MODIFIER/WM_ANY_BUTTON sentinels.
  - WM_EVMASK_* event-mask bits (forthcoming patches).
  - WM_NOTIFY_* crossing modes/details.
  - WM_PROPERTY_* / WM_MAPPING_* / WM_VISIBILITY_* / WM_GRAB_* /
    WM_REVERT_TO_* / WM_CURRENT_TIME / WM_NATIVE_NONE.

Numeric values intentionally match X11 layout for binary
compatibility with WMEvent fields (which were defined that way
originally).  The architectural property that matters is that NONE
of the symbol *names* below are X11 macros — they belong to WINGs
and are defined without any X11 header.

WMEvent.h, WUtil.h, WINGs.h now #include <WINGs/wnative.h> so every
WINGs consumer picks up the new constants.  X11 headers are still
included from the public WINGs headers; phase ε will drop them.

Phase α.1 — first sed pass:

  ShiftMask     → WM_MOD_SHIFT
  ControlMask   → WM_MOD_CONTROL
  LockMask      → WM_MOD_LOCK
  Mod{1..5}Mask → WM_MOD_MOD{1..5}
  Button{1..5}Mask → WM_BUTTON{1..5}_MASK
  AnyModifier   → WM_ANY_MODIFIER
  AnyButton     → WM_ANY_BUTTON

Applied across WINGs/, src/, WPrefs.app/ via sed with word
boundaries.  Build verified clean; binary identical in size,
re-linked successfully.
2026-05-24 10:42:04 +02:00
Window Maker da3bf4c096 wings(wayland-client): wl_pointer + wl_keyboard input dispatch
Task 5.

wclient_wl.c subscribes to wl_seat.capabilities.  On POINTER capability
it binds wl_pointer with a listener that translates enter/leave/motion/
button events into WMEvent (WME_ENTER, WME_LEAVE, WME_MOTION,
WME_BUTTON_PRESS/RELEASE).  Linux evdev button codes (BTN_LEFT, etc.)
map to X-style numbers (1, 2, 3, 8, 9).  Pointer focus is tracked per
wl_surface and resolved to a top-level W_View via wlc_top_for_surface.

On KEYBOARD capability it binds wl_keyboard.  The keymap event mmaps
the fd, compiles via xkb_keymap_new_from_string, and stashes the result
in WLClientCtx (xkb_keymap + xkb_state).  Subsequent key events use
xkb_state_key_get_one_sym for the keysym and xkb_state_key_get_utf8 for
text — these populate WMEKey.{keycode, keysym, utf8, utf8_len}.
Modifiers update xkb_state and a cached X-style mod mask
(ShiftMask, ControlMask, Mod1Mask, Mod4Mask) used in WMEKey.state and
WMEButton.state.

Focus enter/leave on the keyboard side dispatches WME_FOCUS_IN /
WME_FOCUS_OUT so WINGs widgets get focus tracking.

Events flow via W_WL_EnqueueEvent, the same ring buffer wevent_wl.c
already drains for the compositor side — no separate event-pump
required.  Axis (scroll) events are stubbed out for now and will be
synthesized as button 4/5 in a follow-up.
2026-05-24 10:27:56 +02:00
Window Maker 97b2d03a34 wings(wayland-client): wl_shm buffers + xdg_toplevel surfaces
Tasks 3 + 4.

wclient_wl.c grows a memfd+mmap-backed wl_shm buffer allocator that
wraps the mapped region as a pixman_image_t.  Painting into the pixman
image writes directly into the buffer the compositor will read on
commit, so no copy is needed.  wl_buffer.release marks the buffer as
released for future reuse (currently we just realloc on resize, so the
flag is informational).

Each top-level W_View now acquires a WLClientToplevel with a wl_surface,
xdg_surface, and xdg_toplevel.  The first xdg_surface.configure event
acks and attaches the buffer; subsequent configures with non-zero
dimensions realloc the backing.  xdg_toplevel.close sets a want_close
flag (closure event synthesis is in the next pass).

wview_wl.c now calls three function-pointer hooks for top-level views:

  W_WLClientToplevelRealizeFn(view, w, h)  -> pixman_image_t *
  W_WLClientToplevelResizeFn(view, w, h)
  W_WLClientToplevelDestroyFn(view)

When the hooks are NULL (compositor-internal mode or X11), wview_wl.c
falls back to plain pixman_image_create_bits — preserving every
existing behaviour.  When wclient_wl.c installs them, the same paints
end up on a wl_shm buffer attached to a real Wayland surface.

W_ViewCommitBackingFn and W_ViewDestroyBackingFn are also installed by
W_WLClientInit so wview_wl.c's existing redisplay/destroy plumbing
drives wl_surface_attach / damage / commit / surface destruction.

No input handling yet; that's task 5.
2026-05-24 10:25:29 +02:00
Window Maker 12ae1e48fb gitignore: WINGs scanner-generated xdg-shell, drop stray +cmd
The previous commit accidentally swept in a personal scratch file (+cmd)
and the auto-generated xdg-shell-protocol.c.  Both are now ignored.
Generated files come from $(WAYLAND_SCANNER) at build time.
2026-05-24 10:20:42 +02:00
Window Maker 182617513e wings(wayland-client): build system + connection skeleton
Task 1 + 2 of the WINGs Wayland-client backend.

Adds optional --enable-wayland-client (default auto) which depends on
wayland-client, xkbcommon, wayland-protocols, and wayland-scanner.
configure.ac probes for these and exposes WAYLAND_CLIENT_CFLAGS/LIBS
plus the protocols data dir and scanner path.

WINGs/Makefile.am wires a wayland-scanner rule that generates
xdg-shell-{protocol,client-protocol}.{c,h} at build time and links
libWINGs against wayland-client + xkbcommon when enabled.

WINGs/wclient_wl.c is the new file.  It self-stubs when the feature
is disabled.  When enabled it provides:

  W_WLClientInit(scrPtr, display)
    Connects via wl_display_connect, registers a wl_registry listener,
    binds wl_compositor/wl_shm/wl_seat/xdg_wm_base, creates an xkb_context,
    and hooks the libwayland event pump into the existing
    W_EventBackendWL via W_WL_SetLoopDispatch().  This lets the existing
    ring-buffer event mechanism keep working unchanged: the ring is fed
    by client-side wl_pointer/wl_keyboard listeners (next task) and
    drained by WMNextEvent / WMMaskEvent / waitForEvent.

  W_WLClientShutdown(scrPtr)
    Tears down all bound globals and disconnects the wl_display.

No surfaces / buffers / input dispatch yet — those come in tasks 3-5.
Build verified clean, wmaker still links and runs as before.
2026-05-24 10:20:01 +02:00
Window Maker a789abc09f arch: eliminate last _x11_raw escape from src/ (winspector)
The Window Inspector's 'select window' feature grabbed the pointer on
the root window then read XEvent.xbutton.subwindow to learn which
window was clicked.  This was the last access to _x11_raw in shared
src/ code.

Add a subwindow field to WMEButton.  The X11 backend's WMEvent
translation populates it from xbutton.subwindow.  The Wayland backend
leaves it 0 (Wayland has no equivalent grab semantic — the click
reports the actual frame as event.window directly).  winspector.c
now uses event.u.button.subwindow with fallback to
event.u.button.window, working on both backends.

Net: src/ has zero _x11_raw escapes from shared code.  Remaining
references are inside the X11 backend (legitimately consuming the
field set by its own event translator).
2026-05-24 08:40:38 +02:00
Ollie a438713b92 WINGs/wview_wl: implement internal DnD for Wayland
Implement wl_drag_begin as a simple internal drag-and-drop state machine
for WINGs-to-WINGs drag operations (color wells, text widgets).

On button press, waits for motion to confirm drag intent, then enters
a drag loop tracking the cursor. On release, finds the view under the
cursor and if it has drag destination procs + matching types, fetches
data from the source and calls performDragOperation on the destination.

This handles same-process DnD without needing wl_data_device protocol.
2026-05-23 19:07:54 +02:00
Ollie 5558a1edf0 WINGs/wfont_wl: remove stale text comparison in wl_text_width
The optimization that skipped pango_layout_set_text when the text
matched the previous layout content used pango_layout_get_text()
which returns an internal pointer. This pointer comparison with
arbitrary input text could read freed memory or trigger heap
corruption in Pango internals when the layout state was stale.

Always call pango_layout_set_text unconditionally. The cost is
negligible (Pango internally short-circuits if text is identical).
2026-05-23 16:41:44 +02:00
Ollie 3acf2f6b2b WINGs: implement Wayland selection fetch (middle-click paste)
Add selection_fetch vtable slot for synchronous selection retrieval.
On Wayland, WMRequestSelection uses this to fetch clipboard/primary
selection data directly (via W_ClipboardFetchFn -> seat pipe read)
and calls the callback immediately. On X11, the async path
(selection_request -> SelectionNotify event) is unchanged.

This makes middle-click paste work in WINGs text widgets on Wayland.
2026-05-23 16:37:58 +02:00
Ollie 7077e00d12 WINGs: remove dead X11 code from wtext.c and wmisc.c
- wtext.c: remove unused XEvent variable
- wmisc.c: remove dead #ifndef DOUBLE_BUFFER branches (XClearWindow)
  DOUBLE_BUFFER is always defined; these were unreachable.
2026-05-23 16:19:48 +02:00
Ollie 1ab108f7aa WINGs/wevent: fix NULL toplevel crash on Wayland expose dispatch
W_TopLevelOfView returns NULL for views without a topLevel ancestor
(e.g. geometry display widgets parented directly to root). On X11 this
never triggered because expose events only arrived for mapped windows
with proper widget hierarchy. On Wayland, wl_redisplay synthesizes
expose events for any view, exposing the NULL case.

Fix: fall back to the view itself when no topLevel ancestor exists.
2026-05-23 16:17:18 +02:00
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
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
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
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
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
lkn d29f2a29c9 wayland: fix close/iconify buttons and miniwindow rendering
Three bugs fixed:

1. Close and iconify buttons broken after frame rendering model change
   Buttons are composited into the titlebar buffer, so their scene_buf
   nodes carry no committed buffer and are invisible to wlr_scene_node_at.
   frame_buf_at() returned the titlebar fb for all button-area clicks,
   routing them to titlebarMouseDown instead of buttonMouseDown.

   Fix: add frame_buf_button_at() -- coordinate walk of frame_list entries
   with scene_buf->buffer == NULL -- and frame_buf_hit() which tries button
   resolution first then falls back to the scene graph. Replace all
   frame_buf_at() calls in button and motion handlers with frame_buf_hit().
   Also emit synthetic WME_LEAVE/WME_ENTER events on sub-window boundary
   crossings so buttonMouseDown's press-track loop works correctly.

2. Iconify crash (SIGSEGV in update_icon_title)
   WMDrawString() was passed icon->core->window (a frame_buf synthetic ID,
   0x10000000+) as the drawable. wl_font_resolve_drawable() only recognised
   WINGs view IDs (0x20000000+), so it cast the frame_buf ID directly as a
   pixman_image_t* -- wild pointer -- SIGSEGV.

   Fix: add W_RegisterBacking()/W_UnregisterBacking() to wview_wl.c.
   Register each frame_buf's pixman image in the backing table on creation
   and unregister on destroy. Extend the ID range check in wfont_wl.c and
   wrender_wl.c from 0x20000000 down to 0x10000000 so frame_buf IDs resolve
   correctly via W_GetViewBacking().

3. Resizebar visible after iconify + miniwindow not rendering
   wl_window_unmap() disabled fb->scene_buf->node individually, but a
   subsequent wl_frame_paint() could re-enable and re-commit it while the
   window was still iconified.

   Fix: for top-level frames, disable fb->tree->node -- hides the entire
   scene tree (frame buffer, titlebar, resizebar, client surface) atomically.
   Symmetric enable in wl_window_map().

   Miniwindow icons were invisible: icon_paint was a noop so the frame_buf
   image was never committed to the scene graph. Add wl_icon_paint() mirroring
   wl_appicon_paint(): tile + file_image composite + title text, committed
   via wlr_scene_buffer_set_buffer(). Wire into wIconPaint() in icon.c so
   the backend finalises the surface after policy-layer setup.
2026-05-15 09:49:06 +02:00
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 95b0b8ee7c WINGs/wevent: remove _x11_raw from WMHandleEvent dispatch path
WMHandleEvent is the middle layer — it must not contain any
backend-specific code. Move view lookup to _view_target field
set by each event backend during fetch. Move XRefreshKeyboardMapping
and XFilterEvent into x11_fetch. Selection and DND handling removed
from middle layer (handled by extraEventHandler in the WM layer).

The _x11_raw field remains in WMEvent for now (used by src/event.c
and other WM-layer code that still needs the raw XEvent), but the
middle layer no longer touches it.
2026-05-14 20:24:05 +02:00
Levi Neely ed2f825ca0 WINGs/wfont_wl: fix text y-offset in draw_image_string
Don't add ascent offset — pango_ft2_render_layout renders from the
top of the layout, not from the baseline. The extra ascent was
pushing text below the visible area of the text field.
2026-05-14 19:12:36 +02:00
Levi Neely 213f5a6528 WINGs: move updateDisabledMask to render backend vtable
Add create_disabled_mask to W_RenderBackend. X11 backend uses
XCreatePixmap + stippled GC fill. Wayland backend creates a
pixman a8 checkerboard mask. Middle layer (wbutton.c) dispatches
through vtable — zero X11 code remains.
2026-05-14 17:58:33 +02:00
Levi Neely 2910e73878 WINGs/widgets: move makePixmap calls to common init
Widget pixmaps (checkbox, radio, arrows, etc.) were created inside
W_X11PlatformInit, so they were NULL in Wayland mode. Since
makePixmap now uses RImage+RConvertImage (backend-neutral), move
all makePixmap calls to common init after platform_init.
2026-05-14 17:11:31 +02:00
Levi Neely c26a3bec30 WINGs/widgets: rewrite makePixmap to use RImage + RConvertImage
Replace X11 XDrawPoint pixel rendering with RImage construction
and RConvertImage, which dispatches through the backend vtable.
Fixes checkbox/radio button images not appearing in Wayland mode.
2026-05-14 16:59:26 +02:00
Levi Neely fdf0956c02 WINGs/wview_wl: re-composite top-level after children draw
The top-level was composited into root before children had painted
into its backing image, resulting in a blank dialog. Now we
composite the top-level a second time after wl_map_subviews so
the final image includes all child content.
2026-05-14 16:56:29 +02:00
Levi Neely 05d819bf15 WINGs: add flush vtable entry, remove XFlush from wbutton.c
Add flush() to W_ViewBackend. X11 backend calls XFlush,
Wayland backend is a no-op (compositing happens at frame
boundaries). wbutton.c WMPerformButtonClick now uses the vtable.
2026-05-14 16:51:03 +02:00
Levi Neely bb420ef536 WINGs/wpanel: use WMEvent keysym instead of XLookupString
All three handleKeyPress functions in wpanel.c were dereferencing
event->_x11_raw (NULL in Wayland mode) to call XLookupString.
Use event->u.key.keysym directly — it's already translated by
the backend.
2026-05-14 16:47:07 +02:00
Levi Neely 4f462357e1 WINGs/wframe: remove X11 GC/region clipping from paintFrame
Replace XClearWindow with render backend fill_rect.
Remove X11 region-based clip masking around relief drawing —
the title is drawn on top afterward, making the clip unnecessary.
Eliminates WMColorGC/XCreateGC crash in Wayland mode.
2026-05-14 16:44:29 +02:00
Levi Neely 3edf25e0b4 fix build: add missing WINGs vtable fields, fix double-free and linker errors
- Add selection_acquire, selection_release, platform_init to
  W_ViewBackend struct (were used but not declared).
- Add lookup_string to W_FontBackend struct (same issue).
- Guard selection_acquire call with NULL check in selection.c.
- Remove pixman_image_unref in wl_frame_configure resize path —
  wlroots manages the buffer lifecycle via scene refcounting.
  LSan confirms no leak.
- Remove #include of wmspec.c/xdnd.c/xmodifier.c from x11_backend.c
  — they are already compiled as standalone objects, causing
  multiple-definition linker errors on clean builds.
2026-05-14 16:24:59 +02:00