diff --git a/backend/drm/drm.c b/backend/drm/drm.c index bed6ba497..727832c6b 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -1215,6 +1215,8 @@ static void dealloc_crtc(struct wlr_drm_connector *conn); static void drm_connector_destroy_output(struct wlr_output *output) { struct wlr_drm_connector *conn = get_drm_connector_from_output(output); + wlr_output_finish(output); + dealloc_crtc(conn); conn->status = DRM_MODE_DISCONNECTED; diff --git a/backend/headless/output.c b/backend/headless/output.c index 5a00e2e91..4d983a72a 100644 --- a/backend/headless/output.c +++ b/backend/headless/output.c @@ -80,8 +80,10 @@ static bool output_commit(struct wlr_output *wlr_output, } static void output_destroy(struct wlr_output *wlr_output) { - struct wlr_headless_output *output = - headless_output_from_output(wlr_output); + struct wlr_headless_output *output = headless_output_from_output(wlr_output); + + wlr_output_finish(wlr_output); + wl_list_remove(&output->link); wl_event_source_remove(output->frame_timer); free(output); diff --git a/backend/wayland/output.c b/backend/wayland/output.c index 5bc05f947..c3e4866da 100644 --- a/backend/wayland/output.c +++ b/backend/wayland/output.c @@ -933,6 +933,8 @@ static void output_destroy(struct wlr_output *wlr_output) { return; } + wlr_output_finish(wlr_output); + wl_list_remove(&output->link); if (output->cursor.surface) { diff --git a/backend/x11/output.c b/backend/x11/output.c index 67f1dae95..0b63a7088 100644 --- a/backend/x11/output.c +++ b/backend/x11/output.c @@ -94,6 +94,8 @@ static void output_destroy(struct wlr_output *wlr_output) { struct wlr_x11_output *output = get_x11_output_from_output(wlr_output); struct wlr_x11_backend *x11 = output->x11; + wlr_output_finish(wlr_output); + pixman_region32_fini(&output->exposed); wlr_pointer_finish(&output->pointer); diff --git a/include/wlr/interfaces/wlr_output.h b/include/wlr/interfaces/wlr_output.h index 2a40a0fe3..6da2c2c54 100644 --- a/include/wlr/interfaces/wlr_output.h +++ b/include/wlr/interfaces/wlr_output.h @@ -108,6 +108,10 @@ struct wlr_output_impl { void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend, const struct wlr_output_impl *impl, struct wl_event_loop *event_loop, const struct wlr_output_state *state); +/** + * Emit the destroy event and clean up common output state. + */ +void wlr_output_finish(struct wlr_output *output); /** * Notify compositors that they need to submit a new frame in order to apply * output changes. diff --git a/types/output/output.c b/types/output/output.c index 4cded1ab2..7bfdf9c77 100644 --- a/types/output/output.c +++ b/types/output/output.c @@ -375,11 +375,7 @@ void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend, } } -void wlr_output_destroy(struct wlr_output *output) { - if (!output) { - return; - } - +void wlr_output_finish(struct wlr_output *output) { wl_signal_emit_mutable(&output->events.destroy, output); wlr_output_destroy_global(output); @@ -418,10 +414,17 @@ void wlr_output_destroy(struct wlr_output *output) { free(output->make); free(output->model); free(output->serial); +} + +void wlr_output_destroy(struct wlr_output *output) { + if (!output) { + return; + } if (output->impl && output->impl->destroy) { output->impl->destroy(output); } else { + wlr_output_finish(output); free(output); } }