Handle xwayland not started (when HAVE_XWAYLAND, but lacking the binary)

Closes https://github.com/labwc/labwc/issues/434
This commit is contained in:
Daniel Lublin 2026-02-25 10:40:39 +01:00 committed by Johan Malm
parent 4e25347791
commit fee38bceca
5 changed files with 37 additions and 14 deletions

View file

@ -21,7 +21,6 @@
#include "labwc.h" #include "labwc.h"
static const char *const env_vars[] = { static const char *const env_vars[] = {
"DISPLAY",
"WAYLAND_DISPLAY", "WAYLAND_DISPLAY",
"XDG_CURRENT_DESKTOP", "XDG_CURRENT_DESKTOP",
"XCURSOR_SIZE", "XCURSOR_SIZE",
@ -208,6 +207,21 @@ should_update_activation(void)
return have_drm; return have_drm;
} }
static void
execute_update(const char *env_keys, const char *env_unset_keys, bool initialize)
{
char *cmd =
strdup_printf("dbus-update-activation-environment %s",
initialize ? env_keys : env_unset_keys);
spawn_async_no_shell(cmd);
free(cmd);
cmd = strdup_printf("systemctl --user %s %s",
initialize ? "import-environment" : "unset-environment", env_keys);
spawn_async_no_shell(cmd);
free(cmd);
}
static void static void
update_activation_env(bool initialize) update_activation_env(bool initialize)
{ {
@ -227,19 +241,18 @@ update_activation_env(bool initialize)
char *env_keys = str_join(env_vars, "%s", " "); char *env_keys = str_join(env_vars, "%s", " ");
char *env_unset_keys = initialize ? NULL : str_join(env_vars, "%s=", " "); char *env_unset_keys = initialize ? NULL : str_join(env_vars, "%s=", " ");
char *cmd = execute_update(env_keys, env_unset_keys, initialize);
strdup_printf("dbus-update-activation-environment %s",
initialize ? env_keys : env_unset_keys);
spawn_async_no_shell(cmd);
free(cmd);
cmd = strdup_printf("systemctl --user %s %s",
initialize ? "import-environment" : "unset-environment", env_keys);
spawn_async_no_shell(cmd);
free(cmd);
free(env_keys); free(env_keys);
free(env_unset_keys); free(env_unset_keys);
#if HAVE_XWAYLAND
if (server.xwayland) {
// DISPLAY is only set if xwayland was initialized successfully,
// so we only update the env in that case
execute_update("DISPLAY", "DISPLAY=", initialize);
}
#endif
} }
void void

View file

@ -1166,7 +1166,7 @@ cursor_process_button_press(struct seat *seat, uint32_t button, uint32_t time_ms
if (layer && layer->current.keyboard_interactive) { if (layer && layer->current.keyboard_interactive) {
layer_try_set_focus(seat, layer); layer_try_set_focus(seat, layer);
} }
#ifdef HAVE_XWAYLAND #if HAVE_XWAYLAND
} else if (ctx.type == LAB_NODE_UNMANAGED) { } else if (ctx.type == LAB_NODE_UNMANAGED) {
desktop_focus_view_or_surface(seat, NULL, ctx.surface, desktop_focus_view_or_surface(seat, NULL, ctx.surface,
/*raise*/ false); /*raise*/ false);

View file

@ -583,6 +583,8 @@ server_init(void)
server.workspace_tree = lab_wlr_scene_tree_create(&server.scene->tree); server.workspace_tree = lab_wlr_scene_tree_create(&server.scene->tree);
server.xdg_popup_tree = lab_wlr_scene_tree_create(&server.scene->tree); server.xdg_popup_tree = lab_wlr_scene_tree_create(&server.scene->tree);
#if HAVE_XWAYLAND #if HAVE_XWAYLAND
// Creating/setting this is harmless when xwayland support is built-in
// but xwayland could not be successfully started.
server.unmanaged_tree = lab_wlr_scene_tree_create(&server.scene->tree); server.unmanaged_tree = lab_wlr_scene_tree_create(&server.scene->tree);
#endif #endif
server.menu_tree = lab_wlr_scene_tree_create(&server.scene->tree); server.menu_tree = lab_wlr_scene_tree_create(&server.scene->tree);

View file

@ -54,6 +54,8 @@ view_from_wlr_surface(struct wlr_surface *surface)
return xdg_surface->data; return xdg_surface->data;
} }
#if HAVE_XWAYLAND #if HAVE_XWAYLAND
// Doing this is harmless even in the case that xwayland could not be
// successfully started.
struct wlr_xwayland_surface *xsurface = struct wlr_xwayland_surface *xsurface =
wlr_xwayland_surface_try_from_wlr_surface(surface); wlr_xwayland_surface_try_from_wlr_surface(surface);
if (xsurface) { if (xsurface) {

View file

@ -1218,8 +1218,9 @@ xwayland_server_init(struct wlr_compositor *compositor)
wlr_xwayland_create(server.wl_display, wlr_xwayland_create(server.wl_display,
compositor, /* lazy */ !rc.xwayland_persistence); compositor, /* lazy */ !rc.xwayland_persistence);
if (!server.xwayland) { if (!server.xwayland) {
wlr_log(WLR_ERROR, "cannot create xwayland server"); wlr_log(WLR_ERROR, "failed to create xwayland server, continuing without");
exit(EXIT_FAILURE); unsetenv("DISPLAY");
return;
} }
server.xwayland_new_surface.notify = handle_new_surface; server.xwayland_new_surface.notify = handle_new_surface;
wl_signal_add(&server.xwayland->events.new_surface, wl_signal_add(&server.xwayland->events.new_surface,
@ -1308,6 +1309,11 @@ void
xwayland_server_finish(void) xwayland_server_finish(void)
{ {
struct wlr_xwayland *xwayland = server.xwayland; struct wlr_xwayland *xwayland = server.xwayland;
if (!xwayland) {
return;
}
wl_list_remove(&server.xwayland_new_surface.link); wl_list_remove(&server.xwayland_new_surface.link);
wl_list_remove(&server.xwayland_server_ready.link); wl_list_remove(&server.xwayland_server_ready.link);
wl_list_remove(&server.xwayland_xwm_ready.link); wl_list_remove(&server.xwayland_xwm_ready.link);