diff options
-rw-r--r-- | include/sway/server.h | 1 | ||||
-rw-r--r-- | include/sway/tree/container.h | 8 | ||||
-rw-r--r-- | include/sway/tree/layout.h | 3 | ||||
-rw-r--r-- | sway/desktop/output.c | 25 | ||||
-rw-r--r-- | sway/desktop/xwayland.c | 36 | ||||
-rw-r--r-- | sway/input/seat.c | 4 | ||||
-rw-r--r-- | sway/server.c | 18 | ||||
-rw-r--r-- | sway/tree/container.c | 55 | ||||
-rw-r--r-- | sway/tree/layout.c | 37 |
9 files changed, 138 insertions, 49 deletions
diff --git a/include/sway/server.h b/include/sway/server.h index 25eb64fe..db81932f 100644 --- a/include/sway/server.h +++ b/include/sway/server.h | |||
@@ -18,7 +18,6 @@ struct sway_server { | |||
18 | const char *socket; | 18 | const char *socket; |
19 | 19 | ||
20 | struct wlr_backend *backend; | 20 | struct wlr_backend *backend; |
21 | struct wlr_renderer *renderer; | ||
22 | 21 | ||
23 | struct wlr_compositor *compositor; | 22 | struct wlr_compositor *compositor; |
24 | struct wlr_data_device_manager *data_device_manager; | 23 | struct wlr_data_device_manager *data_device_manager; |
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 3bb497db..24e8468e 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h | |||
@@ -99,8 +99,13 @@ struct sway_container *container_view_create( | |||
99 | 99 | ||
100 | struct sway_container *container_output_destroy(struct sway_container *output); | 100 | struct sway_container *container_output_destroy(struct sway_container *output); |
101 | 101 | ||
102 | struct sway_container *container_workspace_destroy( | ||
103 | struct sway_container *workspace); | ||
104 | |||
102 | struct sway_container *container_view_destroy(struct sway_container *view); | 105 | struct sway_container *container_view_destroy(struct sway_container *view); |
103 | 106 | ||
107 | void container_destroy(struct sway_container *cont); | ||
108 | |||
104 | struct sway_container *container_set_layout(struct sway_container *container, | 109 | struct sway_container *container_set_layout(struct sway_container *container, |
105 | enum sway_container_layout layout); | 110 | enum sway_container_layout layout); |
106 | 111 | ||
@@ -140,4 +145,7 @@ void container_for_each_descendant_bfs(struct sway_container *container, | |||
140 | void container_for_each_descendant_dfs(struct sway_container *container, | 145 | void container_for_each_descendant_dfs(struct sway_container *container, |
141 | void (*f)(struct sway_container *container, void *data), void *data); | 146 | void (*f)(struct sway_container *container, void *data), void *data); |
142 | 147 | ||
148 | bool container_has_anscestor(struct sway_container *descendant, | ||
149 | struct sway_container *anscestor); | ||
150 | |||
143 | #endif | 151 | #endif |
diff --git a/include/sway/tree/layout.h b/include/sway/tree/layout.h index ad52bdb0..8239366b 100644 --- a/include/sway/tree/layout.h +++ b/include/sway/tree/layout.h | |||
@@ -39,6 +39,9 @@ struct sway_container *container_add_sibling(struct sway_container *parent, | |||
39 | 39 | ||
40 | struct sway_container *container_remove_child(struct sway_container *child); | 40 | struct sway_container *container_remove_child(struct sway_container *child); |
41 | 41 | ||
42 | void container_move_to(struct sway_container* container, | ||
43 | struct sway_container* destination); | ||
44 | |||
42 | enum sway_container_layout container_get_default_layout(struct sway_container *output); | 45 | enum sway_container_layout container_get_default_layout(struct sway_container *output); |
43 | 46 | ||
44 | void container_sort_workspaces(struct sway_container *output); | 47 | void container_sort_workspaces(struct sway_container *output); |
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 87eb80fe..f3416c03 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -41,6 +41,9 @@ static void rotate_child_position(double *sx, double *sy, double sw, double sh, | |||
41 | static void render_surface(struct wlr_surface *surface, | 41 | static void render_surface(struct wlr_surface *surface, |
42 | struct wlr_output *wlr_output, struct timespec *when, | 42 | struct wlr_output *wlr_output, struct timespec *when, |
43 | double lx, double ly, float rotation) { | 43 | double lx, double ly, float rotation) { |
44 | struct wlr_renderer *renderer = | ||
45 | wlr_backend_get_renderer(wlr_output->backend); | ||
46 | |||
44 | if (!wlr_surface_has_buffer(surface)) { | 47 | if (!wlr_surface_has_buffer(surface)) { |
45 | return; | 48 | return; |
46 | } | 49 | } |
@@ -65,8 +68,8 @@ static void render_surface(struct wlr_surface *surface, | |||
65 | float matrix[9]; | 68 | float matrix[9]; |
66 | wlr_matrix_project_box(matrix, &render_box, surface->current->transform, | 69 | wlr_matrix_project_box(matrix, &render_box, surface->current->transform, |
67 | 0, wlr_output->transform_matrix); | 70 | 0, wlr_output->transform_matrix); |
68 | wlr_render_texture_with_matrix(server.renderer, surface->texture, | 71 | wlr_render_texture_with_matrix(renderer, surface->texture, matrix, |
69 | matrix, 1.0f); // TODO: configurable alpha | 72 | 1.0f); // TODO: configurable alpha |
70 | 73 | ||
71 | wlr_surface_send_frame_done(surface, when); | 74 | wlr_surface_send_frame_done(surface, when); |
72 | } | 75 | } |
@@ -192,15 +195,14 @@ static void render_layer(struct sway_output *output, | |||
192 | } | 195 | } |
193 | } | 196 | } |
194 | 197 | ||
195 | static void output_frame_notify(struct wl_listener *listener, void *data) { | 198 | static void handle_output_frame(struct wl_listener *listener, void *data) { |
196 | struct sway_output *soutput = wl_container_of(listener, soutput, frame); | 199 | struct sway_output *soutput = wl_container_of(listener, soutput, frame); |
197 | struct wlr_output *wlr_output = data; | 200 | struct wlr_output *wlr_output = data; |
198 | struct sway_server *server = soutput->server; | 201 | struct wlr_renderer *renderer = |
199 | struct wlr_renderer *renderer = wlr_backend_get_renderer(wlr_output->backend); | 202 | wlr_backend_get_renderer(wlr_output->backend); |
200 | 203 | ||
201 | int buffer_age = -1; | 204 | wlr_output_make_current(wlr_output, NULL); |
202 | wlr_output_make_current(wlr_output, &buffer_age); | 205 | wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height); |
203 | wlr_renderer_begin(server->renderer, wlr_output->width, wlr_output->height); | ||
204 | 206 | ||
205 | float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f}; | 207 | float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f}; |
206 | wlr_renderer_clear(renderer, clear_color); | 208 | wlr_renderer_clear(renderer, clear_color); |
@@ -218,7 +220,8 @@ static void output_frame_notify(struct wl_listener *listener, void *data) { | |||
218 | &soutput->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]); | 220 | &soutput->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]); |
219 | 221 | ||
220 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 222 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
221 | struct sway_container *focus = sway_seat_get_focus_inactive(seat, soutput->swayc); | 223 | struct sway_container *focus = |
224 | sway_seat_get_focus_inactive(seat, soutput->swayc); | ||
222 | struct sway_container *workspace = (focus->type == C_WORKSPACE ? | 225 | struct sway_container *workspace = (focus->type == C_WORKSPACE ? |
223 | focus : | 226 | focus : |
224 | container_parent(focus, C_WORKSPACE)); | 227 | container_parent(focus, C_WORKSPACE)); |
@@ -248,7 +251,7 @@ static void output_frame_notify(struct wl_listener *listener, void *data) { | |||
248 | render_layer(soutput, output_box, &now, | 251 | render_layer(soutput, output_box, &now, |
249 | &soutput->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); | 252 | &soutput->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); |
250 | 253 | ||
251 | wlr_renderer_end(server->renderer); | 254 | wlr_renderer_end(renderer); |
252 | wlr_output_swap_buffers(wlr_output, &now, NULL); | 255 | wlr_output_swap_buffers(wlr_output, &now, NULL); |
253 | soutput->last_frame = now; | 256 | soutput->last_frame = now; |
254 | } | 257 | } |
@@ -306,7 +309,7 @@ void handle_new_output(struct wl_listener *listener, void *data) { | |||
306 | sway_input_manager_configure_xcursor(input_manager); | 309 | sway_input_manager_configure_xcursor(input_manager); |
307 | 310 | ||
308 | wl_signal_add(&wlr_output->events.frame, &output->frame); | 311 | wl_signal_add(&wlr_output->events.frame, &output->frame); |
309 | output->frame.notify = output_frame_notify; | 312 | output->frame.notify = handle_output_frame; |
310 | wl_signal_add(&wlr_output->events.destroy, &output->destroy); | 313 | wl_signal_add(&wlr_output->events.destroy, &output->destroy); |
311 | output->destroy.notify = handle_output_destroy; | 314 | output->destroy.notify = handle_output_destroy; |
312 | wl_signal_add(&wlr_output->events.mode, &output->mode); | 315 | wl_signal_add(&wlr_output->events.mode, &output->mode); |
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 38ee4656..d608c8b6 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c | |||
@@ -104,14 +104,11 @@ static void handle_commit(struct wl_listener *listener, void *data) { | |||
104 | static void handle_destroy(struct wl_listener *listener, void *data) { | 104 | static void handle_destroy(struct wl_listener *listener, void *data) { |
105 | struct sway_xwayland_surface *sway_surface = | 105 | struct sway_xwayland_surface *sway_surface = |
106 | wl_container_of(listener, sway_surface, destroy); | 106 | wl_container_of(listener, sway_surface, destroy); |
107 | struct wlr_xwayland_surface *xsurface = data; | 107 | |
108 | wl_list_remove(&sway_surface->commit.link); | 108 | wl_list_remove(&sway_surface->commit.link); |
109 | wl_list_remove(&sway_surface->destroy.link); | 109 | wl_list_remove(&sway_surface->destroy.link); |
110 | wl_list_remove(&sway_surface->request_configure.link); | 110 | wl_list_remove(&sway_surface->request_configure.link); |
111 | if (xsurface->override_redirect && xsurface->mapped) { | 111 | wl_list_remove(&sway_surface->view->unmanaged_view_link); |
112 | wl_list_remove(&sway_surface->view->unmanaged_view_link); | ||
113 | wl_list_init(&sway_surface->view->unmanaged_view_link); | ||
114 | } | ||
115 | 112 | ||
116 | struct sway_container *parent = container_view_destroy(sway_surface->view->swayc); | 113 | struct sway_container *parent = container_view_destroy(sway_surface->view->swayc); |
117 | if (parent) { | 114 | if (parent) { |
@@ -125,11 +122,9 @@ static void handle_destroy(struct wl_listener *listener, void *data) { | |||
125 | static void handle_unmap_notify(struct wl_listener *listener, void *data) { | 122 | static void handle_unmap_notify(struct wl_listener *listener, void *data) { |
126 | struct sway_xwayland_surface *sway_surface = | 123 | struct sway_xwayland_surface *sway_surface = |
127 | wl_container_of(listener, sway_surface, unmap_notify); | 124 | wl_container_of(listener, sway_surface, unmap_notify); |
128 | struct wlr_xwayland_surface *xsurface = data; | 125 | |
129 | if (xsurface->override_redirect && xsurface->mapped) { | 126 | wl_list_remove(&sway_surface->view->unmanaged_view_link); |
130 | wl_list_remove(&sway_surface->view->unmanaged_view_link); | 127 | wl_list_init(&sway_surface->view->unmanaged_view_link); |
131 | wl_list_init(&sway_surface->view->unmanaged_view_link); | ||
132 | } | ||
133 | 128 | ||
134 | // take it out of the tree | 129 | // take it out of the tree |
135 | struct sway_container *parent = container_view_destroy(sway_surface->view->swayc); | 130 | struct sway_container *parent = container_view_destroy(sway_surface->view->swayc); |
@@ -150,7 +145,9 @@ static void handle_map_notify(struct wl_listener *listener, void *data) { | |||
150 | sway_surface->view->surface = xsurface->surface; | 145 | sway_surface->view->surface = xsurface->surface; |
151 | 146 | ||
152 | // put it back into the tree | 147 | // put it back into the tree |
153 | if (xsurface->override_redirect) { | 148 | if (wlr_xwayland_surface_is_unmanaged(xsurface) || |
149 | xsurface->override_redirect) { | ||
150 | wl_list_remove(&sway_surface->view->unmanaged_view_link); | ||
154 | wl_list_insert(&root_container.sway_root->unmanaged_views, | 151 | wl_list_insert(&root_container.sway_root->unmanaged_views, |
155 | &sway_surface->view->unmanaged_view_link); | 152 | &sway_surface->view->unmanaged_view_link); |
156 | } else { | 153 | } else { |
@@ -209,6 +206,8 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { | |||
209 | sway_view->surface = xsurface->surface; | 206 | sway_view->surface = xsurface->surface; |
210 | sway_surface->view = sway_view; | 207 | sway_surface->view = sway_view; |
211 | 208 | ||
209 | wl_list_init(&sway_view->unmanaged_view_link); | ||
210 | |||
212 | // TODO: | 211 | // TODO: |
213 | // - Look up pid and open on appropriate workspace | 212 | // - Look up pid and open on appropriate workspace |
214 | // - Set new view to maximized so it behaves nicely | 213 | // - Set new view to maximized so it behaves nicely |
@@ -230,18 +229,5 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { | |||
230 | wl_signal_add(&xsurface->events.map_notify, &sway_surface->map_notify); | 229 | wl_signal_add(&xsurface->events.map_notify, &sway_surface->map_notify); |
231 | sway_surface->map_notify.notify = handle_map_notify; | 230 | sway_surface->map_notify.notify = handle_map_notify; |
232 | 231 | ||
233 | if (wlr_xwayland_surface_is_unmanaged(xsurface)) { | 232 | handle_map_notify(&sway_surface->map_notify, xsurface); |
234 | // these don't get a container in the tree | ||
235 | wl_list_insert(&root_container.sway_root->unmanaged_views, | ||
236 | &sway_view->unmanaged_view_link); | ||
237 | return; | ||
238 | } | ||
239 | |||
240 | struct sway_seat *seat = input_manager_current_seat(input_manager); | ||
241 | struct sway_container *focus = sway_seat_get_focus_inactive(seat, &root_container); | ||
242 | struct sway_container *cont = container_view_create(focus, sway_view); | ||
243 | sway_view->swayc = cont; | ||
244 | |||
245 | arrange_windows(cont->parent, -1, -1); | ||
246 | sway_input_manager_set_focus(input_manager, cont); | ||
247 | } | 233 | } |
diff --git a/sway/input/seat.c b/sway/input/seat.c index 7cf0dd08..ae536264 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include "sway/input/keyboard.h" | 8 | #include "sway/input/keyboard.h" |
9 | #include "sway/ipc-server.h" | 9 | #include "sway/ipc-server.h" |
10 | #include "sway/output.h" | 10 | #include "sway/output.h" |
11 | #include "sway/tree/container.h" | ||
11 | #include "sway/tree/view.h" | 12 | #include "sway/tree/view.h" |
12 | #include "log.h" | 13 | #include "log.h" |
13 | 14 | ||
@@ -331,6 +332,9 @@ void sway_seat_set_focus(struct sway_seat *seat, struct sway_container *containe | |||
331 | if (last_ws) { | 332 | if (last_ws) { |
332 | wlr_log(L_DEBUG, "sending workspace event"); | 333 | wlr_log(L_DEBUG, "sending workspace event"); |
333 | ipc_event_workspace(last_ws, container, "focus"); | 334 | ipc_event_workspace(last_ws, container, "focus"); |
335 | if (last_ws->children->length == 0) { | ||
336 | container_workspace_destroy(last_ws); | ||
337 | } | ||
334 | } | 338 | } |
335 | } | 339 | } |
336 | 340 | ||
diff --git a/sway/server.c b/sway/server.c index 3fba019d..728e624e 100644 --- a/sway/server.c +++ b/sway/server.c | |||
@@ -1,19 +1,19 @@ | |||
1 | #define _POSIX_C_SOURCE 200112L | 1 | #define _POSIX_C_SOURCE 200112L |
2 | #include <stdlib.h> | 2 | #include <assert.h> |
3 | #include <stdbool.h> | 3 | #include <stdbool.h> |
4 | #include <stdlib.h> | ||
4 | #include <wayland-server.h> | 5 | #include <wayland-server.h> |
5 | #include <wlr/backend.h> | 6 | #include <wlr/backend.h> |
6 | #include <wlr/backend/session.h> | 7 | #include <wlr/backend/session.h> |
7 | #include <wlr/render/wlr_renderer.h> | 8 | #include <wlr/render/wlr_renderer.h> |
8 | #include <wlr/render/gles2.h> | ||
9 | #include <wlr/types/wlr_compositor.h> | 9 | #include <wlr/types/wlr_compositor.h> |
10 | #include <wlr/types/wlr_gamma_control.h> | ||
10 | #include <wlr/types/wlr_layer_shell.h> | 11 | #include <wlr/types/wlr_layer_shell.h> |
11 | #include <wlr/types/wlr_screenshooter.h> | 12 | #include <wlr/types/wlr_screenshooter.h> |
12 | #include <wlr/types/wlr_gamma_control.h> | ||
13 | #include <wlr/types/wlr_wl_shell.h> | 13 | #include <wlr/types/wlr_wl_shell.h> |
14 | #include <wlr/util/log.h> | ||
14 | // TODO WLR: make Xwayland optional | 15 | // TODO WLR: make Xwayland optional |
15 | #include <wlr/xwayland.h> | 16 | #include <wlr/xwayland.h> |
16 | #include <wlr/util/log.h> | ||
17 | #include "sway/commands.h" | 17 | #include "sway/commands.h" |
18 | #include "sway/config.h" | 18 | #include "sway/config.h" |
19 | #include "sway/server.h" | 19 | #include "sway/server.h" |
@@ -42,11 +42,12 @@ bool server_init(struct sway_server *server) { | |||
42 | server->wl_event_loop = wl_display_get_event_loop(server->wl_display); | 42 | server->wl_event_loop = wl_display_get_event_loop(server->wl_display); |
43 | server->backend = wlr_backend_autocreate(server->wl_display); | 43 | server->backend = wlr_backend_autocreate(server->wl_display); |
44 | 44 | ||
45 | server->renderer = wlr_gles2_renderer_create(server->backend); | 45 | struct wlr_renderer *renderer = wlr_backend_get_renderer(server->backend); |
46 | assert(renderer); | ||
47 | |||
46 | wl_display_init_shm(server->wl_display); | 48 | wl_display_init_shm(server->wl_display); |
47 | 49 | ||
48 | server->compositor = wlr_compositor_create( | 50 | server->compositor = wlr_compositor_create(server->wl_display, renderer); |
49 | server->wl_display, server->renderer); | ||
50 | server->data_device_manager = | 51 | server->data_device_manager = |
51 | wlr_data_device_manager_create(server->wl_display); | 52 | wlr_data_device_manager_create(server->wl_display); |
52 | 53 | ||
@@ -95,8 +96,7 @@ bool server_init(struct sway_server *server) { | |||
95 | } | 96 | } |
96 | 97 | ||
97 | void server_fini(struct sway_server *server) { | 98 | void server_fini(struct sway_server *server) { |
98 | // TODO WLR: tear down more stuff | 99 | // TODO |
99 | wlr_backend_destroy(server->backend); | ||
100 | } | 100 | } |
101 | 101 | ||
102 | void server_run(struct sway_server *server) { | 102 | void server_run(struct sway_server *server) { |
diff --git a/sway/tree/container.c b/sway/tree/container.c index 2eac812e..ed39a154 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -58,7 +58,7 @@ static struct sway_container *container_create(enum sway_container_type type) { | |||
58 | return c; | 58 | return c; |
59 | } | 59 | } |
60 | 60 | ||
61 | static void container_destroy(struct sway_container *cont) { | 61 | void container_destroy(struct sway_container *cont) { |
62 | if (cont == NULL) { | 62 | if (cont == NULL) { |
63 | return; | 63 | return; |
64 | } | 64 | } |
@@ -203,8 +203,7 @@ struct sway_container *container_view_create(struct sway_container *sibling, | |||
203 | } | 203 | } |
204 | 204 | ||
205 | struct sway_container *container_output_destroy(struct sway_container *output) { | 205 | struct sway_container *container_output_destroy(struct sway_container *output) { |
206 | if (!sway_assert(output, | 206 | if (!sway_assert(output, "cannot destroy null output")) { |
207 | "null output passed to container_output_destroy")) { | ||
208 | return NULL; | 207 | return NULL; |
209 | } | 208 | } |
210 | 209 | ||
@@ -236,6 +235,45 @@ struct sway_container *container_output_destroy(struct sway_container *output) { | |||
236 | return &root_container; | 235 | return &root_container; |
237 | } | 236 | } |
238 | 237 | ||
238 | struct sway_container *container_workspace_destroy( | ||
239 | struct sway_container *workspace) { | ||
240 | if (!sway_assert(workspace, "cannot destroy null workspace")) { | ||
241 | return NULL; | ||
242 | } | ||
243 | |||
244 | // Do not destroy this if it's the last workspace on this output | ||
245 | struct sway_container *output = container_parent(workspace, C_OUTPUT); | ||
246 | if (output && output->children->length == 1) { | ||
247 | return NULL; | ||
248 | } | ||
249 | |||
250 | struct sway_container *parent = workspace->parent; | ||
251 | if (workspace->children->length == 0) { | ||
252 | // destroy the WS if there are no children (TODO check for floating) | ||
253 | wlr_log(L_DEBUG, "destroying workspace '%s'", workspace->name); | ||
254 | ipc_event_workspace(workspace, NULL, "empty"); | ||
255 | } else { | ||
256 | // Move children to a different workspace on this output | ||
257 | struct sway_container *new_workspace = NULL; | ||
258 | // TODO move floating | ||
259 | for (int i = 0; i < output->children->length; i++) { | ||
260 | if (output->children->items[i] != workspace) { | ||
261 | new_workspace = output->children->items[i]; | ||
262 | break; | ||
263 | } | ||
264 | } | ||
265 | |||
266 | wlr_log(L_DEBUG, "moving children to different workspace '%s' -> '%s'", | ||
267 | workspace->name, new_workspace->name); | ||
268 | for (int i = 0; i < workspace->children->length; i++) { | ||
269 | container_move_to(workspace->children->items[i], new_workspace); | ||
270 | } | ||
271 | } | ||
272 | |||
273 | container_destroy(workspace); | ||
274 | return parent; | ||
275 | } | ||
276 | |||
239 | struct sway_container *container_view_destroy(struct sway_container *view) { | 277 | struct sway_container *container_view_destroy(struct sway_container *view) { |
240 | if (!view) { | 278 | if (!view) { |
241 | return NULL; | 279 | return NULL; |
@@ -438,3 +476,14 @@ void container_for_each_descendant_bfs(struct sway_container *con, | |||
438 | list_cat(queue, current->children); | 476 | list_cat(queue, current->children); |
439 | } | 477 | } |
440 | } | 478 | } |
479 | |||
480 | bool container_has_anscestor(struct sway_container *descendant, | ||
481 | struct sway_container *anscestor) { | ||
482 | while (descendant->type != C_ROOT) { | ||
483 | descendant = descendant->parent; | ||
484 | if (descendant == anscestor) { | ||
485 | return true; | ||
486 | } | ||
487 | } | ||
488 | return false; | ||
489 | } | ||
diff --git a/sway/tree/layout.c b/sway/tree/layout.c index c7cf16e6..73c4849b 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include "sway/output.h" | 11 | #include "sway/output.h" |
12 | #include "sway/tree/view.h" | 12 | #include "sway/tree/view.h" |
13 | #include "sway/input/seat.h" | 13 | #include "sway/input/seat.h" |
14 | #include "sway/ipc-server.h" | ||
14 | #include "list.h" | 15 | #include "list.h" |
15 | #include "log.h" | 16 | #include "log.h" |
16 | 17 | ||
@@ -121,6 +122,42 @@ struct sway_container *container_remove_child(struct sway_container *child) { | |||
121 | return parent; | 122 | return parent; |
122 | } | 123 | } |
123 | 124 | ||
125 | struct sway_container *container_reap_empty(struct sway_container *container) { | ||
126 | if (!sway_assert(container, "reaping null container")) { | ||
127 | return NULL; | ||
128 | } | ||
129 | while (container->children->length == 0 && container->type == C_CONTAINER) { | ||
130 | wlr_log(L_DEBUG, "Container: Destroying container '%p'", container); | ||
131 | struct sway_container *parent = container->parent; | ||
132 | container_destroy(container); | ||
133 | container = parent; | ||
134 | } | ||
135 | return container; | ||
136 | } | ||
137 | |||
138 | void container_move_to(struct sway_container* container, | ||
139 | struct sway_container* destination) { | ||
140 | if (container == destination | ||
141 | || container_has_anscestor(container, destination)) { | ||
142 | return; | ||
143 | } | ||
144 | struct sway_container *old_parent = container_remove_child(container); | ||
145 | container->width = container->height = 0; | ||
146 | struct sway_container *new_parent = | ||
147 | container_add_sibling(destination, container); | ||
148 | if (destination->type == C_WORKSPACE) { | ||
149 | // If the workspace only has one child after adding one, it | ||
150 | // means that the workspace was just initialized. | ||
151 | // TODO: Consider floating views in this test | ||
152 | if (destination->children->length == 1) { | ||
153 | ipc_event_workspace(NULL, destination, "init"); | ||
154 | } | ||
155 | } | ||
156 | old_parent = container_reap_empty(old_parent); | ||
157 | arrange_windows(old_parent, -1, -1); | ||
158 | arrange_windows(new_parent, -1, -1); | ||
159 | } | ||
160 | |||
124 | enum sway_container_layout container_get_default_layout( | 161 | enum sway_container_layout container_get_default_layout( |
125 | struct sway_container *output) { | 162 | struct sway_container *output) { |
126 | if (config->default_layout != L_NONE) { | 163 | if (config->default_layout != L_NONE) { |