Commit Graph

432 Commits

Author SHA1 Message Date
Ollie 5d456d5b95 selection: fix crash on Wayland when W_NativeInternAtom called with NULL display 2026-05-28 21:18:18 +02:00
Ollie 367b488e47 selection: push data to compositor on acquire for Wayland (select→paste) 2026-05-28 21:04:24 +02:00
Ollie 784b4c89ce balloon: fix leave tracking + multi-line height in wl_balloon_draw 2026-05-28 20:37:51 +02:00
Ollie adf79141b2 dnd: cross-client motion/drop handler with MIME type routing 2026-05-28 20:29:26 +02:00
Ollie b278d6491d roadmap: mark wcolorpanel complete 2026-05-28 19:55:55 +02:00
Ollie 14b660ff50 colorpanel: split into wcolorpanel.c + _x11.c + _wl.c (412->0 X11 calls) 2026-05-28 19:55:41 +02:00
Ollie 39b63a8184 DND: compositor-internal drag icon overlay + cursor feedback + cross-client wiring 2026-05-28 19:35:41 +02:00
lkn e1eaf17925 docs: replace planning docs with forward-looking ROADMAP.md
Remove completed planning documents (WAYLAND_ROADMAP.md, ACTION_PLAN.md,
ACTION_PLAN_PROMPTS.md). Update ARCHITECTURE.md and BACKEND_ABSTRACTION.md
with current file sizes and completion status. Add ROADMAP.md covering
remaining work prioritized for daily-driver use.
2026-05-26 15:55:25 +02:00
Window Maker db8cd0ea34 WINGs: fix WPrefs not launching in X11 mode
Three issues prevented WPrefs from being managed by wmaker in X11:

1. W_X11OpenDisplay: XOpenDisplay("") fails; treat empty string as NULL
   so it falls back to DISPLAY env var.

2. wevent_x11.c/wevent.c: MapRequest and ConfigureRequest events must
   bypass WINGs view lookup (both _view_target in x11_fetch and
   W_GetViewForWindow in WMHandleEvent) to reach DispatchEvent via
   extraEventHandler.

3. wview_x11.c: x11_create_root must use RootWindow() not
   scr->rootWin (which may be an intermediate window created by
   RCreateContext for non-default visuals). Otherwise toplevel
   WINGs windows are created as children of the wrong parent and
   their MapRequest never reaches the WM.
2026-05-25 18:08:09 +02:00
Window Maker 8700f9a955 WINGs: fix XOpenDisplay with empty string failing for WPrefs
WPrefs.app/main.c defaults display_name to "" (empty string).
W_X11OpenDisplay passed this directly to XOpenDisplay, but
XOpenDisplay("") is not equivalent to XOpenDisplay(NULL) — the
former fails while the latter uses the DISPLAY environment variable.

Treat empty display string as NULL so XOpenDisplay falls back to
the environment variable.

Also remove debug traces from event.c and x11_backend.c.
2026-05-25 17:27:48 +02:00
Window Maker 03fe6771cc WINGs/wevent_x11: fix MapRequest/ConfigureRequest not reaching WM dispatch
SubstructureRedirect events (MapRequest, ConfigureRequest) are delivered
to the root window. Since the root window has a WINGs view registered
(the WMScreen root view), W_GetViewForXWindow resolves it and
WMHandleEvent dispatches to the view handlers instead of falling through
to extraEventHandler (DispatchEvent).

This caused WINGs-based apps like WPrefs to never have their windows
managed by the WM - the MapRequest was silently consumed.

Fix: skip the view lookup for MapRequest and ConfigureRequest events so
they always reach DispatchEvent via extraEventHandler.
2026-05-25 17:17:03 +02:00
Window Maker b714cb783d x11: fix menu rendering, balloon tooltips, clip arrows, and event handling
Menu entry painting:
- Add drawFrame() calls for 3D beveled entries (WTEX_SOLID)
- Add menu_text_clearance to text Y positioning
- Add left-side indicator drawing (radio/check/snap pixmaps)
- Add indicator X offset (MENU_INDICATOR_SPACE)
- Fix disabled+selected text color
- Fix texture-aware background clearing
- Add cascade arrow for submenu entries

Balloon tooltips:
- Implement x11_balloon_show() with text and mini-preview rendering
- Previously was a no-op stub

Clip arrows:
- Draw workspace-switching triangles on clip icon
- Previously stubbed out

Event handling:
- Add MapRequest, ConfigureRequest, ReparentNotify translation to
  xev_to_wme() in WINGs/wevent_x11.c
- These WM-critical events were silently dropped, preventing new X
  clients (e.g. xterm) from being managed
