aboutsummaryrefslogtreecommitdiffstats
path: root/sway/tree
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-03-29 23:34:14 -0400
committerLibravatar GitHub <noreply@github.com>2018-03-29 23:34:14 -0400
commit472e81f35d689d67cda241acafda91c688d61046 (patch)
treeb8b52173a9791e3b13a0316ab9d316a80a6adc20 /sway/tree
parentMerge pull request #1647 from acrisci/refactor-tree (diff)
parentRevert "Refactor tree" (diff)
downloadsway-472e81f35d689d67cda241acafda91c688d61046.tar.gz
sway-472e81f35d689d67cda241acafda91c688d61046.tar.zst
sway-472e81f35d689d67cda241acafda91c688d61046.zip
Merge pull request #1653 from swaywm/revert-1647-refactor-tree
Revert "Refactor tree"
Diffstat (limited to 'sway/tree')
-rw-r--r--sway/tree/container.c221
-rw-r--r--sway/tree/layout.c133
-rw-r--r--sway/tree/view.c7
-rw-r--r--sway/tree/workspace.c92
4 files changed, 216 insertions, 237 deletions
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 40047dcf..bbafe9ec 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -7,14 +7,14 @@
7#include <wlr/types/wlr_output_layout.h> 7#include <wlr/types/wlr_output_layout.h>
8#include <wlr/types/wlr_wl_shell.h> 8#include <wlr/types/wlr_wl_shell.h>
9#include "sway/config.h" 9#include "sway/config.h"
10#include "sway/tree/container.h" 10#include "sway/container.h"
11#include "sway/input/input-manager.h" 11#include "sway/input/input-manager.h"
12#include "sway/input/seat.h" 12#include "sway/input/seat.h"
13#include "sway/tree/layout.h" 13#include "sway/layout.h"
14#include "sway/output.h" 14#include "sway/output.h"
15#include "sway/server.h" 15#include "sway/server.h"
16#include "sway/tree/view.h" 16#include "sway/view.h"
17#include "sway/tree/workspace.h" 17#include "sway/workspace.h"
18#include "sway/ipc-server.h" 18#include "sway/ipc-server.h"
19#include "log.h" 19#include "log.h"
20 20
@@ -33,15 +33,48 @@ static list_t *get_bfs_queue() {
33 return bfs_queue; 33 return bfs_queue;
34} 34}
35 35
36static void notify_new_container(struct sway_container *container) { 36static void notify_new_container(swayc_t *container) {
37 wl_signal_emit(&root_container.sway_root->events.new_container, container); 37 wl_signal_emit(&root_container.sway_root->events.new_container, container);
38 ipc_event_window(container, "new"); 38 ipc_event_window(container, "new");
39} 39}
40 40
41static struct sway_container *container_create(enum sway_container_type type) { 41swayc_t *swayc_by_test(swayc_t *container,
42 bool (*test)(swayc_t *view, void *data), void *data) {
43 if (!container->children) {
44 return NULL;
45 }
46 // TODO: floating windows
47 for (int i = 0; i < container->children->length; ++i) {
48 swayc_t *child = container->children->items[i];
49 if (test(child, data)) {
50 return child;
51 } else {
52 swayc_t *res = swayc_by_test(child, test, data);
53 if (res) {
54 return res;
55 }
56 }
57 }
58 return NULL;
59}
60
61void swayc_descendants_of_type(swayc_t *root, enum swayc_types type,
62 void (*func)(swayc_t *item, void *data), void *data) {
63 for (int i = 0; i < root->children->length; ++i) {
64 swayc_t *item = root->children->items[i];
65 if (item->type == type) {
66 func(item, data);
67 }
68 if (item->children && item->children->length) {
69 swayc_descendants_of_type(item, type, func, data);
70 }
71 }
72}
73
74static swayc_t *new_swayc(enum swayc_types type) {
42 // next id starts at 1 because 0 is assigned to root_container in layout.c 75 // next id starts at 1 because 0 is assigned to root_container in layout.c
43 static size_t next_id = 1; 76 static size_t next_id = 1;
44 struct sway_container *c = calloc(1, sizeof(struct sway_container)); 77 swayc_t *c = calloc(1, sizeof(swayc_t));
45 if (!c) { 78 if (!c) {
46 return NULL; 79 return NULL;
47 } 80 }
@@ -49,6 +82,8 @@ static struct sway_container *container_create(enum sway_container_type type) {
49 c->layout = L_NONE; 82 c->layout = L_NONE;
50 c->workspace_layout = L_NONE; 83 c->workspace_layout = L_NONE;
51 c->type = type; 84 c->type = type;
85 c->nb_master = 1;
86 c->nb_slave_groups = 1;
52 if (type != C_VIEW) { 87 if (type != C_VIEW) {
53 c->children = create_list(); 88 c->children = create_list();
54 } 89 }
@@ -58,18 +93,18 @@ static struct sway_container *container_create(enum sway_container_type type) {
58 return c; 93 return c;
59} 94}
60 95
61static void container_destroy(struct sway_container *cont) { 96static void free_swayc(swayc_t *cont) {
62 if (cont == NULL) { 97 if (!sway_assert(cont, "free_swayc passed NULL")) {
63 return; 98 return;
64 } 99 }
65 100
66 wl_signal_emit(&cont->events.destroy, cont); 101 wl_signal_emit(&cont->events.destroy, cont);
67 102
68 if (cont->children) { 103 if (cont->children) {
69 // remove children until there are no more, container_destroy calls 104 // remove children until there are no more, free_swayc calls
70 // container_remove_child, which removes child from this container 105 // remove_child, which removes child from this container
71 while (cont->children->length) { 106 while (cont->children->length) {
72 container_destroy(cont->children->items[0]); 107 free_swayc(cont->children->items[0]);
73 } 108 }
74 list_free(cont->children); 109 list_free(cont->children);
75 } 110 }
@@ -78,7 +113,7 @@ static void container_destroy(struct sway_container *cont) {
78 list_free(cont->marks); 113 list_free(cont->marks);
79 } 114 }
80 if (cont->parent) { 115 if (cont->parent) {
81 container_remove_child(cont); 116 remove_child(cont);
82 } 117 }
83 if (cont->name) { 118 if (cont->name) {
84 free(cont->name); 119 free(cont->name);
@@ -86,8 +121,7 @@ static void container_destroy(struct sway_container *cont) {
86 free(cont); 121 free(cont);
87} 122}
88 123
89struct sway_container *container_output_create( 124swayc_t *new_output(struct sway_output *sway_output) {
90 struct sway_output *sway_output) {
91 struct wlr_box size; 125 struct wlr_box size;
92 wlr_output_effective_resolution(sway_output->wlr_output, &size.width, 126 wlr_output_effective_resolution(sway_output->wlr_output, &size.width,
93 &size.height); 127 &size.height);
@@ -122,22 +156,22 @@ struct sway_container *container_output_create(
122 return NULL; 156 return NULL;
123 } 157 }
124 158
125 struct sway_container *output = container_create(C_OUTPUT); 159 swayc_t *output = new_swayc(C_OUTPUT);
126 output->sway_output = sway_output; 160 output->sway_output = sway_output;
127 output->name = strdup(name); 161 output->name = strdup(name);
128 if (output->name == NULL) { 162 if (output->name == NULL) {
129 container_destroy(output); 163 free_swayc(output);
130 return NULL; 164 return NULL;
131 } 165 }
132 166
133 apply_output_config(oc, output); 167 apply_output_config(oc, output);
134 168
135 container_add_child(&root_container, output); 169 add_child(&root_container, output);
136 170
137 // Create workspace 171 // Create workspace
138 char *ws_name = workspace_next_name(output->name); 172 char *ws_name = workspace_next_name(output->name);
139 wlr_log(L_DEBUG, "Creating default workspace %s", ws_name); 173 wlr_log(L_DEBUG, "Creating default workspace %s", ws_name);
140 struct sway_container *ws = container_workspace_create(output, ws_name); 174 swayc_t *ws = new_workspace(output, ws_name);
141 // Set each seat's focus if not already set 175 // Set each seat's focus if not already set
142 struct sway_seat *seat = NULL; 176 struct sway_seat *seat = NULL;
143 wl_list_for_each(seat, &input_manager->seats, link) { 177 wl_list_for_each(seat, &input_manager->seats, link) {
@@ -151,14 +185,12 @@ struct sway_container *container_output_create(
151 return output; 185 return output;
152} 186}
153 187
154struct sway_container *container_workspace_create( 188swayc_t *new_workspace(swayc_t *output, const char *name) {
155 struct sway_container *output, const char *name) { 189 if (!sway_assert(output, "new_workspace called with null output")) {
156 if (!sway_assert(output,
157 "container_workspace_create called with null output")) {
158 return NULL; 190 return NULL;
159 } 191 }
160 wlr_log(L_DEBUG, "Added workspace %s for output %s", name, output->name); 192 wlr_log(L_DEBUG, "Added workspace %s for output %s", name, output->name);
161 struct sway_container *workspace = container_create(C_WORKSPACE); 193 swayc_t *workspace = new_swayc(C_WORKSPACE);
162 194
163 workspace->x = output->x; 195 workspace->x = output->x;
164 workspace->y = output->y; 196 workspace->y = output->y;
@@ -166,23 +198,21 @@ struct sway_container *container_workspace_create(
166 workspace->height = output->height; 198 workspace->height = output->height;
167 workspace->name = !name ? NULL : strdup(name); 199 workspace->name = !name ? NULL : strdup(name);
168 workspace->prev_layout = L_NONE; 200 workspace->prev_layout = L_NONE;
169 workspace->layout = container_get_default_layout(output); 201 workspace->layout = default_layout(output);
170 workspace->workspace_layout = container_get_default_layout(output); 202 workspace->workspace_layout = default_layout(output);
171 203
172 container_add_child(output, workspace); 204 add_child(output, workspace);
173 container_sort_workspaces(output); 205 sort_workspaces(output);
174 notify_new_container(workspace); 206 notify_new_container(workspace);
175 return workspace; 207 return workspace;
176} 208}
177 209
178struct sway_container *container_view_create(struct sway_container *sibling, 210swayc_t *new_view(swayc_t *sibling, struct sway_view *sway_view) {
179 struct sway_view *sway_view) { 211 if (!sway_assert(sibling, "new_view called with NULL sibling/parent")) {
180 if (!sway_assert(sibling,
181 "container_view_create called with NULL sibling/parent")) {
182 return NULL; 212 return NULL;
183 } 213 }
184 const char *title = view_get_title(sway_view); 214 const char *title = view_get_title(sway_view);
185 struct sway_container *swayc = container_create(C_VIEW); 215 swayc_t *swayc = new_swayc(C_VIEW);
186 wlr_log(L_DEBUG, "Adding new view %p:%s to container %p %d %s", 216 wlr_log(L_DEBUG, "Adding new view %p:%s to container %p %d %s",
187 swayc, title, sibling, sibling ? sibling->type : 0, sibling->name); 217 swayc, title, sibling, sibling ? sibling->type : 0, sibling->name);
188 // Setup values 218 // Setup values
@@ -193,18 +223,17 @@ struct sway_container *container_view_create(struct sway_container *sibling,
193 223
194 if (sibling->type == C_WORKSPACE) { 224 if (sibling->type == C_WORKSPACE) {
195 // Case of focused workspace, just create as child of it 225 // Case of focused workspace, just create as child of it
196 container_add_child(sibling, swayc); 226 add_child(sibling, swayc);
197 } else { 227 } else {
198 // Regular case, create as sibling of current container 228 // Regular case, create as sibling of current container
199 container_add_sibling(sibling, swayc); 229 add_sibling(sibling, swayc);
200 } 230 }
201 notify_new_container(swayc); 231 notify_new_container(swayc);
202 return swayc; 232 return swayc;
203} 233}
204 234
205struct sway_container *container_output_destroy(struct sway_container *output) { 235swayc_t *destroy_output(swayc_t *output) {
206 if (!sway_assert(output, 236 if (!sway_assert(output, "null output passed to destroy_output")) {
207 "null output passed to container_output_destroy")) {
208 return NULL; 237 return NULL;
209 } 238 }
210 239
@@ -216,13 +245,12 @@ struct sway_container *container_output_destroy(struct sway_container *output) {
216 int p = root_container.children->items[0] == output; 245 int p = root_container.children->items[0] == output;
217 // Move workspace from this output to another output 246 // Move workspace from this output to another output
218 while (output->children->length) { 247 while (output->children->length) {
219 struct sway_container *child = output->children->items[0]; 248 swayc_t *child = output->children->items[0];
220 container_remove_child(child); 249 remove_child(child);
221 container_add_child(root_container.children->items[p], child); 250 add_child(root_container.children->items[p], child);
222 } 251 }
223 container_sort_workspaces(root_container.children->items[p]); 252 sort_workspaces(root_container.children->items[p]);
224 arrange_windows(root_container.children->items[p], 253 arrange_windows(root_container.children->items[p], -1, -1);
225 -1, -1);
226 } 254 }
227 } 255 }
228 256
@@ -231,18 +259,18 @@ struct sway_container *container_output_destroy(struct sway_container *output) {
231 wl_list_remove(&output->sway_output->mode.link); 259 wl_list_remove(&output->sway_output->mode.link);
232 260
233 wlr_log(L_DEBUG, "OUTPUT: Destroying output '%s'", output->name); 261 wlr_log(L_DEBUG, "OUTPUT: Destroying output '%s'", output->name);
234 container_destroy(output); 262 free_swayc(output);
235 263
236 return &root_container; 264 return &root_container;
237} 265}
238 266
239struct sway_container *container_view_destroy(struct sway_container *view) { 267swayc_t *destroy_view(swayc_t *view) {
240 if (!view) { 268 if (!view) {
241 return NULL; 269 return NULL;
242 } 270 }
243 wlr_log(L_DEBUG, "Destroying view '%s'", view->name); 271 wlr_log(L_DEBUG, "Destroying view '%s'", view->name);
244 struct sway_container *parent = view->parent; 272 swayc_t *parent = view->parent;
245 container_destroy(view); 273 free_swayc(view);
246 274
247 // TODO WLR: Destroy empty containers 275 // TODO WLR: Destroy empty containers
248 /* 276 /*
@@ -253,55 +281,7 @@ struct sway_container *container_view_destroy(struct sway_container *view) {
253 return parent; 281 return parent;
254} 282}
255 283
256struct sway_container *container_set_layout(struct sway_container *container, 284swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) {
257 enum sway_container_layout layout) {
258 if (container->type == C_WORKSPACE) {
259 container->workspace_layout = layout;
260 if (layout == L_HORIZ || layout == L_VERT) {
261 container->layout = layout;
262 }
263 } else {
264 container->layout = layout;
265 }
266 return container;
267}
268
269void container_descendents(struct sway_container *root,
270 enum sway_container_type type,
271 void (*func)(struct sway_container *item, void *data), void *data) {
272 for (int i = 0; i < root->children->length; ++i) {
273 struct sway_container *item = root->children->items[i];
274 if (item->type == type) {
275 func(item, data);
276 }
277 if (item->children && item->children->length) {
278 container_descendents(item, type, func, data);
279 }
280 }
281}
282
283struct sway_container *container_find(struct sway_container *container,
284 bool (*test)(struct sway_container *view, void *data), void *data) {
285 if (!container->children) {
286 return NULL;
287 }
288 // TODO: floating windows
289 for (int i = 0; i < container->children->length; ++i) {
290 struct sway_container *child = container->children->items[i];
291 if (test(child, data)) {
292 return child;
293 } else {
294 struct sway_container *res = container_find(child, test, data);
295 if (res) {
296 return res;
297 }
298 }
299 }
300 return NULL;
301}
302
303struct sway_container *container_parent(struct sway_container *container,
304 enum sway_container_type type) {
305 if (!sway_assert(container, "container is NULL")) { 285 if (!sway_assert(container, "container is NULL")) {
306 return NULL; 286 return NULL;
307 } 287 }
@@ -314,8 +294,7 @@ struct sway_container *container_parent(struct sway_container *container,
314 return container; 294 return container;
315} 295}
316 296
317struct sway_container *container_at(struct sway_container *parent, 297swayc_t *swayc_at(swayc_t *parent, double lx, double ly,
318 double lx, double ly,
319 struct wlr_surface **surface, double *sx, double *sy) { 298 struct wlr_surface **surface, double *sx, double *sy) {
320 list_t *queue = get_bfs_queue(); 299 list_t *queue = get_bfs_queue();
321 if (!queue) { 300 if (!queue) {
@@ -324,13 +303,13 @@ struct sway_container *container_at(struct sway_container *parent,
324 303
325 list_add(queue, parent); 304 list_add(queue, parent);
326 305
327 struct sway_container *swayc = NULL; 306 swayc_t *swayc = NULL;
328 while (queue->length) { 307 while (queue->length) {
329 swayc = queue->items[0]; 308 swayc = queue->items[0];
330 list_del(queue, 0); 309 list_del(queue, 0);
331 if (swayc->type == C_VIEW) { 310 if (swayc->type == C_VIEW) {
332 struct sway_view *sview = swayc->sway_view; 311 struct sway_view *sview = swayc->sway_view;
333 struct sway_container *soutput = container_parent(swayc, C_OUTPUT); 312 swayc_t *soutput = swayc_parent_by_type(swayc, C_OUTPUT);
334 struct wlr_box *output_box = 313 struct wlr_box *output_box =
335 wlr_output_layout_get_box( 314 wlr_output_layout_get_box(
336 root_container.sway_root->output_layout, 315 root_container.sway_root->output_layout,
@@ -400,8 +379,30 @@ struct sway_container *container_at(struct sway_container *parent,
400 return NULL; 379 return NULL;
401} 380}
402 381
403void container_for_each_descendent(struct sway_container *con, 382void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) {
404 void (*f)(struct sway_container *con, void *data), void *data) { 383 if (container) {
384 int i;
385 if (container->children) {
386 for (i = 0; i < container->children->length; ++i) {
387 swayc_t *child = container->children->items[i];
388 container_map(child, f, data);
389 }
390 }
391 // TODO
392 /*
393 if (container->floating) {
394 for (i = 0; i < container->floating->length; ++i) {
395 swayc_t *child = container->floating->items[i];
396 container_map(child, f, data);
397 }
398 }
399 */
400 f(container, data);
401 }
402}
403
404void container_for_each_bfs(swayc_t *con, void (*f)(swayc_t *con, void *data),
405 void *data) {
405 list_t *queue = get_bfs_queue(); 406 list_t *queue = get_bfs_queue();
406 if (!queue) { 407 if (!queue) {
407 return; 408 return;
@@ -414,7 +415,7 @@ void container_for_each_descendent(struct sway_container *con,
414 415
415 list_add(queue, con); 416 list_add(queue, con);
416 417
417 struct sway_container *current = NULL; 418 swayc_t *current = NULL;
418 while (queue->length) { 419 while (queue->length) {
419 current = queue->items[0]; 420 current = queue->items[0];
420 list_del(queue, 0); 421 list_del(queue, 0);
@@ -423,3 +424,15 @@ void container_for_each_descendent(struct sway_container *con,
423 list_cat(queue, current->children); 424 list_cat(queue, current->children);
424 } 425 }
425} 426}
427
428swayc_t *swayc_change_layout(swayc_t *container, enum swayc_layouts layout) {
429 if (container->type == C_WORKSPACE) {
430 container->workspace_layout = layout;
431 if (layout == L_HORIZ || layout == L_VERT) {
432 container->layout = layout;
433 }
434 } else {
435 container->layout = layout;
436 }
437 return container;
438}
diff --git a/sway/tree/layout.c b/sway/tree/layout.c
index dc0ee5b4..de9e7b58 100644
--- a/sway/tree/layout.c
+++ b/sway/tree/layout.c
@@ -6,26 +6,24 @@
6#include <string.h> 6#include <string.h>
7#include <wlr/types/wlr_output.h> 7#include <wlr/types/wlr_output.h>
8#include <wlr/types/wlr_output_layout.h> 8#include <wlr/types/wlr_output_layout.h>
9#include "sway/tree/container.h" 9#include "sway/container.h"
10#include "sway/tree/layout.h" 10#include "sway/layout.h"
11#include "sway/output.h" 11#include "sway/output.h"
12#include "sway/tree/view.h" 12#include "sway/view.h"
13#include "sway/input/seat.h" 13#include "sway/input/seat.h"
14#include "list.h" 14#include "list.h"
15#include "log.h" 15#include "log.h"
16 16
17struct sway_container root_container; 17swayc_t root_container;
18 18
19static void output_layout_change_notify(struct wl_listener *listener, 19static void output_layout_change_notify(struct wl_listener *listener, void *data) {
20 void *data) {
21 struct wlr_box *layout_box = wlr_output_layout_get_box( 20 struct wlr_box *layout_box = wlr_output_layout_get_box(
22 root_container.sway_root->output_layout, NULL); 21 root_container.sway_root->output_layout, NULL);
23 root_container.width = layout_box->width; 22 root_container.width = layout_box->width;
24 root_container.height = layout_box->height; 23 root_container.height = layout_box->height;
25 24
26 for (int i = 0 ; i < root_container.children->length; ++i) { 25 for (int i = 0 ; i < root_container.children->length; ++i) {
27 struct sway_container *output_container = 26 swayc_t *output_container = root_container.children->items[i];
28 root_container.children->items[i];
29 if (output_container->type != C_OUTPUT) { 27 if (output_container->type != C_OUTPUT) {
30 continue; 28 continue;
31 } 29 }
@@ -45,7 +43,7 @@ static void output_layout_change_notify(struct wl_listener *listener,
45 arrange_windows(&root_container, -1, -1); 43 arrange_windows(&root_container, -1, -1);
46} 44}
47 45
48void layout_init(void) { 46void init_layout(void) {
49 root_container.id = 0; // normally assigned in new_swayc() 47 root_container.id = 0; // normally assigned in new_swayc()
50 root_container.type = C_ROOT; 48 root_container.type = C_ROOT;
51 root_container.layout = L_NONE; 49 root_container.layout = L_NONE;
@@ -64,9 +62,9 @@ void layout_init(void) {
64 &root_container.sway_root->output_layout_change); 62 &root_container.sway_root->output_layout_change);
65} 63}
66 64
67static int index_child(const struct sway_container *child) { 65static int index_child(const swayc_t *child) {
68 // TODO handle floating 66 // TODO handle floating
69 struct sway_container *parent = child->parent; 67 swayc_t *parent = child->parent;
70 int i, len; 68 int i, len;
71 len = parent->children->length; 69 len = parent->children->length;
72 for (i = 0; i < len; ++i) { 70 for (i = 0; i < len; ++i) {
@@ -81,18 +79,16 @@ static int index_child(const struct sway_container *child) {
81 return i; 79 return i;
82} 80}
83 81
84struct sway_container *container_add_sibling(struct sway_container *fixed, 82swayc_t *add_sibling(swayc_t *fixed, swayc_t *active) {
85 struct sway_container *active) {
86 // TODO handle floating 83 // TODO handle floating
87 struct sway_container *parent = fixed->parent; 84 swayc_t *parent = fixed->parent;
88 int i = index_child(fixed); 85 int i = index_child(fixed);
89 list_insert(parent->children, i + 1, active); 86 list_insert(parent->children, i + 1, active);
90 active->parent = parent; 87 active->parent = parent;
91 return active->parent; 88 return active->parent;
92} 89}
93 90
94void container_add_child(struct sway_container *parent, 91void add_child(swayc_t *parent, swayc_t *child) {
95 struct sway_container *child) {
96 wlr_log(L_DEBUG, "Adding %p (%d, %fx%f) to %p (%d, %fx%f)", 92 wlr_log(L_DEBUG, "Adding %p (%d, %fx%f) to %p (%d, %fx%f)",
97 child, child->type, child->width, child->height, 93 child, child->type, child->width, child->height,
98 parent, parent->type, parent->width, parent->height); 94 parent, parent->type, parent->width, parent->height);
@@ -100,17 +96,15 @@ void container_add_child(struct sway_container *parent,
100 child->parent = parent; 96 child->parent = parent;
101 // set focus for this container 97 // set focus for this container
102 /* TODO WLR 98 /* TODO WLR
103 if (parent->type == C_WORKSPACE && child->type == C_VIEW && 99 if (parent->type == C_WORKSPACE && child->type == C_VIEW && (parent->workspace_layout == L_TABBED || parent->workspace_layout == L_STACKED)) {
104 (parent->workspace_layout == L_TABBED || parent->workspace_layout ==
105 L_STACKED)) {
106 child = new_container(child, parent->workspace_layout); 100 child = new_container(child, parent->workspace_layout);
107 } 101 }
108 */ 102 */
109} 103}
110 104
111struct sway_container *container_remove_child(struct sway_container *child) { 105swayc_t *remove_child(swayc_t *child) {
112 int i; 106 int i;
113 struct sway_container *parent = child->parent; 107 swayc_t *parent = child->parent;
114 for (i = 0; i < parent->children->length; ++i) { 108 for (i = 0; i < parent->children->length; ++i) {
115 if (parent->children->items[i] == child) { 109 if (parent->children->items[i] == child) {
116 list_del(parent->children, i); 110 list_del(parent->children, i);
@@ -121,8 +115,7 @@ struct sway_container *container_remove_child(struct sway_container *child) {
121 return parent; 115 return parent;
122} 116}
123 117
124enum sway_container_layout container_get_default_layout( 118enum swayc_layouts default_layout(swayc_t *output) {
125 struct sway_container *output) {
126 /* TODO WLR 119 /* TODO WLR
127 if (config->default_layout != L_NONE) { 120 if (config->default_layout != L_NONE) {
128 //return config->default_layout; 121 //return config->default_layout;
@@ -136,8 +129,8 @@ enum sway_container_layout container_get_default_layout(
136} 129}
137 130
138static int sort_workspace_cmp_qsort(const void *_a, const void *_b) { 131static int sort_workspace_cmp_qsort(const void *_a, const void *_b) {
139 struct sway_container *a = *(void **)_a; 132 swayc_t *a = *(void **)_a;
140 struct sway_container *b = *(void **)_b; 133 swayc_t *b = *(void **)_b;
141 int retval = 0; 134 int retval = 0;
142 135
143 if (isdigit(a->name[0]) && isdigit(b->name[0])) { 136 if (isdigit(a->name[0]) && isdigit(b->name[0])) {
@@ -153,22 +146,21 @@ static int sort_workspace_cmp_qsort(const void *_a, const void *_b) {
153 return retval; 146 return retval;
154} 147}
155 148
156void container_sort_workspaces(struct sway_container *output) { 149void sort_workspaces(swayc_t *output) {
157 list_stable_sort(output->children, sort_workspace_cmp_qsort); 150 list_stable_sort(output->children, sort_workspace_cmp_qsort);
158} 151}
159 152
160static void apply_horiz_layout(struct sway_container *container, const double x, 153static void apply_horiz_layout(swayc_t *container, const double x,
161 const double y, const double width, 154 const double y, const double width,
162 const double height, const int start, 155 const double height, const int start,
163 const int end); 156 const int end);
164 157
165static void apply_vert_layout(struct sway_container *container, const double x, 158static void apply_vert_layout(swayc_t *container, const double x,
166 const double y, const double width, 159 const double y, const double width,
167 const double height, const int start, 160 const double height, const int start,
168 const int end); 161 const int end);
169 162
170void arrange_windows(struct sway_container *container, 163void arrange_windows(swayc_t *container, double width, double height) {
171 double width, double height) {
172 int i; 164 int i;
173 if (width == -1 || height == -1) { 165 if (width == -1 || height == -1) {
174 width = container->width; 166 width = container->width;
@@ -189,7 +181,7 @@ void arrange_windows(struct sway_container *container,
189 case C_ROOT: 181 case C_ROOT:
190 // TODO: wlr_output_layout probably 182 // TODO: wlr_output_layout probably
191 for (i = 0; i < container->children->length; ++i) { 183 for (i = 0; i < container->children->length; ++i) {
192 struct sway_container *output = container->children->items[i]; 184 swayc_t *output = container->children->items[i];
193 wlr_log(L_DEBUG, "Arranging output '%s' at %f,%f", 185 wlr_log(L_DEBUG, "Arranging output '%s' at %f,%f",
194 output->name, output->x, output->y); 186 output->name, output->x, output->y);
195 arrange_windows(output, -1, -1); 187 arrange_windows(output, -1, -1);
@@ -205,14 +197,13 @@ void arrange_windows(struct sway_container *container,
205 } 197 }
206 // arrange all workspaces: 198 // arrange all workspaces:
207 for (i = 0; i < container->children->length; ++i) { 199 for (i = 0; i < container->children->length; ++i) {
208 struct sway_container *child = container->children->items[i]; 200 swayc_t *child = container->children->items[i];
209 arrange_windows(child, -1, -1); 201 arrange_windows(child, -1, -1);
210 } 202 }
211 return; 203 return;
212 case C_WORKSPACE: 204 case C_WORKSPACE:
213 { 205 {
214 struct sway_container *output = 206 swayc_t *output = swayc_parent_by_type(container, C_OUTPUT);
215 container_parent(container, C_OUTPUT);
216 struct wlr_box *area = &output->sway_output->usable_area; 207 struct wlr_box *area = &output->sway_output->usable_area;
217 wlr_log(L_DEBUG, "Usable area for ws: %dx%d@%d,%d", 208 wlr_log(L_DEBUG, "Usable area for ws: %dx%d@%d,%d",
218 area->width, area->height, area->x, area->y); 209 area->width, area->height, area->x, area->y);
@@ -261,15 +252,14 @@ void arrange_windows(struct sway_container *container,
261 } 252 }
262} 253}
263 254
264static void apply_horiz_layout(struct sway_container *container, 255static void apply_horiz_layout(swayc_t *container,
265 const double x, const double y, 256 const double x, const double y,
266 const double width, const double height, 257 const double width, const double height,
267 const int start, const int end) { 258 const int start, const int end) {
268 double scale = 0; 259 double scale = 0;
269 // Calculate total width 260 // Calculate total width
270 for (int i = start; i < end; ++i) { 261 for (int i = start; i < end; ++i) {
271 double *old_width = 262 double *old_width = &((swayc_t *)container->children->items[i])->width;
272 &((struct sway_container *)container->children->items[i])->width;
273 if (*old_width <= 0) { 263 if (*old_width <= 0) {
274 if (end - start > 1) { 264 if (end - start > 1) {
275 *old_width = width / (end - start - 1); 265 *old_width = width / (end - start - 1);
@@ -286,7 +276,7 @@ static void apply_horiz_layout(struct sway_container *container,
286 if (scale > 0.1) { 276 if (scale > 0.1) {
287 wlr_log(L_DEBUG, "Arranging %p horizontally", container); 277 wlr_log(L_DEBUG, "Arranging %p horizontally", container);
288 for (int i = start; i < end; ++i) { 278 for (int i = start; i < end; ++i) {
289 struct sway_container *child = container->children->items[i]; 279 swayc_t *child = container->children->items[i];
290 wlr_log(L_DEBUG, 280 wlr_log(L_DEBUG,
291 "Calculating arrangement for %p:%d (will scale %f by %f)", 281 "Calculating arrangement for %p:%d (will scale %f by %f)",
292 child, child->type, width, scale); 282 child, child->type, width, scale);
@@ -311,7 +301,7 @@ static void apply_horiz_layout(struct sway_container *container,
311 } 301 }
312} 302}
313 303
314void apply_vert_layout(struct sway_container *container, 304void apply_vert_layout(swayc_t *container,
315 const double x, const double y, 305 const double x, const double y,
316 const double width, const double height, const int start, 306 const double width, const double height, const int start,
317 const int end) { 307 const int end) {
@@ -319,8 +309,7 @@ void apply_vert_layout(struct sway_container *container,
319 double scale = 0; 309 double scale = 0;
320 // Calculate total height 310 // Calculate total height
321 for (i = start; i < end; ++i) { 311 for (i = start; i < end; ++i) {
322 double *old_height = 312 double *old_height = &((swayc_t *)container->children->items[i])->height;
323 &((struct sway_container *)container->children->items[i])->height;
324 if (*old_height <= 0) { 313 if (*old_height <= 0) {
325 if (end - start > 1) { 314 if (end - start > 1) {
326 *old_height = height / (end - start - 1); 315 *old_height = height / (end - start - 1);
@@ -337,7 +326,7 @@ void apply_vert_layout(struct sway_container *container,
337 if (scale > 0.1) { 326 if (scale > 0.1) {
338 wlr_log(L_DEBUG, "Arranging %p vertically", container); 327 wlr_log(L_DEBUG, "Arranging %p vertically", container);
339 for (i = start; i < end; ++i) { 328 for (i = start; i < end; ++i) {
340 struct sway_container *child = container->children->items[i]; 329 swayc_t *child = container->children->items[i];
341 wlr_log(L_DEBUG, 330 wlr_log(L_DEBUG,
342 "Calculating arrangement for %p:%d (will scale %f by %f)", 331 "Calculating arrangement for %p:%d (will scale %f by %f)",
343 child, child->type, height, scale); 332 child, child->type, height, scale);
@@ -365,16 +354,15 @@ void apply_vert_layout(struct sway_container *container,
365/** 354/**
366 * Get swayc in the direction of newly entered output. 355 * Get swayc in the direction of newly entered output.
367 */ 356 */
368static struct sway_container *get_swayc_in_output_direction( 357static swayc_t *get_swayc_in_output_direction(swayc_t *output,
369 struct sway_container *output, enum movement_direction dir, 358 enum movement_direction dir, struct sway_seat *seat) {
370 struct sway_seat *seat) {
371 if (!output) { 359 if (!output) {
372 return NULL; 360 return NULL;
373 } 361 }
374 362
375 struct sway_container *ws = sway_seat_get_focus_inactive(seat, output); 363 swayc_t *ws = sway_seat_get_focus_inactive(seat, output);
376 if (ws->type != C_WORKSPACE) { 364 if (ws->type != C_WORKSPACE) {
377 ws = container_parent(ws, C_WORKSPACE); 365 ws = swayc_parent_by_type(ws, C_WORKSPACE);
378 } 366 }
379 367
380 if (ws == NULL) { 368 if (ws == NULL) {
@@ -392,15 +380,13 @@ static struct sway_container *get_swayc_in_output_direction(
392 return ws->children->items[0]; 380 return ws->children->items[0];
393 case MOVE_UP: 381 case MOVE_UP:
394 case MOVE_DOWN: { 382 case MOVE_DOWN: {
395 struct sway_container *focused = 383 swayc_t *focused = sway_seat_get_focus_inactive(seat, ws);
396 sway_seat_get_focus_inactive(seat, ws);
397 if (focused && focused->parent) { 384 if (focused && focused->parent) {
398 struct sway_container *parent = focused->parent; 385 swayc_t *parent = focused->parent;
399 if (parent->layout == L_VERT) { 386 if (parent->layout == L_VERT) {
400 if (dir == MOVE_UP) { 387 if (dir == MOVE_UP) {
401 // get child furthest down on new output 388 // get child furthest down on new output
402 int idx = parent->children->length - 1; 389 return parent->children->items[parent->children->length-1];
403 return parent->children->items[idx];
404 } else if (dir == MOVE_DOWN) { 390 } else if (dir == MOVE_DOWN) {
405 // get child furthest up on new output 391 // get child furthest up on new output
406 return parent->children->items[0]; 392 return parent->children->items[0];
@@ -418,14 +404,13 @@ static struct sway_container *get_swayc_in_output_direction(
418 return ws; 404 return ws;
419} 405}
420 406
421static void get_layout_center_position(struct sway_container *container, 407static void get_layout_center_position(swayc_t *container, int *x, int *y) {
422 int *x, int *y) {
423 // FIXME view coords are inconsistently referred to in layout/output systems 408 // FIXME view coords are inconsistently referred to in layout/output systems
424 if (container->type == C_OUTPUT) { 409 if (container->type == C_OUTPUT) {
425 *x = container->x + container->width/2; 410 *x = container->x + container->width/2;
426 *y = container->y + container->height/2; 411 *y = container->y + container->height/2;
427 } else { 412 } else {
428 struct sway_container *output = container_parent(container, C_OUTPUT); 413 swayc_t *output = swayc_parent_by_type(container, C_OUTPUT);
429 if (container->type == C_WORKSPACE) { 414 if (container->type == C_WORKSPACE) {
430 // Workspace coordinates are actually wrong/arbitrary, but should 415 // Workspace coordinates are actually wrong/arbitrary, but should
431 // be same as output. 416 // be same as output.
@@ -438,8 +423,7 @@ static void get_layout_center_position(struct sway_container *container,
438 } 423 }
439} 424}
440 425
441static bool sway_dir_to_wlr(enum movement_direction dir, 426static bool sway_dir_to_wlr(enum movement_direction dir, enum wlr_direction *out) {
442 enum wlr_direction *out) {
443 switch (dir) { 427 switch (dir) {
444 case MOVE_UP: 428 case MOVE_UP:
445 *out = WLR_DIRECTION_UP; 429 *out = WLR_DIRECTION_UP;
@@ -460,12 +444,12 @@ static bool sway_dir_to_wlr(enum movement_direction dir,
460 return true; 444 return true;
461} 445}
462 446
463static struct sway_container *sway_output_from_wlr(struct wlr_output *output) { 447static swayc_t *sway_output_from_wlr(struct wlr_output *output) {
464 if (output == NULL) { 448 if (output == NULL) {
465 return NULL; 449 return NULL;
466 } 450 }
467 for (int i = 0; i < root_container.children->length; ++i) { 451 for (int i = 0; i < root_container.children->length; ++i) {
468 struct sway_container *o = root_container.children->items[i]; 452 swayc_t *o = root_container.children->items[i];
469 if (o->type == C_OUTPUT && o->sway_output->wlr_output == output) { 453 if (o->type == C_OUTPUT && o->sway_output->wlr_output == output) {
470 return o; 454 return o;
471 } 455 }
@@ -473,14 +457,13 @@ static struct sway_container *sway_output_from_wlr(struct wlr_output *output) {
473 return NULL; 457 return NULL;
474} 458}
475 459
476static struct sway_container *get_swayc_in_direction_under( 460static swayc_t *get_swayc_in_direction_under(swayc_t *container,
477 struct sway_container *container, enum movement_direction dir, 461 enum movement_direction dir, struct sway_seat *seat, swayc_t *limit) {
478 struct sway_seat *seat, struct sway_container *limit) {
479 if (dir == MOVE_CHILD) { 462 if (dir == MOVE_CHILD) {
480 return sway_seat_get_focus_inactive(seat, container); 463 return sway_seat_get_focus_inactive(seat, container);
481 } 464 }
482 465
483 struct sway_container *parent = container->parent; 466 swayc_t *parent = container->parent;
484 if (dir == MOVE_PARENT) { 467 if (dir == MOVE_PARENT) {
485 if (parent->type == C_OUTPUT) { 468 if (parent->type == C_OUTPUT) {
486 return NULL; 469 return NULL;
@@ -513,10 +496,9 @@ static struct sway_container *get_swayc_in_direction_under(
513 /* 496 /*
514 if (container->type == C_VIEW && swayc_is_fullscreen(container)) { 497 if (container->type == C_VIEW && swayc_is_fullscreen(container)) {
515 wlr_log(L_DEBUG, "Moving from fullscreen view, skipping to output"); 498 wlr_log(L_DEBUG, "Moving from fullscreen view, skipping to output");
516 container = container_parent(container, C_OUTPUT); 499 container = swayc_parent_by_type(container, C_OUTPUT);
517 get_layout_center_position(container, &abs_pos); 500 get_layout_center_position(container, &abs_pos);
518 struct sway_container *output = 501 swayc_t *output = swayc_adjacent_output(container, dir, &abs_pos, true);
519 swayc_adjacent_output(container, dir, &abs_pos, true);
520 return get_swayc_in_output_direction(output, dir); 502 return get_swayc_in_output_direction(output, dir);
521 } 503 }
522 if (container->type == C_WORKSPACE && container->fullscreen) { 504 if (container->type == C_WORKSPACE && container->fullscreen) {
@@ -525,7 +507,7 @@ static struct sway_container *get_swayc_in_direction_under(
525 } 507 }
526 */ 508 */
527 509
528 struct sway_container *wrap_candidate = NULL; 510 swayc_t *wrap_candidate = NULL;
529 while (true) { 511 while (true) {
530 // Test if we can even make a difference here 512 // Test if we can even make a difference here
531 bool can_move = false; 513 bool can_move = false;
@@ -539,19 +521,16 @@ static struct sway_container *get_swayc_in_direction_under(
539 } 521 }
540 int lx, ly; 522 int lx, ly;
541 get_layout_center_position(container, &lx, &ly); 523 get_layout_center_position(container, &lx, &ly);
542 struct wlr_output_layout *layout = 524 struct wlr_output_layout *layout = root_container.sway_root->output_layout;
543 root_container.sway_root->output_layout;
544 struct wlr_output *wlr_adjacent = 525 struct wlr_output *wlr_adjacent =
545 wlr_output_layout_adjacent_output(layout, wlr_dir, 526 wlr_output_layout_adjacent_output(layout, wlr_dir,
546 container->sway_output->wlr_output, lx, ly); 527 container->sway_output->wlr_output, lx, ly);
547 struct sway_container *adjacent = 528 swayc_t *adjacent = sway_output_from_wlr(wlr_adjacent);
548 sway_output_from_wlr(wlr_adjacent);
549 529
550 if (!adjacent || adjacent == container) { 530 if (!adjacent || adjacent == container) {
551 return wrap_candidate; 531 return wrap_candidate;
552 } 532 }
553 struct sway_container *next = 533 swayc_t *next = get_swayc_in_output_direction(adjacent, dir, seat);
554 get_swayc_in_output_direction(adjacent, dir, seat);
555 if (next == NULL) { 534 if (next == NULL) {
556 return NULL; 535 return NULL;
557 } 536 }
@@ -591,9 +570,8 @@ static struct sway_container *get_swayc_in_direction_under(
591 } 570 }
592 } 571 }
593 } else { 572 } else {
594 wlr_log(L_DEBUG, 573 wlr_log(L_DEBUG, "%s cont %d-%p dir %i sibling %d: %p", __func__,
595 "cont %d-%p dir %i sibling %d: %p", idx, 574 idx, container, dir, desired, parent->children->items[desired]);
596 container, dir, desired, parent->children->items[desired]);
597 return parent->children->items[desired]; 575 return parent->children->items[desired];
598 } 576 }
599 } 577 }
@@ -609,8 +587,7 @@ static struct sway_container *get_swayc_in_direction_under(
609 } 587 }
610} 588}
611 589
612struct sway_container *container_get_in_direction( 590swayc_t *get_swayc_in_direction(swayc_t *container, struct sway_seat *seat,
613 struct sway_container *container, struct sway_seat *seat,
614 enum movement_direction dir) { 591 enum movement_direction dir) {
615 return get_swayc_in_direction_under(container, dir, seat, NULL); 592 return get_swayc_in_direction_under(container, dir, seat, NULL);
616} 593}
diff --git a/sway/tree/view.c b/sway/tree/view.c
index d5325c31..9499adca 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -1,8 +1,8 @@
1#include <wayland-server.h> 1#include <wayland-server.h>
2#include <wlr/types/wlr_output_layout.h> 2#include <wlr/types/wlr_output_layout.h>
3#include "sway/tree/container.h" 3#include "sway/container.h"
4#include "sway/tree/layout.h" 4#include "sway/layout.h"
5#include "sway/tree/view.h" 5#include "sway/view.h"
6 6
7const char *view_get_title(struct sway_view *view) { 7const char *view_get_title(struct sway_view *view) {
8 if (view->iface.get_prop) { 8 if (view->iface.get_prop) {
@@ -45,7 +45,6 @@ void view_set_size(struct sway_view *view, int width, int height) {
45 } 45 }
46} 46}
47 47
48// TODO make view coordinates in layout coordinates
49void view_set_position(struct sway_view *view, double ox, double oy) { 48void view_set_position(struct sway_view *view, double ox, double oy) {
50 if (view->iface.set_position) { 49 if (view->iface.set_position) {
51 struct wlr_box box = { 50 struct wlr_box box = {
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c
index ba04c55c..861fda4d 100644
--- a/sway/tree/workspace.c
+++ b/sway/tree/workspace.c
@@ -3,10 +3,10 @@
3#include <stdlib.h> 3#include <stdlib.h>
4#include <stdio.h> 4#include <stdio.h>
5#include <strings.h> 5#include <strings.h>
6#include "sway/tree/container.h" 6#include "sway/container.h"
7#include "sway/input/input-manager.h" 7#include "sway/input/input-manager.h"
8#include "sway/input/seat.h" 8#include "sway/input/seat.h"
9#include "sway/tree/workspace.h" 9#include "sway/workspace.h"
10#include "log.h" 10#include "log.h"
11#include "util.h" 11#include "util.h"
12 12
@@ -17,7 +17,7 @@ struct workspace_by_number_data {
17 const char *name; 17 const char *name;
18}; 18};
19 19
20void next_name_map(struct sway_container *ws, void *data) { 20void next_name_map(swayc_t *ws, void *data) {
21 int *count = data; 21 int *count = data;
22 ++count; 22 ++count;
23} 23}
@@ -37,7 +37,7 @@ char *workspace_next_name(const char *output_name) {
37 return name; 37 return name;
38} 38}
39 39
40static bool _workspace_by_number(struct sway_container *view, void *data) { 40static bool _workspace_by_number(swayc_t *view, void *data) {
41 if (view->type != C_WORKSPACE) { 41 if (view->type != C_WORKSPACE) {
42 return false; 42 return false;
43 } 43 }
@@ -46,28 +46,27 @@ static bool _workspace_by_number(struct sway_container *view, void *data) {
46 return a == wbnd->len && strncmp(view->name, wbnd->name, a) == 0; 46 return a == wbnd->len && strncmp(view->name, wbnd->name, a) == 0;
47} 47}
48 48
49struct sway_container *workspace_by_number(const char* name) { 49swayc_t *workspace_by_number(const char* name) {
50 struct workspace_by_number_data wbnd = {0, "1234567890", name}; 50 struct workspace_by_number_data wbnd = {0, "1234567890", name};
51 wbnd.len = strspn(name, wbnd.cset); 51 wbnd.len = strspn(name, wbnd.cset);
52 if (wbnd.len <= 0) { 52 if (wbnd.len <= 0) {
53 return NULL; 53 return NULL;
54 } 54 }
55 return container_find(&root_container, 55 return swayc_by_test(&root_container, _workspace_by_number, (void *) &wbnd);
56 _workspace_by_number, (void *) &wbnd);
57} 56}
58 57
59static bool _workspace_by_name(struct sway_container *view, void *data) { 58static bool _workspace_by_name(swayc_t *view, void *data) {
60 return (view->type == C_WORKSPACE) && 59 return (view->type == C_WORKSPACE) &&
61 (strcasecmp(view->name, (char *) data) == 0); 60 (strcasecmp(view->name, (char *) data) == 0);
62} 61}
63 62
64struct sway_container *workspace_by_name(const char *name) { 63swayc_t *workspace_by_name(const char *name) {
65 struct sway_seat *seat = input_manager_current_seat(input_manager); 64 struct sway_seat *seat = input_manager_current_seat(input_manager);
66 struct sway_container *current_workspace = NULL, *current_output = NULL; 65 swayc_t *current_workspace = NULL, *current_output = NULL;
67 struct sway_container *focus = sway_seat_get_focus(seat); 66 swayc_t *focus = sway_seat_get_focus(seat);
68 if (focus) { 67 if (focus) {
69 current_workspace = container_parent(focus, C_WORKSPACE); 68 current_workspace = swayc_parent_by_type(focus, C_WORKSPACE);
70 current_output = container_parent(focus, C_OUTPUT); 69 current_output = swayc_parent_by_type(focus, C_OUTPUT);
71 } 70 }
72 if (strcmp(name, "prev") == 0) { 71 if (strcmp(name, "prev") == 0) {
73 return workspace_prev(current_workspace); 72 return workspace_prev(current_workspace);
@@ -80,13 +79,12 @@ struct sway_container *workspace_by_name(const char *name) {
80 } else if (strcmp(name, "current") == 0) { 79 } else if (strcmp(name, "current") == 0) {
81 return current_workspace; 80 return current_workspace;
82 } else { 81 } else {
83 return container_find(&root_container, _workspace_by_name, 82 return swayc_by_test(&root_container, _workspace_by_name, (void *) name);
84 (void *)name);
85 } 83 }
86} 84}
87 85
88struct sway_container *workspace_create(const char *name) { 86swayc_t *workspace_create(const char *name) {
89 struct sway_container *parent; 87 swayc_t *parent;
90 // Search for workspace<->output pair 88 // Search for workspace<->output pair
91 int i, e = config->workspace_outputs->length; 89 int i, e = config->workspace_outputs->length;
92 for (i = 0; i < e; ++i) { 90 for (i = 0; i < e; ++i) {
@@ -97,7 +95,7 @@ struct sway_container *workspace_create(const char *name) {
97 for (i = 0; i < e; ++i) { 95 for (i = 0; i < e; ++i) {
98 parent = root_container.children->items[i]; 96 parent = root_container.children->items[i];
99 if (strcmp(parent->name, wso->output) == 0) { 97 if (strcmp(parent->name, wso->output) == 0) {
100 return container_workspace_create(parent, name); 98 return new_workspace(parent, name);
101 } 99 }
102 } 100 }
103 break; 101 break;
@@ -105,11 +103,10 @@ struct sway_container *workspace_create(const char *name) {
105 } 103 }
106 // Otherwise create a new one 104 // Otherwise create a new one
107 struct sway_seat *seat = input_manager_current_seat(input_manager); 105 struct sway_seat *seat = input_manager_current_seat(input_manager);
108 struct sway_container *focus = 106 swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container);
109 sway_seat_get_focus_inactive(seat, &root_container);
110 parent = focus; 107 parent = focus;
111 parent = container_parent(parent, C_OUTPUT); 108 parent = swayc_parent_by_type(parent, C_OUTPUT);
112 return container_workspace_create(parent, name); 109 return new_workspace(parent, name);
113} 110}
114 111
115/** 112/**
@@ -117,18 +114,17 @@ struct sway_container *workspace_create(const char *name) {
117 * the end and beginning. If next is false, the previous workspace is returned, 114 * the end and beginning. If next is false, the previous workspace is returned,
118 * otherwise the next one is returned. 115 * otherwise the next one is returned.
119 */ 116 */
120struct sway_container *workspace_output_prev_next_impl( 117swayc_t *workspace_output_prev_next_impl(swayc_t *output, bool next) {
121 struct sway_container *output, bool next) {
122 if (!sway_assert(output->type == C_OUTPUT, 118 if (!sway_assert(output->type == C_OUTPUT,
123 "Argument must be an output, is %d", output->type)) { 119 "Argument must be an output, is %d", output->type)) {
124 return NULL; 120 return NULL;
125 } 121 }
126 122
127 struct sway_seat *seat = input_manager_current_seat(input_manager); 123 struct sway_seat *seat = input_manager_current_seat(input_manager);
128 struct sway_container *focus = sway_seat_get_focus_inactive(seat, output); 124 swayc_t *focus = sway_seat_get_focus_inactive(seat, output);
129 struct sway_container *workspace = (focus->type == C_WORKSPACE ? 125 swayc_t *workspace = (focus->type == C_WORKSPACE ?
130 focus : 126 focus :
131 container_parent(focus, C_WORKSPACE)); 127 swayc_parent_by_type(focus, C_WORKSPACE));
132 128
133 int i; 129 int i;
134 for (i = 0; i < output->children->length; i++) { 130 for (i = 0; i < output->children->length; i++) {
@@ -138,8 +134,7 @@ struct sway_container *workspace_output_prev_next_impl(
138 } 134 }
139 } 135 }
140 136
141 // Doesn't happen, at worst the for loop returns the previously active 137 // Doesn't happen, at worst the for loop returns the previously active workspace
142 // workspace
143 return NULL; 138 return NULL;
144} 139}
145 140
@@ -149,14 +144,13 @@ struct sway_container *workspace_output_prev_next_impl(
149 * next is false, the previous workspace is returned, otherwise the next one is 144 * next is false, the previous workspace is returned, otherwise the next one is
150 * returned. 145 * returned.
151 */ 146 */
152struct sway_container *workspace_prev_next_impl( 147swayc_t *workspace_prev_next_impl(swayc_t *workspace, bool next) {
153 struct sway_container *workspace, bool next) {
154 if (!sway_assert(workspace->type == C_WORKSPACE, 148 if (!sway_assert(workspace->type == C_WORKSPACE,
155 "Argument must be a workspace, is %d", workspace->type)) { 149 "Argument must be a workspace, is %d", workspace->type)) {
156 return NULL; 150 return NULL;
157 } 151 }
158 152
159 struct sway_container *current_output = workspace->parent; 153 swayc_t *current_output = workspace->parent;
160 int offset = next ? 1 : -1; 154 int offset = next ? 1 : -1;
161 int start = next ? 0 : 1; 155 int start = next ? 0 : 1;
162 int end; 156 int end;
@@ -172,57 +166,54 @@ struct sway_container *workspace_prev_next_impl(
172 } 166 }
173 } 167 }
174 168
175 // Given workspace is the first/last on the output, jump to the 169 // Given workspace is the first/last on the output, jump to the previous/next output
176 // previous/next output
177 int num_outputs = root_container.children->length; 170 int num_outputs = root_container.children->length;
178 for (i = 0; i < num_outputs; i++) { 171 for (i = 0; i < num_outputs; i++) {
179 if (root_container.children->items[i] == current_output) { 172 if (root_container.children->items[i] == current_output) {
180 struct sway_container *next_output = root_container.children->items[ 173 swayc_t *next_output = root_container.children->items[
181 wrap(i + offset, num_outputs)]; 174 wrap(i + offset, num_outputs)];
182 return workspace_output_prev_next_impl(next_output, next); 175 return workspace_output_prev_next_impl(next_output, next);
183 } 176 }
184 } 177 }
185 178
186 // Doesn't happen, at worst the for loop returns the previously active 179 // Doesn't happen, at worst the for loop returns the previously active workspace on the active output
187 // workspace on the active output
188 return NULL; 180 return NULL;
189} 181}
190 182
191struct sway_container *workspace_output_next(struct sway_container *current) { 183swayc_t *workspace_output_next(swayc_t *current) {
192 return workspace_output_prev_next_impl(current, true); 184 return workspace_output_prev_next_impl(current, true);
193} 185}
194 186
195struct sway_container *workspace_next(struct sway_container *current) { 187swayc_t *workspace_next(swayc_t *current) {
196 return workspace_prev_next_impl(current, true); 188 return workspace_prev_next_impl(current, true);
197} 189}
198 190
199struct sway_container *workspace_output_prev(struct sway_container *current) { 191swayc_t *workspace_output_prev(swayc_t *current) {
200 return workspace_output_prev_next_impl(current, false); 192 return workspace_output_prev_next_impl(current, false);
201} 193}
202 194
203struct sway_container *workspace_prev(struct sway_container *current) { 195swayc_t *workspace_prev(swayc_t *current) {
204 return workspace_prev_next_impl(current, false); 196 return workspace_prev_next_impl(current, false);
205} 197}
206 198
207bool workspace_switch(struct sway_container *workspace) { 199bool workspace_switch(swayc_t *workspace) {
208 if (!workspace) { 200 if (!workspace) {
209 return false; 201 return false;
210 } 202 }
211 struct sway_seat *seat = input_manager_current_seat(input_manager); 203 struct sway_seat *seat = input_manager_current_seat(input_manager);
212 struct sway_container *focus = 204 swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container);
213 sway_seat_get_focus_inactive(seat, &root_container);
214 if (!seat || !focus) { 205 if (!seat || !focus) {
215 return false; 206 return false;
216 } 207 }
217 struct sway_container *active_ws = focus; 208 swayc_t *active_ws = focus;
218 if (active_ws->type != C_WORKSPACE) { 209 if (active_ws->type != C_WORKSPACE) {
219 container_parent(focus, C_WORKSPACE); 210 swayc_parent_by_type(focus, C_WORKSPACE);
220 } 211 }
221 212
222 if (config->auto_back_and_forth 213 if (config->auto_back_and_forth
223 && active_ws == workspace 214 && active_ws == workspace
224 && prev_workspace_name) { 215 && prev_workspace_name) {
225 struct sway_container *new_ws = workspace_by_name(prev_workspace_name); 216 swayc_t *new_ws = workspace_by_name(prev_workspace_name);
226 workspace = new_ws ? new_ws : workspace_create(prev_workspace_name); 217 workspace = new_ws ? new_ws : workspace_create(prev_workspace_name);
227 } 218 }
228 219
@@ -239,14 +230,13 @@ bool workspace_switch(struct sway_container *workspace) {
239 230
240 // TODO: Deal with sticky containers 231 // TODO: Deal with sticky containers
241 232
242 wlr_log(L_DEBUG, "Switching to workspace %p:%s", 233 wlr_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name);
243 workspace, workspace->name); 234 swayc_t *next = sway_seat_get_focus_inactive(seat, workspace);
244 struct sway_container *next = sway_seat_get_focus_inactive(seat, workspace);
245 if (next == NULL) { 235 if (next == NULL) {
246 next = workspace; 236 next = workspace;
247 } 237 }
248 sway_seat_set_focus(seat, next); 238 sway_seat_set_focus(seat, next);
249 struct sway_container *output = container_parent(workspace, C_OUTPUT); 239 swayc_t *output = swayc_parent_by_type(workspace, C_OUTPUT);
250 arrange_windows(output, -1, -1); 240 arrange_windows(output, -1, -1);
251 return true; 241 return true;
252} 242}