Skip to content

Commit

Permalink
output: Destroy when output layout is destroyed
Browse files Browse the repository at this point in the history
Since output layout is destroyed when the wayland display is destroyed
we run into a destroy listener order problem: Either the display starts
destroying the outputs first, in which case we're good: The existing
handling will clean up. However, things go wrong if the display decides
to destroy the output layout first. In this case, sway will hold
invalid references to the output layout as part of each output so that
when it finally goes to destroy them, sway will dereference destroyed
output layout bits.

Ref: #6844 (comment)
  • Loading branch information
Nefsen402 authored and emersion committed Dec 13, 2023
1 parent c6edbb7 commit bbabb9a
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 2 deletions.
1 change: 1 addition & 0 deletions include/sway/output.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ struct sway_output {

struct sway_output_state current;

struct wl_listener layout_destroy;
struct wl_listener destroy;
struct wl_listener commit;
struct wl_listener present;
Expand Down
16 changes: 14 additions & 2 deletions sway/desktop/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -892,8 +892,7 @@ static void update_output_manager_config(struct sway_server *server) {
ipc_event_output();
}

static void handle_destroy(struct wl_listener *listener, void *data) {
struct sway_output *output = wl_container_of(listener, output, destroy);
static void begin_destroy(struct sway_output *output) {
struct sway_server *server = output->server;

if (output->enabled) {
Expand All @@ -904,6 +903,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) {

wl_list_remove(&output->link);

wl_list_remove(&output->layout_destroy.link);
wl_list_remove(&output->destroy.link);
wl_list_remove(&output->commit.link);
wl_list_remove(&output->present.link);
Expand All @@ -922,6 +922,16 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
update_output_manager_config(server);
}

static void handle_destroy(struct wl_listener *listener, void *data) {
struct sway_output *output = wl_container_of(listener, output, destroy);
begin_destroy(output);
}

static void handle_layout_destroy(struct wl_listener *listener, void *data) {
struct sway_output *output = wl_container_of(listener, output, layout_destroy);
begin_destroy(output);
}

static void update_textures(struct sway_container *con, void *data) {
container_update_title_textures(con);
container_update_marks_textures(con);
Expand Down Expand Up @@ -1036,6 +1046,8 @@ void handle_new_output(struct wl_listener *listener, void *data) {
output->server = server;
wlr_damage_ring_init(&output->damage_ring);

wl_signal_add(&root->output_layout->events.destroy, &output->layout_destroy);
output->layout_destroy.notify = handle_layout_destroy;
wl_signal_add(&wlr_output->events.destroy, &output->destroy);
output->destroy.notify = handle_destroy;
wl_signal_add(&wlr_output->events.commit, &output->commit);
Expand Down

0 comments on commit bbabb9a

Please sign in to comment.