From bb0d888f2500290693232704c2a477cf321cdec6 Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Fri, 29 Dec 2017 16:30:59 +0100 Subject: xwayland selection: further cleanup on Xwayland exit This is necessary if our last primary/clipboard selection was on Xwayland, and we try to paste to native wayland after Xwayland died --- include/wlr/xwm.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/wlr') diff --git a/include/wlr/xwm.h b/include/wlr/xwm.h index cbc2f132..35c43b18 100644 --- a/include/wlr/xwm.h +++ b/include/wlr/xwm.h @@ -108,6 +108,7 @@ void xwm_set_cursor(struct wlr_xwm *xwm, const uint8_t *pixels, uint32_t stride, int xwm_handle_selection_event(struct wlr_xwm *xwm, xcb_generic_event_t *event); void xwm_selection_init(struct wlr_xwm *xwm); +void xwm_selection_finish(struct wlr_xwm *xwm); void xwm_set_seat(struct wlr_xwm *xwm, struct wlr_seat *seat); -- cgit v1.2.3 From 58488ec5ce9254334bf3cfef986dfd7deeb62549 Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Fri, 29 Dec 2017 17:55:03 +0100 Subject: wlr_seat: add destroy signal --- include/wlr/types/wlr_seat.h | 2 ++ types/wlr_seat.c | 4 ++++ 2 files changed, 6 insertions(+) (limited to 'include/wlr') diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h index f7dea52f..e049d4c7 100644 --- a/include/wlr/types/wlr_seat.h +++ b/include/wlr/types/wlr_seat.h @@ -207,6 +207,8 @@ struct wlr_seat { struct wl_signal selection; struct wl_signal primary_selection; + + struct wl_signal destroy; } events; void *data; diff --git a/types/wlr_seat.c b/types/wlr_seat.c index 2a79f784..40143723 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -348,6 +348,8 @@ void wlr_seat_destroy(struct wlr_seat *wlr_seat) { return; } + wl_signal_emit(&wlr_seat->events.destroy, NULL); + wl_list_remove(&wlr_seat->display_destroy.link); struct wlr_seat_client *client, *tmp; @@ -453,6 +455,8 @@ struct wlr_seat *wlr_seat_create(struct wl_display *display, const char *name) { wl_signal_init(&wlr_seat->events.touch_grab_begin); wl_signal_init(&wlr_seat->events.touch_grab_end); + wl_signal_init(&wlr_seat->events.destroy); + wlr_seat->display_destroy.notify = handle_display_destroy; wl_display_add_destroy_listener(display, &wlr_seat->display_destroy); -- cgit v1.2.3 From e0eafa04293496b95f29fdaf42703f1fc1e29e2e Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Fri, 29 Dec 2017 17:55:16 +0100 Subject: xwayland: listen to wlr_seat destroy signal --- include/wlr/xwayland.h | 1 + xwayland/xwayland.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) (limited to 'include/wlr') diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index 8d71a7ab..d4590f97 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -28,6 +28,7 @@ struct wlr_xwayland { struct wl_event_source *sigusr1_source; struct wl_listener client_destroy; struct wl_listener display_destroy; + struct wl_listener seat_destroy; struct wlr_xwm *xwm; struct wlr_xwayland_cursor *cursor; diff --git a/xwayland/xwayland.c b/xwayland/xwayland.c index a0b6d1c3..e181d261 100644 --- a/xwayland/xwayland.c +++ b/xwayland/xwayland.c @@ -134,6 +134,7 @@ static void wlr_xwayland_finish(struct wlr_xwayland *wlr_xwayland) { free(wlr_xwayland->cursor); } + wlr_xwayland_set_seat(wlr_xwayland, NULL); xwm_destroy(wlr_xwayland->xwm); if (wlr_xwayland->client) { @@ -388,11 +389,30 @@ void wlr_xwayland_set_cursor(struct wlr_xwayland *wlr_xwayland, wlr_xwayland->cursor->hotspot_y = hotspot_y; } +static void wlr_xwayland_handle_seat_destroy(struct wl_listener *listener, + void *data) { + struct wlr_xwayland *xwayland = + wl_container_of(listener, xwayland, seat_destroy); + + wlr_xwayland_set_seat(xwayland, NULL); +} + void wlr_xwayland_set_seat(struct wlr_xwayland *xwayland, struct wlr_seat *seat) { + if (xwayland->seat) { + wl_list_remove(&xwayland->seat_destroy.link); + } + xwayland->seat = seat; if (xwayland->xwm) { xwm_set_seat(xwayland->xwm, seat); } + + if (seat == NULL) { + return; + } + + xwayland->seat_destroy.notify = wlr_xwayland_handle_seat_destroy; + wl_signal_add(&seat->events.destroy, &xwayland->seat_destroy); } -- cgit v1.2.3 From ec952931a18cc21c99f20424b190590f9c769ae1 Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Fri, 29 Dec 2017 20:50:50 +0100 Subject: wlr_xwayland: preserve end of struct on restart This is more robust than trying to recopy a few fields. Note: wlr_xwayland->events.ready now resets after each trigger, so one can hook on it again and be called when restart is ready --- include/wlr/xwayland.h | 6 ++++-- xwayland/xwayland.c | 34 +++++++++++----------------------- 2 files changed, 15 insertions(+), 25 deletions(-) (limited to 'include/wlr') diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index d4590f97..b6671de1 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -22,16 +22,18 @@ struct wlr_xwayland { struct wl_client *client; struct wl_display *wl_display; struct wlr_compositor *compositor; - struct wlr_seat *seat; time_t server_start; struct wl_event_source *sigusr1_source; struct wl_listener client_destroy; struct wl_listener display_destroy; - struct wl_listener seat_destroy; struct wlr_xwm *xwm; struct wlr_xwayland_cursor *cursor; + /* Anything above seat is reset on Xwayland restart, rest is conserved */ + struct wlr_seat *seat; + struct wl_listener seat_destroy; + struct { struct wl_signal ready; struct wl_signal new_surface; diff --git a/xwayland/xwayland.c b/xwayland/xwayland.c index e181d261..6c700cc5 100644 --- a/xwayland/xwayland.c +++ b/xwayland/xwayland.c @@ -134,7 +134,6 @@ static void wlr_xwayland_finish(struct wlr_xwayland *wlr_xwayland) { free(wlr_xwayland->cursor); } - wlr_xwayland_set_seat(wlr_xwayland, NULL); xwm_destroy(wlr_xwayland->xwm); if (wlr_xwayland->client) { @@ -163,21 +162,13 @@ static void wlr_xwayland_finish(struct wlr_xwayland *wlr_xwayland) { */ } -static bool wlr_xwayland_init(struct wlr_xwayland *wlr_xwayland, +static bool wlr_xwayland_start(struct wlr_xwayland *wlr_xwayland, struct wl_display *wl_display, struct wlr_compositor *compositor); static void handle_client_destroy(struct wl_listener *listener, void *data) { struct wlr_xwayland *wlr_xwayland = wl_container_of(listener, wlr_xwayland, client_destroy); - struct wlr_seat *seat = wlr_xwayland->seat; - struct wl_list new_surface_signals; - struct wl_listener *new_surface_listener, *next; - wl_list_init(&new_surface_signals); - wl_list_for_each_safe(new_surface_listener, next, &wlr_xwayland->events.new_surface.listener_list, link) { - wl_list_remove(&new_surface_listener->link); - wl_list_insert(&new_surface_signals, &new_surface_listener->link); - } // Don't call client destroy: it's being destroyed already wlr_xwayland->client = NULL; wl_list_remove(&wlr_xwayland->client_destroy.link); @@ -186,15 +177,8 @@ static void handle_client_destroy(struct wl_listener *listener, void *data) { if (time(NULL) - wlr_xwayland->server_start > 5) { wlr_log(L_INFO, "Restarting Xwayland"); - wlr_xwayland_init(wlr_xwayland, wlr_xwayland->wl_display, + wlr_xwayland_start(wlr_xwayland, wlr_xwayland->wl_display, wlr_xwayland->compositor); - wl_list_for_each_safe(new_surface_listener, next, &new_surface_signals, link) { - wl_list_remove(&new_surface_listener->link); - wl_signal_add(&wlr_xwayland->events.new_surface, new_surface_listener); - } - if (seat) { - wlr_xwayland_set_seat(wlr_xwayland, seat); - } } } @@ -254,20 +238,20 @@ static int xserver_handle_ready(int signal_number, void *data) { setenv("DISPLAY", display_name, true); wl_signal_emit(&wlr_xwayland->events.ready, wlr_xwayland); + /* ready is a one-shot signal, fire and forget */ + wl_signal_init(&wlr_xwayland->events.ready); return 1; /* wayland event loop dispatcher's count */ } -static bool wlr_xwayland_init(struct wlr_xwayland *wlr_xwayland, +static bool wlr_xwayland_start(struct wlr_xwayland *wlr_xwayland, struct wl_display *wl_display, struct wlr_compositor *compositor) { - memset(wlr_xwayland, 0, 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->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); wlr_xwayland->display_destroy.notify = handle_display_destroy; wl_display_add_destroy_listener(wl_display, &wlr_xwayland->display_destroy); @@ -352,6 +336,7 @@ static bool wlr_xwayland_init(struct wlr_xwayland *wlr_xwayland, } void wlr_xwayland_destroy(struct wlr_xwayland *wlr_xwayland) { + wlr_xwayland_set_seat(wlr_xwayland, NULL); wlr_xwayland_finish(wlr_xwayland); free(wlr_xwayland); } @@ -359,7 +344,10 @@ void wlr_xwayland_destroy(struct wlr_xwayland *wlr_xwayland) { struct wlr_xwayland *wlr_xwayland_create(struct wl_display *wl_display, struct wlr_compositor *compositor) { struct wlr_xwayland *wlr_xwayland = calloc(1, sizeof(struct wlr_xwayland)); - if (wlr_xwayland_init(wlr_xwayland, wl_display, compositor)) { + + wl_signal_init(&wlr_xwayland->events.new_surface); + wl_signal_init(&wlr_xwayland->events.ready); + if (wlr_xwayland_start(wlr_xwayland, wl_display, compositor)) { return wlr_xwayland; } free(wlr_xwayland); -- cgit v1.2.3