Fix swaylock crashing when unplugging output

master
emersion 7 years ago
parent c2c5a3f5f6
commit e4dbafe4d8
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48

@ -48,6 +48,7 @@ struct swaylock_surface {
cairo_surface_t *image; cairo_surface_t *image;
struct swaylock_state *state; struct swaylock_state *state;
struct wl_output *output; struct wl_output *output;
uint32_t output_global_name;
struct wl_surface *surface; struct wl_surface *surface;
struct zwlr_layer_surface_v1 *layer_surface; struct zwlr_layer_surface_v1 *layer_surface;
struct pool_buffer buffers[2]; struct pool_buffer buffers[2];

@ -61,6 +61,20 @@ static void daemonize() {
} }
} }
static void destroy_surface(struct swaylock_surface *surface) {
wl_list_remove(&surface->link);
if (surface->layer_surface != NULL) {
zwlr_layer_surface_v1_destroy(surface->layer_surface);
}
if (surface->surface != NULL) {
wl_surface_destroy(surface->surface);
}
destroy_buffer(&surface->buffers[0]);
destroy_buffer(&surface->buffers[1]);
wl_output_destroy(surface->output);
free(surface);
}
static void layer_surface_configure(void *data, static void layer_surface_configure(void *data,
struct zwlr_layer_surface_v1 *layer_surface, struct zwlr_layer_surface_v1 *layer_surface,
uint32_t serial, uint32_t width, uint32_t height) { uint32_t serial, uint32_t width, uint32_t height) {
@ -74,9 +88,7 @@ static void layer_surface_configure(void *data,
static void layer_surface_closed(void *data, static void layer_surface_closed(void *data,
struct zwlr_layer_surface_v1 *layer_surface) { struct zwlr_layer_surface_v1 *layer_surface) {
struct swaylock_surface *surface = data; struct swaylock_surface *surface = data;
zwlr_layer_surface_v1_destroy(surface->layer_surface); destroy_surface(surface);
wl_surface_destroy(surface->surface);
surface->state->run_display = false;
} }
static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { static const struct zwlr_layer_surface_v1_listener layer_surface_listener = {
@ -139,6 +151,7 @@ static void handle_global(void *data, struct wl_registry *registry,
surface->state = state; surface->state = state;
surface->output = wl_registry_bind(registry, name, surface->output = wl_registry_bind(registry, name,
&wl_output_interface, 3); &wl_output_interface, 3);
surface->output_global_name = name;
wl_output_add_listener(surface->output, &output_listener, surface); wl_output_add_listener(surface->output, &output_listener, surface);
wl_list_insert(&state->surfaces, &surface->link); wl_list_insert(&state->surfaces, &surface->link);
} }
@ -146,7 +159,14 @@ static void handle_global(void *data, struct wl_registry *registry,
static void handle_global_remove(void *data, struct wl_registry *registry, static void handle_global_remove(void *data, struct wl_registry *registry,
uint32_t name) { uint32_t name) {
// who cares struct swaylock_state *state = data;
struct swaylock_surface *surface;
wl_list_for_each(surface, &state->surfaces, link) {
if (surface->output_global_name == name) {
destroy_surface(surface);
break;
}
}
} }
static const struct wl_registry_listener registry_listener = { static const struct wl_registry_listener registry_listener = {

Loading…
Cancel
Save