2026-05-25 17:04:30 +02:00
Window Maker f878117013 WINGs: deliver maskless events (selection, mapping) to all handlers
Selection and mapping events have mask 0 in the type table (matching
X11 semantics where they bypass event masks). Change the dispatch
check to deliver events with mask==0 to all registered handlers,
so these events are not silently dropped.
2026-05-25 13:39:18 +02:00
Window Maker 1954fa2a12 WINGs: fix WME_CLIENT_MESSAGE mask so close events reach handlers
The wmeMaskForType table had WME_CLIENT_MESSAGE mapped to 0, so
WMHandleEvent never dispatched client messages to registered handlers.
The window close handler (registered with ClientMessageMask) was never
called. Set the correct mask so the deleteWindow protocol works.
2026-05-25 13:37:32 +02:00
Window Maker d522fc87c5 wayland: use non-blocking read_events for client dispatch
The poll-based wlclient_dispatch with timeout 0 missed events that
were already buffered. Use prepare_read/read_events/dispatch_pending
which reads whatever is available on the socket without polling.
2026-05-25 13:33:30 +02:00
Window Maker fe2ec1fb9e wayland: pump client display in main loop for close button support
In-process WINGs clients have their own wl_display connection that
needs to be dispatched for xdg_toplevel.close to be received. Add
W_WLClientDispatchPending() and call it each main loop iteration
so protocol events reach the client-side handlers promptly.
2026-05-25 13:32:59 +02:00
Window Maker 94157394d7 wayland: fix close button for WINGs clients by flushing after send_close 2026-05-25 13:31:38 +02:00
Window Maker 36c2396130 WINGs/wayland: defer redisplay during W_RealizeView to prevent crash
During W_RealizeView, child views with mapWhenRealized triggered
wl_map which called wl_redisplay on the toplevel. This ran expose
handlers on a partially-realized widget tree, causing backing image
corruption from resizes during redisplay.

Fix: track realization depth with W_WL_Realizing counter. wl_map
skips redisplay when realization is in progress. After the outermost
W_RealizeView completes, trigger a single redisplay of the toplevel
to paint everything correctly.
2026-05-25 13:29:46 +02:00
Window Maker 6e18e1fe0d WINGs/wayland: use backing image dimensions for fill_rectangles
The fill_rectangles call used view->size which can exceed the backing
image dimensions when a view is resized during realization without its
backing being reallocated. This wrote past the allocated buffer,
corrupting the heap and causing later pixman_image_composite32 crashes.
Use pixman_image_get_width/height of the actual backing instead.
2026-05-25 13:22:41 +02:00
Window Maker 7a93b1d389 WINGs/wayland: remove diagnostic fprintf, keep bounds clipping
Remove the verbose COMPOSITE fprintf and BAD composite warning that
were used for debugging. Keep the source/destination bounds clipping
as it correctly handles the case where view->size diverges from the
backing image dimensions during realization.
2026-05-25 13:21:14 +02:00
Window Maker ef98cc3c64 WINGs/wayland: prevent infinite redisplay recursion during resize
The font prefs panel crashed because wl_resize called wl_redisplay
while already inside a redisplay. This caused expose handlers to
trigger more resizes, creating unbounded recursion and memory growth
(backing images growing to 1024+ pixels wide). Skip the redisplay
from wl_resize when wl_redisplay_depth > 0 — the ongoing parent
redisplay will composite the resized child at its new size.
2026-05-25 13:19:39 +02:00
Window Maker 4a6c5330a3 WINGs/wayland: also clip composite to destination bounds and check data
The previous source-only clamp was insufficient. Also check that both
src and dst have non-NULL pixel data, and clip the composite region to
the destination image dimensions to prevent out-of-bounds writes.
2026-05-25 13:12:58 +02:00
Window Maker 53b0b65b3b WINGs/wayland: clamp pixman composite to actual backing image size
During W_RealizeView the WME_EXPOSE handler can trigger child resizes
that make view->size exceed the backing image dimensions. Clamp the
composite width/height to the source image actual size to prevent
out-of-bounds reads in pixman_image_composite32.
2026-05-25 13:12:17 +02:00
Window Maker 9c83db6977 WINGs/wayland: guard pixman composite against zero-sized views
Font prefs panel crashed in pixman_image_composite32 during W_MapView
because a child view had zero width/height. Skip compositing for
zero-sized views.
2026-05-25 13:09:59 +02:00
Window Maker 2aeb76971a WINGs: guard WMRegisterViewForDraggedTypes against NULL X display
In Wayland mode the X11 display is NULL. WMCreateColorWell calls
WMRegisterViewForDraggedTypes which calls XInternAtom, crashing.
Bail early when display is NULL since X11 DnD is not available.
2026-05-25 13:07:55 +02:00
Window Maker d5bc733842 wayland: directly synthesize close event for in-process WINGs clients
The xdg_toplevel.close protocol message requires the client to dispatch
its wl_display, but in-process WINGs clients may not do so promptly.
Directly enqueue the WME_CLIENT_MESSAGE/deleteWindowAtom event from
wl_client_close so the closeAction fires on the next WINGs event drain.
2026-05-25 13:05:42 +02:00
Window Maker e2f73e90e5 WINGs/wayland: handle xdg_toplevel close by synthesizing WM_DELETE_WINDOW
The close button press from the compositor sends xdg_toplevel.close,
but the handler only set a flag without notifying the WINGs event
system. Synthesize a WME_CLIENT_MESSAGE with deleteWindowAtom so
the window closeAction callback fires and the app shuts down
gracefully.
2026-05-25 13:03:31 +02:00
Window Maker 4442380d50 wayland: derive menu colors from appearance preferences
Menu background colors were hardcoded. Now uses:
- scr->select_color for selected item background
- scr->menu_item_texture->normal for unselected background
- scr->menu_item_texture->dim/light/dark for cascade arrow

