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>2024-01-26 15:14:24 +0100
commit80ea52910a15a5065922f8ecbac46e5024a89da9 (patch)
tree66c3384d0a5a57c3a3e66bdc63ecb1c8b414747a
parentsway: raise error on non-accessible background file (diff)
downloadsway-80ea52910a15a5065922f8ecbac46e5024a89da9.tar.gz
sway-80ea52910a15a5065922f8ecbac46e5024a89da9.tar.zst
sway-80ea52910a15a5065922f8ecbac46e5024a89da9.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 (cherry picked from commit bbabb9aae8d7b7771d02489b6f20301cf1c090c9)
-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 e02ab32d..bb61e1bd 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -891,8 +891,7 @@ static void update_output_manager_config(struct sway_server *server) {
891 ipc_event_output(); 891 ipc_event_output();
892} 892}
893 893
894static void handle_destroy(struct wl_listener *listener, void *data) { 894static void begin_destroy(struct sway_output *output) {
895 struct sway_output *output = wl_container_of(listener, output, destroy);
896 struct sway_server *server = output->server; 895 struct sway_server *server = output->server;
897 896
898 if (output->enabled) { 897 if (output->enabled) {
@@ -903,6 +902,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
903 902
904 wl_list_remove(&output->link); 903 wl_list_remove(&output->link);
905 904
905 wl_list_remove(&output->layout_destroy.link);
906 wl_list_remove(&output->destroy.link); 906 wl_list_remove(&output->destroy.link);
907 wl_list_remove(&output->commit.link); 907 wl_list_remove(&output->commit.link);
908 wl_list_remove(&output->present.link); 908 wl_list_remove(&output->present.link);
@@ -921,6 +921,16 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
921 update_output_manager_config(server); 921 update_output_manager_config(server);
922} 922}
923 923
924static void handle_destroy(struct wl_listener *listener, void *data) {
925 struct sway_output *output = wl_container_of(listener, output, destroy);
926 begin_destroy(output);
927}
928
929static void handle_layout_destroy(struct wl_listener *listener, void *data) {
930 struct sway_output *output = wl_container_of(listener, output, layout_destroy);
931 begin_destroy(output);
932}
933
924static void update_textures(struct sway_container *con, void *data) { 934static void update_textures(struct sway_container *con, void *data) {
925 container_update_title_textures(con); 935 container_update_title_textures(con);
926 container_update_marks_textures(con); 936 container_update_marks_textures(con);
@@ -1035,6 +1045,8 @@ void handle_new_output(struct wl_listener *listener, void *data) {
1035 output->server = server; 1045 output->server = server;
1036 wlr_damage_ring_init(&output->damage_ring); 1046 wlr_damage_ring_init(&output->damage_ring);
1037 1047
1048 wl_signal_add(&root->output_layout->events.destroy, &output->layout_destroy);
1049 output->layout_destroy.notify = handle_layout_destroy;
1038 wl_signal_add(&wlr_output->events.destroy, &output->destroy); 1050 wl_signal_add(&wlr_output->events.destroy, &output->destroy);
1039 output->destroy.notify = handle_destroy; 1051 output->destroy.notify = handle_destroy;
1040 wl_signal_add(&wlr_output->events.commit, &output->commit); 1052 wl_signal_add(&wlr_output->events.commit, &output->commit);