wlr_scene_xdg_surface_create handles geometry offset internally.
Our manual subtraction of geometry.x/y in handle_toplevel_commit,
handle_toplevel_map, and wl_window_move was double-subtracting,
causing client surfaces to render behind their frames.
Remove all manual geometry offset from scene node positioning.
When MenuTextColor is not explicitly set (defaults to black), dark
widget themes render invisible black-on-dark menu text. Compute
luminance contrast between text color and background; if insufficient
(< 64 difference), substitute white text on dark backgrounds or black
text on light backgrounds.
wl_frame_configure and wl_window_resize reallocate fb->image (unref
old pixman image, create new one) but never updated the WINGs backing
table. W_GetViewBacking() continued returning the freed pointer.
Any subsequent draw into that backing (e.g. WMDrawString for titlebar
text) wrote into freed memory, corrupting the heap. The corruption
manifested as SIGSEGV/SIGABRT at the next malloc or free — in
fontconfig, Mesa, RReleaseImage, etc. depending on timing.
Fix: call W_RegisterBacking(fb->id, fb->image) after reallocation in
both resize paths.
Call wlr_scene_buffer_set_buffer(NULL) before freeing the old pixman
image in every resize path (client configure, frame configure,
workspace badge, balloon). This ensures the scene graph never holds
a dangling reference to freed pixel data.
Frame_buf IDs (0x10000000-0x1FFFFFFF) were registered in the 256-entry
view_table alongside WINGs views, filling it with tombstones until
lookups failed. Now frame_buf IDs are excluded from the table; the 3
callers that passed frame_buf IDs to WMDrawString pass raw pixman
pointers instead.
XWayland dockapps (wmclock, etc.) now render their content inside the
dock icon tile instead of in a separate window.
Key changes:
- wl_props.c: implement wl_prop_get_wm_hints for XWayland surfaces,
reading xcb_icccm_wm_hints_t to detect WithdrawnState dockapps
- appicon.c: for is_dockapp windows, use client_win as icon_win
- icon.c: capture icon_window pixels via XGetImage with XShape mask
for transparency, skip surface embedding when image is captured
- wl_icon.c: create_rimage_from_drawable handles X11 Window IDs via
XGetImage, applies XShape bounding rectangles as alpha mask
- wl_stubs.c: pixmap_get_size returns actual view dimensions
- wl_window.c: map XWayland dockapp windows and reparent icon_window
child into main window for compositing
Without this, moving a CSD client (Firefox) causes the surface to
"pop" out of the WM frame — the scene node was positioned at the
raw frame-relative coords without subtracting geometry.x/y.
The dock_shadow was rendering above the dragged icon because:
1. It was in WL_LAYER_OVERLAY/DOCK, above the dock icons in WL_LAYER_FLOATING
2. wl_stacking_restack could not order nodes across different parent trees
3. wl_window_map auto-raised on map, undoing any prior restack
Fixes:
- Place dock_shadow in WL_LAYER_FLOATING (where WMDockLevel=5 maps)
- Rewrite wl_stacking_restack to reparent nodes into the same tree
and use wlr_scene_node_place_below for guaranteed ordering
- Remove auto-raise from wl_window_map (explicit wRaiseFrame handles it)
When wl_window_resize frees the old pixman image and creates a new one,
it must call W_RegisterBacking to update the backing store. Otherwise
W_GetViewBacking returns the freed old image pointer, causing a crash
when WMDrawString (via wl_font_resolve_drawable) tries to draw into
the stale backing. This manifests on workspace name badge display
in direct render mode.