diff options
author | Drew DeVault <sir@cmpwn.com> | 2017-11-25 16:30:15 -0500 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2017-11-25 16:30:15 -0500 |
commit | 8caabe59c2e6f6174678e6c28be3381a7dabff10 (patch) | |
tree | 5425efb1f3b68e9b275d8429bba70a2b132b72c9 | |
parent | Fix rendering issues, wire up some xdg listeners (diff) | |
download | sway-8caabe59c2e6f6174678e6c28be3381a7dabff10.tar.gz sway-8caabe59c2e6f6174678e6c28be3381a7dabff10.tar.zst sway-8caabe59c2e6f6174678e6c28be3381a7dabff10.zip |
Handle view destruction properly
-rw-r--r-- | include/sway/container.h | 2 | ||||
-rw-r--r-- | include/sway/layout.h | 1 | ||||
-rw-r--r-- | include/sway/view.h | 2 | ||||
-rw-r--r-- | sway/desktop/xdg_shell_v6.c | 15 | ||||
-rw-r--r-- | sway/tree/container.c | 42 | ||||
-rw-r--r-- | sway/tree/layout.c | 13 |
6 files changed, 73 insertions, 2 deletions
diff --git a/include/sway/container.h b/include/sway/container.h index 1a173f3e..08a98ed9 100644 --- a/include/sway/container.h +++ b/include/sway/container.h | |||
@@ -132,6 +132,8 @@ swayc_t *new_output(struct sway_output *sway_output); | |||
132 | swayc_t *new_workspace(swayc_t *output, const char *name); | 132 | swayc_t *new_workspace(swayc_t *output, const char *name); |
133 | swayc_t *new_view(swayc_t *sibling, struct sway_view *sway_view); | 133 | swayc_t *new_view(swayc_t *sibling, struct sway_view *sway_view); |
134 | 134 | ||
135 | swayc_t *destroy_view(swayc_t *view); | ||
136 | |||
135 | swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type); | 137 | swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type); |
136 | 138 | ||
137 | #endif | 139 | #endif |
diff --git a/include/sway/layout.h b/include/sway/layout.h index 505036a0..f3b62b05 100644 --- a/include/sway/layout.h +++ b/include/sway/layout.h | |||
@@ -5,6 +5,7 @@ struct sway_container; | |||
5 | 5 | ||
6 | void init_layout(void); | 6 | void init_layout(void); |
7 | void add_child(struct sway_container *parent, struct sway_container *child); | 7 | void add_child(struct sway_container *parent, struct sway_container *child); |
8 | struct sway_container *remove_child(struct sway_container *child); | ||
8 | enum swayc_layouts default_layout(struct sway_container *output); | 9 | enum swayc_layouts default_layout(struct sway_container *output); |
9 | void sort_workspaces(struct sway_container *output); | 10 | void sort_workspaces(struct sway_container *output); |
10 | void arrange_windows(struct sway_container *container, double width, double height); | 11 | void arrange_windows(struct sway_container *container, double width, double height); |
diff --git a/include/sway/view.h b/include/sway/view.h index fca444b7..2707ca78 100644 --- a/include/sway/view.h +++ b/include/sway/view.h | |||
@@ -14,6 +14,7 @@ struct sway_xdg_surface_v6 { | |||
14 | struct wl_listener request_move; | 14 | struct wl_listener request_move; |
15 | struct wl_listener request_resize; | 15 | struct wl_listener request_resize; |
16 | struct wl_listener request_maximize; | 16 | struct wl_listener request_maximize; |
17 | struct wl_listener destroy; | ||
17 | 18 | ||
18 | int pending_width, pending_height; | 19 | int pending_width, pending_height; |
19 | }; | 20 | }; |
@@ -38,7 +39,6 @@ enum sway_view_prop { | |||
38 | * tree (shell surfaces). | 39 | * tree (shell surfaces). |
39 | */ | 40 | */ |
40 | struct sway_view { | 41 | struct sway_view { |
41 | struct wl_listener destroy; | ||
42 | enum sway_view_type type; | 42 | enum sway_view_type type; |
43 | struct sway_container *swayc; | 43 | struct sway_container *swayc; |
44 | struct wlr_surface *surface; | 44 | struct wlr_surface *surface; |
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 94682fcd..45e443fc 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c | |||
@@ -44,11 +44,22 @@ static void handle_commit(struct wl_listener *listener, void *data) { | |||
44 | sway_log(L_DEBUG, "xdg surface commit %dx%d", | 44 | sway_log(L_DEBUG, "xdg surface commit %dx%d", |
45 | sway_surface->pending_width, sway_surface->pending_height); | 45 | sway_surface->pending_width, sway_surface->pending_height); |
46 | // NOTE: We intentionally discard the view's desired width here | 46 | // NOTE: We intentionally discard the view's desired width here |
47 | // TODO: Don't do that for floating views | 47 | // TODO: Let floating views do whatever |
48 | view->width = sway_surface->pending_width; | 48 | view->width = sway_surface->pending_width; |
49 | view->height = sway_surface->pending_height; | 49 | view->height = sway_surface->pending_height; |
50 | } | 50 | } |
51 | 51 | ||
52 | static void handle_destroy(struct wl_listener *listener, void *data) { | ||
53 | struct sway_xdg_surface_v6 *sway_xdg_surface = | ||
54 | wl_container_of(listener, sway_xdg_surface, destroy); | ||
55 | wl_list_remove(&sway_xdg_surface->commit.link); | ||
56 | wl_list_remove(&sway_xdg_surface->destroy.link); | ||
57 | swayc_t *parent = destroy_view(sway_xdg_surface->view->swayc); | ||
58 | free(sway_xdg_surface->view); | ||
59 | free(sway_xdg_surface); | ||
60 | arrange_windows(parent, -1, -1); | ||
61 | } | ||
62 | |||
52 | void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { | 63 | void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { |
53 | struct sway_server *server = wl_container_of( | 64 | struct sway_server *server = wl_container_of( |
54 | listener, server, xdg_shell_v6_surface); | 65 | listener, server, xdg_shell_v6_surface); |
@@ -90,6 +101,8 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { | |||
90 | 101 | ||
91 | sway_surface->commit.notify = handle_commit; | 102 | sway_surface->commit.notify = handle_commit; |
92 | wl_signal_add(&xdg_surface->events.commit, &sway_surface->commit); | 103 | wl_signal_add(&xdg_surface->events.commit, &sway_surface->commit); |
104 | sway_surface->destroy.notify = handle_destroy; | ||
105 | wl_signal_add(&xdg_surface->events.destroy, &sway_surface->destroy); | ||
93 | 106 | ||
94 | // TODO: actual focus semantics | 107 | // TODO: actual focus semantics |
95 | swayc_t *parent = root_container.children->items[0]; | 108 | swayc_t *parent = root_container.children->items[0]; |
diff --git a/sway/tree/container.c b/sway/tree/container.c index a83c0f6b..c7bce38a 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -109,6 +109,48 @@ swayc_t *new_view(swayc_t *sibling, struct sway_view *sway_view) { | |||
109 | return swayc; | 109 | return swayc; |
110 | } | 110 | } |
111 | 111 | ||
112 | static void free_swayc(swayc_t *cont) { | ||
113 | if (!sway_assert(cont, "free_swayc passed NULL")) { | ||
114 | return; | ||
115 | } | ||
116 | if (cont->children) { | ||
117 | // remove children until there are no more, free_swayc calls | ||
118 | // remove_child, which removes child from this container | ||
119 | while (cont->children->length) { | ||
120 | free_swayc(cont->children->items[0]); | ||
121 | } | ||
122 | list_free(cont->children); | ||
123 | } | ||
124 | if (cont->marks) { | ||
125 | list_foreach(cont->marks, free); | ||
126 | list_free(cont->marks); | ||
127 | } | ||
128 | if (cont->parent) { | ||
129 | remove_child(cont); | ||
130 | } | ||
131 | if (cont->name) { | ||
132 | free(cont->name); | ||
133 | } | ||
134 | free(cont); | ||
135 | } | ||
136 | |||
137 | swayc_t *destroy_view(swayc_t *view) { | ||
138 | if (!sway_assert(view, "null view passed to destroy_view")) { | ||
139 | return NULL; | ||
140 | } | ||
141 | sway_log(L_DEBUG, "Destroying view '%s'", view->name); | ||
142 | swayc_t *parent = view->parent; | ||
143 | free_swayc(view); | ||
144 | |||
145 | // TODO WLR: Destroy empty containers | ||
146 | /* | ||
147 | if (parent && parent->type == C_CONTAINER) { | ||
148 | return destroy_container(parent); | ||
149 | } | ||
150 | */ | ||
151 | return parent; | ||
152 | } | ||
153 | |||
112 | swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) { | 154 | swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) { |
113 | if (!sway_assert(container, "container is NULL")) { | 155 | if (!sway_assert(container, "container is NULL")) { |
114 | return NULL; | 156 | return NULL; |
diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 6e2586a7..ea7bb8bb 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c | |||
@@ -40,6 +40,19 @@ void add_child(swayc_t *parent, swayc_t *child) { | |||
40 | */ | 40 | */ |
41 | } | 41 | } |
42 | 42 | ||
43 | swayc_t *remove_child(swayc_t *child) { | ||
44 | int i; | ||
45 | swayc_t *parent = child->parent; | ||
46 | for (i = 0; i < parent->children->length; ++i) { | ||
47 | if (parent->children->items[i] == child) { | ||
48 | list_del(parent->children, i); | ||
49 | break; | ||
50 | } | ||
51 | } | ||
52 | child->parent = NULL; | ||
53 | return parent; | ||
54 | } | ||
55 | |||
43 | enum swayc_layouts default_layout(swayc_t *output) { | 56 | enum swayc_layouts default_layout(swayc_t *output) { |
44 | /* TODO WLR | 57 | /* TODO WLR |
45 | if (config->default_layout != L_NONE) { | 58 | if (config->default_layout != L_NONE) { |