- 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
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.
wlr_seat_keyboard_notify_key was being called unconditionally, which
caused re-entrancy that consumed WINGs events from the queue before
the modal loop could fetch them. Now only forwards to the seat when
there's an actual focused client surface.
Also use 16ms timeout in wl_flush so keyboard events from the nested
compositor are actually received during modal loop dispatch.
The deadlock: frame_timer_cb called WMHandleEvent which entered
menuMouseDown's modal WMMaskEvent loop. That blocked inside
wl_event_loop_dispatch (reentrant), preventing new events.
Fix:
1. Replace wl_display_run() with custom loop that drains WINGs
events BETWEEN wl_event_loop_dispatch calls (not inside timer)
2. Make WINGs wl_flush() pump wlroots (call dispatch_fn) so
WMMaskEvent modal loops get new events without reentrancy
3. Fix wBalloonHide NULL dereference (scr->balloon not allocated)
4. Remove XEvent dependency from wSelectWindows (takes x,y now)
5. Remove debug traces
Right-click on background now opens the root menu.
Key changes in wl_backend.c:
- wl_atom_intern: call XInternAtom on XWayland display (was returning 0)
- Add wl_or_view struct to track override_redirect XWayland surfaces
- handle_xwayland_new_surface: composite OR surfaces via scene graph
- frame_create_toplevel/child: create real X11 windows on XWayland
- frame_destroy/configure: delegate to Xlib
- window_map/unmap/move/resize: fall through to Xlib for frame windows
- stacking_raise/lower: update scene graph + Xlib fallback
- event_flush/sync: call XFlush/XSync on XWayland display
- window_set_border/border_width/clear: delegate to Xlib
- window_get_rect: query XWayland geometry for non-toplevel windows
Note: frame creation via XWayland is a temporary bridge. The correct
architectural approach is native scene-buffer rendering with pixman.