wayland: fix XWayland window visibility

Two bugs prevented XWayland client windows from appearing:

1. flags.mapped never set for XWayland windows (window.c)
   The condition `else if (!dpy)` is false when dpy is the XWayland
   Display* (it is only true for pure native-Wayland mode with no X11).
   Changed to `else if (!dpy || wm_backend->is_wayland)` so XWayland
   windows also get flags.mapped=1 after wManageWindow, matching the
   semantics of XDG toplevel windows.

2. scene node positioned at xw->x,xw->y before configure round-trip
   handle_xwayland_map used xw->x,xw->y for the initial scene node
   position.  These values may not yet reflect the configure sent in
   handle_new_xwayland_surface (the X11 round-trip is async).  Changed
   to use view->x,view->y which are set to output/4 in
   handle_new_xwayland_surface and kept in sync by set_geometry listener.

Also added a log line when xw->surface is NULL at map time so the cause
is diagnosable from wmaker stderr.

Note: if xterm connects to the wrong DISPLAY (e.g. Sway's :1 instead of
wmaker's :2), no handle_xwayland_map fires at all.  Check wmaker's
"XWayland ready on :X" log line for the correct display number.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Levi Neely 2026-03-31 16:54:21 +02:00
parent fa26a31209
commit 2bcc676202
2 changed files with 10 additions and 4 deletions

View File

@ -1046,12 +1046,18 @@ handle_xwayland_map(struct wl_listener *listener, void *data)
xw->class ? xw->class : "(none)",
xw->title ? xw->title : "(none)");
/* Add to scene graph for compositing regardless of mode. */
/* Add to scene graph for compositing regardless of mode.
* Use view->x,y (set in handle_new_xwayland_surface to output/4)
* rather than xw->x,y which may not yet reflect the configure we
* sent; the set_geometry listener keeps them in sync thereafter. */
if (wl_state.scene && !view->scene_node && xw->surface) {
view->scene_node = wlr_scene_subsurface_tree_create(
&wl_state.scene->node, xw->surface);
if (view->scene_node)
wlr_scene_node_set_position(view->scene_node, xw->x, xw->y);
wlr_scene_node_set_position(view->scene_node, view->x, view->y);
} else if (!xw->surface) {
wwarning("wl_backend: xwayland map id=0x%lx: surface is NULL, window will not render",
view->id);
}

View File

@ -1251,8 +1251,8 @@ WWindow *wManageWindow(WScreen *scr, WNativeWindow window)
if (wwin->frame)
wWindowMap(wwin);
else if (!dpy)
wwin->flags.mapped = 1; /* Wayland: toplevel is visible by definition */
else if (!dpy || wm_backend->is_wayland)
wwin->flags.mapped = 1; /* Wayland/XWayland: scene node visible by definition */
}
/* setup stacking descriptor */