wlroots manages XWayland internally via its own xcb connection.
Our second Xlib connection (XOpenDisplay) interfered with XWayland's
event routing, preventing WM_DELETE_WINDOW from reaching X clients
and causing slow XWayland startup.
Removed:
- Persistent wl_state.x_display / x11_event_source
- X11 event pump (wl_handle_x11_events)
- Xlib-based icon capture, GC creation, key/message forwarding
- XSetErrorHandler on our connection
- Reentrant wl_event_loop_dispatch in wl_event_flush (caused UAF)
Root cursor now set via wlr_xwayland_set_cursor (wlroots API).
XWayland close button now works correctly.
Each frame_buf gets a canary field (0xDEADBEEF) set at creation.
Before every frame_paint, all canaries are checked. If one is
trashed, dumps all frame_buf IDs/sizes/addresses to /tmp/wm-canary.log
before aborting.
Set canary in ALL frame_buf creation paths:
- wl_frame_create_toplevel, wl_frame_create_child
- wl_fake_leader_create
- wl_client_reparent (WINGs view frame_buf creation)
- wl_view_commit_backing_impl (WINGs toplevel)
- wl_screen dock_shadow and icon frame_bufs
- wl_window pixmap-to-frame_buf path
The close button on internal windows (dock app settings, etc.) did
nothing because:
1. wwin->protocols.DELETE_WINDOW was never set for internal windows,
so windowCloseClick skipped the wClientSendProtocol call.
2. Even if it were called, wl_client_send_protocol just called
client_close which looks for an XDG/XWayland surface. Internal
windows have synthetic WINGs view IDs, not real surfaces.
Fix: set DELETE_WINDOW protocol flag in wManageInternalWindow, and
handle internal windows in wl_client_send_protocol by calling
wUnmanageWindow directly.
W_ViewDestroyedFn hook clears last_hovered_view when the pointed-to
view is destroyed. Prevents use-after-free in motion handler when
the hovering over a view inside a dialog that is then closed.
Add client_set_fullscreen backend vtable entry. Call
wlr_xdg_toplevel_set_fullscreen on enter/leave so clients
(e.g. Firefox) know to render content at full size.
The WINGs view_table (open-addressing hash, size 256) used id=0 as both
"empty" and "deleted". Zeroing a slot on removal broke probe chains for
entries that hashed past that slot. After two dialog open/close cycles
(~40 views created and destroyed), enough chains were broken that
W_GetViewForWindow/W_GetViewBacking returned NULL for valid IDs.
Fix: use a tombstone marker (id=1) for deleted slots. Lookups skip
tombstones (continue probing), inserts reuse them. This is the standard
approach for deletion in open-addressing hash tables (Knuth Vol.3 §6.4).
Also:
- wl_destroy now calls view_table_remove + frees backing pixman image
- wl_frame_destroy cleans up child frame_bufs
- client_reparent existing path re-links backing and recreates scene_buf
- client_reparent to root destroys the child frame_buf
Firefox and other CSD clients include invisible shadow borders in their
surface buffer. Use xdg_surface->geometry (the client-declared content
rect) for:
- reporting client width/height to the WM frame
- sizing the frame on commit
- offsetting the scene node so shadows are outside the frame bounds
Falls back to surface->current.width/height when geometry is unset.
Remove duplicate W_ViewSceneNodeSetEnabledFn call, fix malformed debug code.
wl_unmap now logs cleanup diagnostics once. wl_view_scene_node_set_enabled
logs proxy ID lookup, match result, and no-match case properly.
The function only handled wl_frame_buf entries. WINGs client popup menus have
their own xdg_toplevel surface with a scene_node but no wl_frame_buf. Their
WINGs view window IDs (0x20000000+) differ from compositor view IDs
(0x10000000+), so wl_find_view_by_id could not find them.
Fix: add wlc_top_get_surface_id() in wclient_wl.c which returns the
libwayland-client proxy ID for the wl_surface. In
wl_view_scene_node_set_enabled, use this ID to iterate the compositor
toplevel_list and find the matching wlr_surface resource by object ID.
Then enable/disable the view scene_node directly.
The function only searched for wl_frame_buf entries to enable/disable
their scene nodes. WINGs client popup menus have their own xdg_toplevel
surface with a scene_node but no wl_frame_buf. On unmap, the scene node
was never disabled, so the popup content remained rendered underneath
other windows.
Fix: fall through to wl_find_view_by_id when no frame_buf is found,
and operate on the wl_toplevel_view->scene_node instead.