aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Alexander Orzechowski <alex@ozal.ski>2023-12-06 15:47:24 -0500
committerLibravatar Simon Ser <contact@emersion.fr>2023-12-13 18:10:03 +0100
commitbbabb9aae8d7b7771d02489b6f20301cf1c090c9 (patch)
tree4f012efa2b612cf580c58596a173520eeb17c40d
parentinput/seat: simplify seat_is_input_allowed() (diff)
downloadsway-bbabb9aae8d7b7771d02489b6f20301cf1c090c9.tar.gz
sway-bbabb9aae8d7b7771d02489b6f20301cf1c090c9.tar.zst
sway-bbabb9aae8d7b7771d02489b6f20301cf1c090c9.zip
output: Destroy when output layout is destroyed
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: https://github.com/swaywm/sway/pull/6844#issuecomment-1843599513
-rw-r--r--include/sway/output.h1
-rw-r--r--sway/desktop/output.c16
2 files changed, 15 insertions, 2 deletions
diff --git a/include/sway/output.h b/include/sway/output.h
index 62d866bc..43cbccd2 100644
--- a/include/sway/output.h
+++ b/include/sway/output.h
@@ -39,6 +39,7 @@ struct sway_output {
39 39
40 struct sway_output_state current; 40 struct sway_output_state current;
41 41
42 struct wl_listener layout_destroy;
42 struct wl_listener destroy; 43 struct wl_listener destroy;
43 struct wl_listener commit; 44 struct wl_listener commit;
44 struct wl_listener present; 45 struct wl_listener present;
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index d9328701..d525b2b4 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -892,8 +892,7 @@ static void update_output_manager_config(struct sway_server *server) {
892 ipc_event_output(); 892 ipc_event_output();
893} 893}
894 894
895static void handle_destroy(struct wl_listener *listener, void *data) { 895static void begin_destroy(struct sway_output *output) {
896 struct sway_output *output = wl_container_of(listener, output, destroy);
897 struct sway_server *server = output->server; 896 struct sway_server *server = output->server;
898 897
899 if (output->enabled) { 898 if (output->enabled) {
@@ -904,6 +903,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
904 903
905 wl_list_remove(&output->link); 904 wl_list_remove(&output->link);
906 905
906 wl_list_remove(&output->layout_destroy.link);
907 wl_list_remove(&output->destroy.link); 907 wl_list_remove(&output->destroy.link);
908 wl_list_remove(&output->commit.link); 908 wl_list_remove(&output->commit.link);
909 wl_list_remove(&output->present.link); 909 wl_list_remove(&output->present.link);
@@ -922,6 +922,16 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
922 update_output_manager_config(server); 922 update_output_manager_config(server);
923} 923}
924 924
925static void handle_destroy(struct wl_listener *listener, void *data) {
926 struct sway_output *output = wl_container_of(listener, output, destroy);
927 begin_destroy(output);
928}
929
930static void handle_layout_destroy(struct wl_listener *listener, void *data) {
931 struct sway_output *output = wl_container_of(listener, output, layout_destroy);
932 begin_destroy(output);
933}
934
925static void update_textures(struct sway_container *con, void *data) { 935static void update_textures(struct sway_container *con, void *data) {
926 container_update_title_textures(con); 936 container_update_title_textures(con);
927 container_update_marks_textures(con); 937 container_update_marks_textures(con);
@@ -1036,6 +1046,8 @@ void handle_new_output(struct wl_listener *listener, void *data) {
1036 output->server = server; 1046 output->server = server;
1037 wlr_damage_ring_init(&output->damage_ring); 1047 wlr_damage_ring_init(&output->damage_ring);
1038 1048
1049 wl_signal_add(&root->output_layout->events.destroy, &output->layout_destroy);
1050 output->layout_destroy.notify = handle_layout_destroy;
1039 wl_signal_add(&wlr_output->events.destroy, &output->destroy); 1051 wl_signal_add(&wlr_output->events.destroy, &output->destroy);
1040 output->destroy.notify = handle_destroy; 1052 output->destroy.notify = handle_destroy;
1041 wl_signal_add(&wlr_output->events.commit, &output->commit); 1053 wl_signal_add(&wlr_output->events.commit, &output->commit);