From c80bf1591e5cea26bd29e1b4b4680d4ef3693833 Mon Sep 17 00:00:00 2001 From: Vincent Vanlaer Date: Sun, 6 May 2018 20:23:10 +0200 Subject: [PATCH 1/8] Allow xwayland to start lazily Makes the xwayland startup process two phased. The first phase just initialises the X11 sockets. The second phase starts the Xwayland server itself. When starting xwayland lazily the second phase will be postponed until a client has connected to the X11 socket. Changes in behaviour: The DISPLAY environment is now set immediately after the X11 sockets are created. When the Xwayland server is killed or crashes, the sockets will not be recreated, but reused. Fixes #849: Start up Xwayland lazily --- include/wlr/xwayland.h | 4 +- rootston/desktop.c | 2 +- xwayland/xwayland.c | 138 +++++++++++++++++++++++++++++------------ 3 files changed, 101 insertions(+), 43 deletions(-) diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index b2c236675..a802d32df 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -15,10 +15,12 @@ struct wlr_xwayland { pid_t pid; int display; int x_fd[2], wl_fd[2], wm_fd[2]; + struct wl_event_source *x_fd_read_event[2]; struct wl_client *client; struct wl_display *wl_display; struct wlr_compositor *compositor; time_t server_start; + bool lazy; struct wl_event_source *sigusr1_source; struct wl_listener client_destroy; @@ -168,7 +170,7 @@ struct wlr_xwayland_resize_event { }; struct wlr_xwayland *wlr_xwayland_create(struct wl_display *wl_display, - struct wlr_compositor *compositor); + struct wlr_compositor *compositor, bool lazy); void wlr_xwayland_destroy(struct wlr_xwayland *wlr_xwayland); diff --git a/rootston/desktop.c b/rootston/desktop.c index 6ac665bca..06c188d89 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -835,7 +835,7 @@ struct roots_desktop *desktop_create(struct roots_server *server, if (config->xwayland) { desktop->xwayland = wlr_xwayland_create(server->wl_display, - desktop->compositor); + desktop->compositor, false); wl_signal_add(&desktop->xwayland->events.new_surface, &desktop->xwayland_surface); desktop->xwayland_surface.notify = handle_xwayland_surface; diff --git a/xwayland/xwayland.c b/xwayland/xwayland.c index f27de679b..fd5309ad4 100644 --- a/xwayland/xwayland.c +++ b/xwayland/xwayland.c @@ -128,7 +128,7 @@ static void exec_xwayland(struct wlr_xwayland *wlr_xwayland) { execvp("Xwayland", argv); } -static void xwayland_finish(struct wlr_xwayland *wlr_xwayland) { +static void xwayland_finish_server(struct wlr_xwayland *wlr_xwayland) { if (!wlr_xwayland || wlr_xwayland->display == -1) { return; } @@ -147,27 +147,33 @@ static void xwayland_finish(struct wlr_xwayland *wlr_xwayland) { wl_event_source_remove(wlr_xwayland->sigusr1_source); } - safe_close(wlr_xwayland->x_fd[0]); - safe_close(wlr_xwayland->x_fd[1]); safe_close(wlr_xwayland->wl_fd[0]); safe_close(wlr_xwayland->wl_fd[1]); safe_close(wlr_xwayland->wm_fd[0]); safe_close(wlr_xwayland->wm_fd[1]); - - wl_list_remove(&wlr_xwayland->display_destroy.link); - - unlink_display_sockets(wlr_xwayland->display); - wlr_xwayland->display = -1; - unsetenv("DISPLAY"); /* We do not kill the Xwayland process, it dies to broken pipe * after we close our side of the wm/wl fds. This is more reliable * than trying to kill something that might no longer be Xwayland. */ } -static bool xwayland_start(struct wlr_xwayland *wlr_xwayland, +static void xwayland_finish_display(struct wlr_xwayland *wlr_xwayland) { + safe_close(wlr_xwayland->x_fd[0]); + safe_close(wlr_xwayland->x_fd[1]); + + wl_list_remove(&wlr_xwayland->display_destroy.link); + + unlink_display_sockets(wlr_xwayland->display); + wlr_xwayland->display = -1; + unsetenv("DISPLAY"); +} + +static bool xwayland_start_display(struct wlr_xwayland *wlr_xwayland, struct wl_display *wl_display, struct wlr_compositor *compositor); +static bool xwayland_start_server(struct wlr_xwayland *wlr_xwayland); +static bool xwayland_start_server_lazy(struct wlr_xwayland *wlr_xwayland); + static void handle_client_destroy(struct wl_listener *listener, void *data) { struct wlr_xwayland *wlr_xwayland = wl_container_of(listener, wlr_xwayland, client_destroy); @@ -176,12 +182,13 @@ static void handle_client_destroy(struct wl_listener *listener, void *data) { wlr_xwayland->client = NULL; wl_list_remove(&wlr_xwayland->client_destroy.link); - xwayland_finish(wlr_xwayland); + xwayland_finish_server(wlr_xwayland); - if (time(NULL) - wlr_xwayland->server_start > 5) { + if (wlr_xwayland->lazy) { + xwayland_start_server_lazy(wlr_xwayland); + } else if (time(NULL) - wlr_xwayland->server_start > 5) { wlr_log(L_INFO, "Restarting Xwayland"); - xwayland_start(wlr_xwayland, wlr_xwayland->wl_display, - wlr_xwayland->compositor); + xwayland_start_server(wlr_xwayland); } } @@ -217,7 +224,7 @@ static int xserver_handle_ready(int signal_number, void *data) { wlr_xwayland->xwm = xwm_create(wlr_xwayland); if (!wlr_xwayland->xwm) { - xwayland_finish(wlr_xwayland); + xwayland_finish_server(wlr_xwayland); return 1; } @@ -236,9 +243,6 @@ static int xserver_handle_ready(int signal_number, void *data) { wlr_xwayland->cursor = NULL; } - char display_name[16]; - snprintf(display_name, sizeof(display_name), ":%d", wlr_xwayland->display); - setenv("DISPLAY", display_name, true); wlr_signal_emit_safe(&wlr_xwayland->events.ready, wlr_xwayland); /* ready is a one-shot signal, fire and forget */ @@ -247,48 +251,62 @@ static int xserver_handle_ready(int signal_number, void *data) { return 1; /* wayland event loop dispatcher's count */ } -static bool xwayland_start(struct wlr_xwayland *wlr_xwayland, +static int xwayland_socket_connected(int fd, uint32_t mask, void* data){ + struct wlr_xwayland *wlr_xwayland = data; + + wl_event_source_remove(wlr_xwayland->x_fd_read_event[0]); + wl_event_source_remove(wlr_xwayland->x_fd_read_event[1]); + + xwayland_start_server(wlr_xwayland); + + return 0; +} + +static bool xwayland_start_display(struct wlr_xwayland *wlr_xwayland, struct wl_display *wl_display, struct wlr_compositor *compositor) { - memset(wlr_xwayland, 0, offsetof(struct wlr_xwayland, seat)); - wlr_xwayland->wl_display = wl_display; - wlr_xwayland->compositor = compositor; wlr_xwayland->x_fd[0] = wlr_xwayland->x_fd[1] = -1; - wlr_xwayland->wl_fd[0] = wlr_xwayland->wl_fd[1] = -1; - wlr_xwayland->wm_fd[0] = wlr_xwayland->wm_fd[1] = -1; wlr_xwayland->display_destroy.notify = handle_display_destroy; wl_display_add_destroy_listener(wl_display, &wlr_xwayland->display_destroy); wlr_xwayland->display = open_display_sockets(wlr_xwayland->x_fd); if (wlr_xwayland->display < 0) { - xwayland_finish(wlr_xwayland); + xwayland_finish_display(wlr_xwayland); return false; } + + char display_name[16]; + snprintf(display_name, sizeof(display_name), ":%d", wlr_xwayland->display); + setenv("DISPLAY", display_name, true); + + return true; +} + +static bool xwayland_start_server(struct wlr_xwayland *wlr_xwayland) { + wlr_xwayland->wl_fd[0] = wlr_xwayland->wl_fd[1] = -1; + wlr_xwayland->wm_fd[0] = wlr_xwayland->wm_fd[1] = -1; + if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, wlr_xwayland->wl_fd) != 0 || socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, wlr_xwayland->wm_fd) != 0) { wlr_log_errno(L_ERROR, "failed to create socketpair"); - xwayland_finish(wlr_xwayland); + xwayland_finish_server(wlr_xwayland); return false; } - wlr_xwayland->server_start = time(NULL); - if (!(wlr_xwayland->client = wl_client_create(wl_display, wlr_xwayland->wl_fd[0]))) { + if (!(wlr_xwayland->client = wl_client_create(wlr_xwayland->wl_display, wlr_xwayland->wl_fd[0]))) { wlr_log_errno(L_ERROR, "wl_client_create failed"); - xwayland_finish(wlr_xwayland); + xwayland_finish_server(wlr_xwayland); return false; } - // unset $DISPLAY while XWayland starts - unsetenv("DISPLAY"); - wlr_xwayland->wl_fd[0] = -1; /* not ours anymore */ wlr_xwayland->client_destroy.notify = handle_client_destroy; wl_client_add_destroy_listener(wlr_xwayland->client, &wlr_xwayland->client_destroy); - struct wl_event_loop *loop = wl_display_get_event_loop(wl_display); + struct wl_event_loop *loop = wl_display_get_event_loop(wlr_xwayland->wl_display); wlr_xwayland->sigusr1_source = wl_event_loop_add_signal(loop, SIGUSR1, xserver_handle_ready, wlr_xwayland); @@ -323,36 +341,74 @@ static bool xwayland_start(struct wlr_xwayland *wlr_xwayland, } if (wlr_xwayland->pid < 0) { wlr_log_errno(L_ERROR, "fork failed"); - xwayland_finish(wlr_xwayland); + xwayland_finish_server(wlr_xwayland); return false; } /* close child fds */ - close(wlr_xwayland->x_fd[0]); - close(wlr_xwayland->x_fd[1]); + /* remain managing x sockets for lazy start */ close(wlr_xwayland->wl_fd[1]); close(wlr_xwayland->wm_fd[1]); - wlr_xwayland->x_fd[0] = wlr_xwayland->x_fd[1] = -1; wlr_xwayland->wl_fd[1] = wlr_xwayland->wm_fd[1] = -1; return true; } +static bool xwayland_start_server_lazy(struct wlr_xwayland *wlr_xwayland) { + struct wl_event_loop *loop = wl_display_get_event_loop(wlr_xwayland->wl_display); + wlr_xwayland->x_fd_read_event[0] = + wl_event_loop_add_fd(loop, wlr_xwayland->x_fd[0], WL_EVENT_READABLE, + xwayland_socket_connected, wlr_xwayland); + wlr_xwayland->x_fd_read_event[1] = + wl_event_loop_add_fd(loop, wlr_xwayland->x_fd[1], WL_EVENT_READABLE, + xwayland_socket_connected, wlr_xwayland); + + return true; +} + void wlr_xwayland_destroy(struct wlr_xwayland *wlr_xwayland) { wlr_xwayland_set_seat(wlr_xwayland, NULL); - xwayland_finish(wlr_xwayland); + xwayland_finish_server(wlr_xwayland); + xwayland_finish_display(wlr_xwayland); free(wlr_xwayland); } struct wlr_xwayland *wlr_xwayland_create(struct wl_display *wl_display, - struct wlr_compositor *compositor) { + struct wlr_compositor *compositor, bool lazy) { struct wlr_xwayland *wlr_xwayland = calloc(1, sizeof(struct wlr_xwayland)); + memset(wlr_xwayland, 0, offsetof(struct wlr_xwayland, seat)); + + wlr_xwayland->wl_display = wl_display; + wlr_xwayland->compositor = compositor; + wlr_xwayland->lazy = lazy; + + wlr_xwayland->x_fd[0] = wlr_xwayland->x_fd[1] = -1; + wlr_xwayland->wl_fd[0] = wlr_xwayland->wl_fd[1] = -1; + wlr_xwayland->wm_fd[0] = wlr_xwayland->wm_fd[1] = -1; wl_signal_init(&wlr_xwayland->events.new_surface); wl_signal_init(&wlr_xwayland->events.ready); - if (xwayland_start(wlr_xwayland, wl_display, compositor)) { - return wlr_xwayland; + + if (!xwayland_start_display(wlr_xwayland, wl_display, compositor)) { + goto error_alloc; } + + if (wlr_xwayland->lazy) { + if (!xwayland_start_server_lazy(wlr_xwayland)) { + goto error_display; + } + } else { + if (!xwayland_start_server(wlr_xwayland)) { + goto error_display; + } + } + + return wlr_xwayland; + +error_display: + xwayland_finish_display(wlr_xwayland); + +error_alloc: free(wlr_xwayland); return NULL; } From 31861b3a7a2a4f3dc278278dadec60a70138c74e Mon Sep 17 00:00:00 2001 From: Vincent Vanlaer Date: Sun, 6 May 2018 22:22:39 +0200 Subject: [PATCH 2/8] Add option to rootston to start xwayland lazy --- include/rootston/config.h | 1 + rootston/config.c | 4 ++++ rootston/desktop.c | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/include/rootston/config.h b/include/rootston/config.h index 0a67ac1e3..97a8baab2 100644 --- a/include/rootston/config.h +++ b/include/rootston/config.h @@ -60,6 +60,7 @@ struct roots_cursor_config { struct roots_config { bool xwayland; + bool xwayland_lazy; struct wl_list outputs; struct wl_list devices; diff --git a/rootston/config.c b/rootston/config.c index 67bf83e95..bbdb79906 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -240,6 +240,9 @@ static int config_ini_handler(void *user, const char *section, const char *name, if (strcmp(name, "xwayland") == 0) { if (strcasecmp(value, "true") == 0) { config->xwayland = true; + } else if (strcasecmp(value, "lazy") == 0) { + config->xwayland = true; + config->xwayland_lazy = true; } else if (strcasecmp(value, "false") == 0) { config->xwayland = false; } else { @@ -389,6 +392,7 @@ struct roots_config *roots_config_create_from_args(int argc, char *argv[]) { } config->xwayland = true; + config->xwayland_lazy = false; wl_list_init(&config->outputs); wl_list_init(&config->devices); wl_list_init(&config->keyboards); diff --git a/rootston/desktop.c b/rootston/desktop.c index 06c188d89..7be1c64a3 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -835,7 +835,7 @@ struct roots_desktop *desktop_create(struct roots_server *server, if (config->xwayland) { desktop->xwayland = wlr_xwayland_create(server->wl_display, - desktop->compositor, false); + desktop->compositor, config->xwayland_lazy); wl_signal_add(&desktop->xwayland->events.new_surface, &desktop->xwayland_surface); desktop->xwayland_surface.notify = handle_xwayland_surface; From dbf4f9a2312c378b855db68f18b922e73c746887 Mon Sep 17 00:00:00 2001 From: Vincent Vanlaer Date: Sun, 6 May 2018 22:51:32 +0200 Subject: [PATCH 3/8] Make startup command no longer wait for xwayland --- include/rootston/desktop.h | 1 - rootston/main.c | 31 +++++++++++-------------------- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/include/rootston/desktop.h b/include/rootston/desktop.h index f150147b0..83ff2ea81 100644 --- a/include/rootston/desktop.h +++ b/include/rootston/desktop.h @@ -65,7 +65,6 @@ struct roots_desktop { #ifdef WLR_HAS_XWAYLAND struct wlr_xwayland *xwayland; struct wl_listener xwayland_surface; - struct wl_listener xwayland_ready; #endif }; diff --git a/rootston/main.c b/rootston/main.c index a61d65c92..18d27a8a8 100644 --- a/rootston/main.c +++ b/rootston/main.c @@ -14,18 +14,6 @@ struct roots_server server = { 0 }; -static void ready(struct wl_listener *listener, void *data) { - if (server.config->startup_cmd != NULL) { - const char *cmd = server.config->startup_cmd; - pid_t pid = fork(); - if (pid < 0) { - wlr_log(L_ERROR, "cannot execute binding command: fork() failed"); - } else if (pid == 0) { - execl("/bin/sh", "/bin/sh", "-c", cmd, (void *)NULL); - } - } -} - int main(int argc, char **argv) { wlr_log_init(L_DEBUG, NULL); server.config = roots_config_create_from_args(argc, argv); @@ -65,21 +53,24 @@ int main(int argc, char **argv) { } setenv("WAYLAND_DISPLAY", socket, true); -#ifndef WLR_HAS_XWAYLAND - ready(NULL, NULL); -#else +#ifdef WLR_HAS_XWAYLAND if (server.desktop->xwayland != NULL) { struct roots_seat *xwayland_seat = input_get_seat(server.input, ROOTS_CONFIG_DEFAULT_SEAT_NAME); wlr_xwayland_set_seat(server.desktop->xwayland, xwayland_seat->seat); - wl_signal_add(&server.desktop->xwayland->events.ready, - &server.desktop->xwayland_ready); - server.desktop->xwayland_ready.notify = ready; - } else { - ready(NULL, NULL); } #endif + if (server.config->startup_cmd != NULL) { + const char *cmd = server.config->startup_cmd; + pid_t pid = fork(); + if (pid < 0) { + wlr_log(L_ERROR, "cannot execute binding command: fork() failed"); + } else if (pid == 0) { + execl("/bin/sh", "/bin/sh", "-c", cmd, (void *)NULL); + } + } + wl_display_run(server.wl_display); wl_display_destroy(server.wl_display); return 0; From 446ea3a3408e2d735aaa77059745f82943bc67d2 Mon Sep 17 00:00:00 2001 From: Vincent Vanlaer Date: Mon, 7 May 2018 00:43:26 +0200 Subject: [PATCH 4/8] Add beter handling for Xwayland failing at startup --- xwayland/xwayland.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/xwayland/xwayland.c b/xwayland/xwayland.c index fd5309ad4..d70795e4d 100644 --- a/xwayland/xwayland.c +++ b/xwayland/xwayland.c @@ -178,17 +178,25 @@ static void handle_client_destroy(struct wl_listener *listener, void *data) { struct wlr_xwayland *wlr_xwayland = wl_container_of(listener, wlr_xwayland, client_destroy); + if (wlr_xwayland->sigusr1_source) { + // Xwayland failed to start, let the sigusr1 handler deal with it + return; + } + // Don't call client destroy: it's being destroyed already wlr_xwayland->client = NULL; wl_list_remove(&wlr_xwayland->client_destroy.link); xwayland_finish_server(wlr_xwayland); - if (wlr_xwayland->lazy) { - xwayland_start_server_lazy(wlr_xwayland); - } else if (time(NULL) - wlr_xwayland->server_start > 5) { - wlr_log(L_INFO, "Restarting Xwayland"); - xwayland_start_server(wlr_xwayland); + if (time(NULL) - wlr_xwayland->server_start > 5) { + if (wlr_xwayland->lazy) { + wlr_log(L_INFO, "Restarting Xwayland (lazy)"); + xwayland_start_server_lazy(wlr_xwayland); + } else { + wlr_log(L_INFO, "Restarting Xwayland"); + xwayland_start_server(wlr_xwayland); + } } } From 80586b8f6b254bff4d0701aae8d53ebfb49b876e Mon Sep 17 00:00:00 2001 From: Vincent Vanlaer Date: Mon, 7 May 2018 00:48:02 +0200 Subject: [PATCH 5/8] Clean up events --- xwayland/xwayland.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xwayland/xwayland.c b/xwayland/xwayland.c index d70795e4d..511eb6fc7 100644 --- a/xwayland/xwayland.c +++ b/xwayland/xwayland.c @@ -265,6 +265,8 @@ static int xwayland_socket_connected(int fd, uint32_t mask, void* data){ wl_event_source_remove(wlr_xwayland->x_fd_read_event[0]); wl_event_source_remove(wlr_xwayland->x_fd_read_event[1]); + wlr_xwayland->x_fd_read_event[0] = wlr_xwayland->x_fd_read_event[1] = NULL; + xwayland_start_server(wlr_xwayland); return 0; From 119a6cf35c4163091a699d5987f8d3bab384c95e Mon Sep 17 00:00:00 2001 From: Vincent Vanlaer Date: Tue, 8 May 2018 22:22:35 +0200 Subject: [PATCH 6/8] Make xwayland_finish* clean up wlr_xwayland --- include/wlr/xwayland.h | 22 +++++++++++++--------- xwayland/xwayland.c | 12 ++++++++---- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index a802d32df..d0f378342 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -13,22 +13,26 @@ struct wlr_xwayland_cursor; struct wlr_xwayland { pid_t pid; - int display; - int x_fd[2], wl_fd[2], wm_fd[2]; - struct wl_event_source *x_fd_read_event[2]; struct wl_client *client; - struct wl_display *wl_display; - struct wlr_compositor *compositor; - time_t server_start; - bool lazy; - struct wl_event_source *sigusr1_source; struct wl_listener client_destroy; struct wl_listener display_destroy; struct wlr_xwm *xwm; struct wlr_xwayland_cursor *cursor; + int wm_fd[2], wl_fd[2]; - /* Anything above seat is reset on Xwayland restart, rest is conserved */ + time_t server_start; + + /* Anything above display is reset on Xwayland restart, rest is conserved */ + + int display; + int x_fd[2]; + struct wl_event_source *x_fd_read_event[2]; + + bool lazy; + + struct wl_display *wl_display; + struct wlr_compositor *compositor; struct wlr_seat *seat; struct wl_listener seat_destroy; diff --git a/xwayland/xwayland.c b/xwayland/xwayland.c index 511eb6fc7..22d5cdeb0 100644 --- a/xwayland/xwayland.c +++ b/xwayland/xwayland.c @@ -151,6 +151,10 @@ static void xwayland_finish_server(struct wlr_xwayland *wlr_xwayland) { safe_close(wlr_xwayland->wl_fd[1]); safe_close(wlr_xwayland->wm_fd[0]); safe_close(wlr_xwayland->wm_fd[1]); + memset(wlr_xwayland, 0, offsetof(struct wlr_xwayland, display)); + wlr_xwayland->wl_fd[0] = wlr_xwayland->wl_fd[1] = -1; + wlr_xwayland->wm_fd[0] = wlr_xwayland->wm_fd[1] = -1; + /* We do not kill the Xwayland process, it dies to broken pipe * after we close our side of the wm/wl fds. This is more reliable * than trying to kill something that might no longer be Xwayland. @@ -160,6 +164,7 @@ static void xwayland_finish_server(struct wlr_xwayland *wlr_xwayland) { static void xwayland_finish_display(struct wlr_xwayland *wlr_xwayland) { safe_close(wlr_xwayland->x_fd[0]); safe_close(wlr_xwayland->x_fd[1]); + wlr_xwayland->x_fd[0] = wlr_xwayland->x_fd[1] = -1; wl_list_remove(&wlr_xwayland->display_destroy.link); @@ -274,7 +279,6 @@ static int xwayland_socket_connected(int fd, uint32_t mask, void* data){ static bool xwayland_start_display(struct wlr_xwayland *wlr_xwayland, struct wl_display *wl_display, struct wlr_compositor *compositor) { - wlr_xwayland->x_fd[0] = wlr_xwayland->x_fd[1] = -1; wlr_xwayland->display_destroy.notify = handle_display_destroy; wl_display_add_destroy_listener(wl_display, &wlr_xwayland->display_destroy); @@ -293,8 +297,6 @@ static bool xwayland_start_display(struct wlr_xwayland *wlr_xwayland, } static bool xwayland_start_server(struct wlr_xwayland *wlr_xwayland) { - wlr_xwayland->wl_fd[0] = wlr_xwayland->wl_fd[1] = -1; - wlr_xwayland->wm_fd[0] = wlr_xwayland->wm_fd[1] = -1; if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, wlr_xwayland->wl_fd) != 0 || socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, wlr_xwayland->wm_fd) != 0) { @@ -386,7 +388,9 @@ void wlr_xwayland_destroy(struct wlr_xwayland *wlr_xwayland) { struct wlr_xwayland *wlr_xwayland_create(struct wl_display *wl_display, struct wlr_compositor *compositor, bool lazy) { struct wlr_xwayland *wlr_xwayland = calloc(1, sizeof(struct wlr_xwayland)); - memset(wlr_xwayland, 0, offsetof(struct wlr_xwayland, seat)); + if (!wlr_xwayland) { + return NULL; + } wlr_xwayland->wl_display = wl_display; wlr_xwayland->compositor = compositor; From ef1a24430a5f6d1d3d60c1d506288e3e14f5e077 Mon Sep 17 00:00:00 2001 From: Vincent Vanlaer Date: Tue, 8 May 2018 22:43:31 +0200 Subject: [PATCH 7/8] Make lazy xwayland start default in rootston --- rootston/config.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rootston/config.c b/rootston/config.c index bbdb79906..9a4d77fd8 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -240,9 +240,9 @@ static int config_ini_handler(void *user, const char *section, const char *name, if (strcmp(name, "xwayland") == 0) { if (strcasecmp(value, "true") == 0) { config->xwayland = true; - } else if (strcasecmp(value, "lazy") == 0) { + } else if (strcasecmp(value, "immediate") == 0) { config->xwayland = true; - config->xwayland_lazy = true; + config->xwayland_lazy = false; } else if (strcasecmp(value, "false") == 0) { config->xwayland = false; } else { @@ -392,7 +392,7 @@ struct roots_config *roots_config_create_from_args(int argc, char *argv[]) { } config->xwayland = true; - config->xwayland_lazy = false; + config->xwayland_lazy = true; wl_list_init(&config->outputs); wl_list_init(&config->devices); wl_list_init(&config->keyboards); From 6936be984fbeca83feae96d92bc8fd1d2b0ec4af Mon Sep 17 00:00:00 2001 From: Vincent Vanlaer Date: Tue, 8 May 2018 22:54:45 +0200 Subject: [PATCH 8/8] Document xwayland rootston config changes --- rootston/rootston.ini.example | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rootston/rootston.ini.example b/rootston/rootston.ini.example index 6f29a35dd..556cbefba 100644 --- a/rootston/rootston.ini.example +++ b/rootston/rootston.ini.example @@ -1,5 +1,8 @@ [core] -# Disable X11 support. Enabled by default. +# X11 support +# - true: enables X11, xwayland is started only when an X11 client connects +# - immediate: enables X11, xwayland is started immediately +# - false: disables xwayland xwayland=false # Single output configuration. String after colon must match output's name.