Text colors already used scr->select_text_color, mtext_color, dtext_color.
2026-05-25 13:01:14 +02:00
Window Maker 40295223c6 wayland: match X11 cascade arrow style with 3D shaded lines
Replace the filled triangle with three lines matching the upstream X11
implementation: a dim top edge, light bottom edge, and dark left edge,
forming a 3D right-pointing triangle indicator for submenu entries.
2026-05-25 12:59:35 +02:00
Window Maker 95c4101ed3 wayland: fix submenu cascade arrow to point right
The triangle was drawn with increasing width from left to right,
making it point left. Reverse the vertical span so the widest part
is on the left and it tapers to a point on the right.
2026-05-25 12:58:39 +02:00
Window Maker b79f699a35 wayland: call W_CheckTimerHandlers in event loop for workspace fade
WINGs timers (used by workspace name fade animation) were never firing
because the compositor event loop never called W_CheckTimerHandlers.
This function is normally invoked by WMNextEvent, but the compositor
uses a custom loop. Add the call so timers fire each iteration.
2026-05-25 12:57:12 +02:00
Window Maker 7ea6a7ac88 wayland: workspace name badge with transparent background and fade
The workspace name display was rendering with an opaque black background
and never fading out. Fix by:
- Using transparent (alpha=0) background instead of black
- Returning RGBA images from badge_render and badge_get_background
- Preserving alpha channel in badge_update instead of hardcoding 0xFF

This allows the fade animation (RCombineImagesWithOpaqueness) to work
correctly, blending text with decreasing opacity over a transparent
background until the badge disappears.
2026-05-25 12:55:38 +02:00
Window Maker 172e226947 wayland: fix NULL dereference in wl_pointer_query_full
wWorkspaceForceChange passes NULL for root_x/root_y when it only needs
the child window. Add NULL checks before dereferencing these pointers.
2026-05-25 12:51:47 +02:00
Window Maker 5e60df9f3a WPrefs: redisplay toplevel for icon position preview
Redisplaying posVF alone leaves stale content in the parent backing.
Redisplay the entire toplevel window to ensure a clean full repaint.
2026-05-25 12:49:48 +02:00
Window Maker f1ded24294 WPrefs/wayland: fix icon preview one-click-behind with extra dispatch
WINGs button callbacks trigger wl_redisplay which commits the client
surface, but the compositor only processes that commit on the next
wl_event_loop_dispatch. Add a zero-timeout dispatch after handling
WINGs events so client commits are processed immediately, making
the next scheduled frame render the updated content.

Also revert posF redisplay back to posVF (posF caused gray flash).
2026-05-25 12:49:00 +02:00
Window Maker 04e84310df WPrefs: redisplay entire posF frame for icon position preview update
Redisplaying just posVF was insufficient; redisplay the entire posF
parent frame to ensure the icon position indicator renders at its
new location immediately after a button click.
2026-05-25 12:47:07 +02:00
Window Maker 69db74b3a6 wayland: fix frame pacing regression, schedule frame after dispatch
The extra wlr_scene_output_commit broke frame pacing in nested mode by
consuming the host frame callback. Instead, move wlr_output_schedule_frame
to after wl_event_loop_dispatch so client commits processed during
dispatch are rendered on the next frame event.
2026-05-25 12:45:25 +02:00
Window Maker ee434b024a wayland: commit scene after dispatch to fix one-frame-behind rendering
Client surface commits arrive during wl_event_loop_dispatch but may be
processed after the frame event has already rendered the old state. Add
an additional wlr_scene_output_commit after dispatch to immediately
pick up any new client content, fixing the one-interaction-behind
visual update issue in WINGs clients like WPrefs.
2026-05-25 12:43:55 +02:00
Window Maker 7982e8155d WINGs/wayland: flush display after surface commit for immediate updates
Without an explicit wl_display_flush after wl_surface_commit, protocol
requests were buffered until the next event loop iteration. This caused
visual updates (like the icon position preview in WPrefs) to appear one
interaction behind.
2026-05-25 12:25:43 +02:00
Window Maker a16c25a78e WPrefs: fix icon position preview lagging one click behind
The posV widget was moved/resized but the parent frame (posVF) was
never redrawn, so the visual update only appeared on the next event
that triggered a redraw. Add WMRedisplayWidget after the move.
2026-05-25 12:05:53 +02:00
Window Maker b94bc2ce95 WPrefs: drop SIGUSR2, rely on inotify for defaults reload
SIGUSR2 is fundamentally unsafe in a multi-threaded compositor: library
threads (pango fontconfig) created after pthread_sigmask receive the
signal and crash. The Wayland event loop already has inotify watching
the defaults directory, so file changes are detected automatically
without any explicit signaling.

