Fix screen init: create RContext + WINGs screen on XWayland in Wayland mode

- wScreenInit Wayland fast path now creates RContext on XWayland display
  (needed for wTextureRenderImage and wraster image loading)
- Also creates WINGs screen (wmscreen) so WMDrawString/WMFontHeight work
- Add wl_get_x_display() accessor for screen.c to get XWayland Display*
- Remove if(dpy) guard around wScreenRestoreState in startup.c so dock,
  clip, menus, and window management run in Wayland mode

Status: startup reaches menu creation but hangs in wMenuCreate due to
Xlib operations on XWayland during WINGs font/screen init. The pump
thread is running but something in the menu creation path is spinning.
Next step: identify and eliminate the remaining XWayland dependency in
the menu creation path.
This commit is contained in:
Levi Neely 2026-05-13 07:33:25 +02:00
parent cc3655d2fd
commit 74647423c5
3 changed files with 44 additions and 13 deletions

View File

@ -1921,6 +1921,13 @@ wl_handle_x11_events(int fd, uint32_t mask, void *data)
return 0;
}
/* Public accessor for the XWayland Display* — used by screen.c to create
* an RContext for texture rendering without exposing wl_state globally. */
Display *wl_get_x_display(void)
{
return wl_state.x_display;
}
static void *
wl_display_open(const char *name)
{

View File

@ -163,17 +163,43 @@ WScreen *wScreenInit(int screen_number)
* set, Path 1), fall through to the full X11 init so WINGs, RContext,
* GCs, and menus work correctly on the XWayland display. */
if (wm_backend->is_wayland && !dpy) {
WWorkspace *wspace = wmalloc(sizeof(WWorkspace));
wspace->name = wstrdup("Workspace 1");
wspace->clip = NULL;
wspace->map = NULL;
scr->workspaces = wmalloc(sizeof(WWorkspace *));
scr->workspaces[0] = wspace;
scr->workspace_count = 1;
/* Phase 62: run backend screen internals (sets no_focus_win,
* auto_focus, clears keyboard focus) before leaving the Wayland
* fast path — screen_create_internals is normally called at
* line 248 which the goto would skip. */
extern Display *wl_get_x_display(void);
Display *xdpy = wl_get_x_display();
if (!xdpy) {
/* No XWayland — truly headless. Minimal workspace only. */
WWorkspace *wspace = wmalloc(sizeof(WWorkspace));
wspace->name = wstrdup("Workspace 1");
wspace->clip = NULL;
wspace->map = NULL;
scr->workspaces = wmalloc(sizeof(WWorkspace *));
scr->workspaces[0] = wspace;
scr->workspace_count = 1;
wm_backend->screen_create_internals(scr);
goto screen_done;
}
/* XWayland available — create RContext on it for texture rendering. */
rattr.flags = RC_RenderMode | RC_ColorsPerChannel | RC_StandardColormap;
rattr.render_mode = RBestMatchRendering;
rattr.colors_per_channel = 4;
rattr.standard_colormap_mode = RUseStdColormap;
scr->rcontext = RCreateContext(xdpy, DefaultScreen(xdpy), &rattr);
if (!scr->rcontext) {
rattr.flags &= ~RC_StandardColormap;
scr->rcontext = RCreateContext(xdpy, DefaultScreen(xdpy), &rattr);
}
if (scr->rcontext) {
scr->w_win = scr->rcontext->drawable;
scr->w_visual = scr->rcontext->visual;
scr->w_depth = scr->rcontext->depth;
scr->w_colormap = scr->rcontext->cmap;
scr->wmscreen = WMCreateScreenWithRContext(xdpy, DefaultScreen(xdpy), scr->rcontext);
}
wm_backend->screen_create_internals(scr);
goto screen_done;
}

View File

@ -554,7 +554,6 @@ void StartUp(Bool defaultScreenOnly)
InitializeSwitchMenu();
/* initialize/restore state for the screens */
if (dpy) {
for (j = 0; j < w_global.screen_count; j++) {
int lastDesktop;
@ -613,7 +612,6 @@ void StartUp(Bool defaultScreenOnly)
else
wSessionRestoreLastWorkspace(wScreen[j]);
}
} /* end if (dpy) */
if (w_global.screen_count == 0) {
wfatal(_("could not manage any screen"));