The early pthread_sigmask(SIG_BLOCK, SIGUSR2) is retained as a safety
measure to prevent stray SIGUSR2 from terminating the compositor.
2026-05-25 12:02:26 +02:00
Window Maker d8592f3b57 wayland: block SIGUSR2 early so library threads inherit the mask
SIGUSR2 was being delivered to pango fontconfig threads instead of the
signalfd because those threads were created before the signal mask was
set in wl_event_loop_run. Block SIGUSR2 at the very start of real_main
so all threads (including library-spawned ones) inherit the blocked
mask and the signalfd is the sole recipient.
2026-05-25 12:00:13 +02:00
Window Maker 8630a5ce95 wayland: handle SIGUSR2 via signalfd to reload defaults without dying
SIGUSR2 was not in the signalfd set, so it was delivered asynchronously
to the old signal handler which set WSTATE_NEED_REREAD. But the Wayland
event loop never checked that state flag, and the signal delivery itself
could crash the compositor.

Add SIGUSR2 to the signalfd set and handle it synchronously within the
event loop by calling wDefaultsCheckDomains directly.
2026-05-25 11:58:14 +02:00
Window Maker 9dee4f7a65 WPrefs: fix SIGUSR2 targeting wmaker instead of parent shell
The previous getppid() approach sent SIGUSR2 to the terminal process
(foot) rather than wmaker, killing the shell. Now wmaker exports
WMAKER_PID at startup and wl_send_wm_command reads it to signal the
correct process.
2026-05-25 11:55:14 +02:00
Window Maker 35226c8588 WPrefs: send SIGUSR2 to wmaker after saving settings
The Wayland event backend stub for send_wm_command was a no-op, so
WPrefs settings changes never triggered a reread in the running wmaker.
Now sends SIGUSR2 to the parent process (wmaker) on "Reconfigure",
causing wDefaultsCheckDomains to run and apply changes immediately.
2026-05-25 11:51:25 +02:00
Window Maker 9a4438fb65 cursor: respect XCURSOR_THEME and XCURSOR_SIZE environment variables
The xcursor manager was hardcoded to NULL theme with size 24. Now reads
XCURSOR_THEME and XCURSOR_SIZE from the environment, matching the
behavior of other Wayland compositors like Sway.
2026-05-25 11:48:23 +02:00
Window Maker 703872bcca xwayland: route keyboard events via wlr_seat_keyboard_notify_enter
The XWayland focus path only called wlr_xwayland_surface_activate (X11
focus) but did not notify the wlr_seat about keyboard focus. Without
wlr_seat_keyboard_notify_enter, key events were never forwarded to the
XWayland surface via the Wayland transport.

Now wl_focus_set for XWayland surfaces sets the seat keyboard and calls
wlr_seat_keyboard_notify_enter, matching the XDG toplevel path.
2026-05-25 11:45:47 +02:00
Window Maker 5bff28efcd xwayland: fix rendering by switching from map_request to associate+surface.map
The map_request signal was never firing for managed XWayland surfaces,
preventing scene node creation and window management. Switch to the
standard wlroots 0.19 lifecycle: listen for associate (surface attached),
then hook surface->events.map (content committed) before creating the
scene node and calling wManageWindow.

Also fix wl_window_get_client_attrs to report VIEWABLE based on surface
existence rather than surface->mapped, since X11 geometry (xw->width/height)
is available before the wlr_surface maps.
2026-05-25 11:43:18 +02:00
Window Maker 9bb2d02254 debug: trace xwayland scene node creation 2026-05-25 10:35:07 +02:00
Window Maker b67d3a04fb wl_backend: send 640x480 configure for xwayland surfaces with tiny initial size
xterm starts with a 10x17 pixel window. The initial configure was
sending that size back (since > 0), so xterm rendered at 10x17.
Now use 640x480 default when the initial size is < 64px.
2026-05-25 10:33:18 +02:00