summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar taiyu <taiyu.len@gmail.com>2015-08-20 09:52:54 -0700
committerLibravatar taiyu <taiyu.len@gmail.com>2015-08-20 09:52:54 -0700
commit36e07e9ebc55b3fc8a8b8cd76ee743202691ad56 (patch)
treee9e2a9d9db46044ab7cd7bd4dcb7ca2650a89f70
parentMerge pull request #75 from minus7/ipc (diff)
downloadsway-36e07e9ebc55b3fc8a8b8cd76ee743202691ad56.tar.gz
sway-36e07e9ebc55b3fc8a8b8cd76ee743202691ad56.tar.zst
sway-36e07e9ebc55b3fc8a8b8cd76ee743202691ad56.zip
find_parent_by_type
-rw-r--r--include/container.h11
-rw-r--r--sway/commands.c5
-rw-r--r--sway/container.c138
-rw-r--r--sway/handlers.c15
-rw-r--r--sway/layout.c10
-rw-r--r--sway/workspace.c4
6 files changed, 112 insertions, 71 deletions
diff --git a/include/container.h b/include/container.h
index bd92058d..fd621490 100644
--- a/include/container.h
+++ b/include/container.h
@@ -55,6 +55,7 @@ struct sway_container {
55 struct sway_container *focused; 55 struct sway_container *focused;
56}; 56};
57 57
58// Container Creation
58 59
59swayc_t *new_output(wlc_handle handle); 60swayc_t *new_output(wlc_handle handle);
60swayc_t *new_workspace(swayc_t *output, const char *name); 61swayc_t *new_workspace(swayc_t *output, const char *name);
@@ -65,13 +66,23 @@ swayc_t *new_view(swayc_t *sibling, wlc_handle handle);
65// Creates view as a new floating view which is in the active workspace 66// Creates view as a new floating view which is in the active workspace
66swayc_t *new_floating_view(wlc_handle handle); 67swayc_t *new_floating_view(wlc_handle handle);
67 68
69// Container Destroying
68 70
69swayc_t *destroy_output(swayc_t *output); 71swayc_t *destroy_output(swayc_t *output);
70// Destroys workspace if empty and returns parent pointer, else returns NULL 72// Destroys workspace if empty and returns parent pointer, else returns NULL
71swayc_t *destroy_workspace(swayc_t *workspace); 73swayc_t *destroy_workspace(swayc_t *workspace);
74// Destroyes container and all parent container if they are empty, returns
75// topmost non-empty parent. returns NULL otherwise
72swayc_t *destroy_container(swayc_t *container); 76swayc_t *destroy_container(swayc_t *container);
77// Destroys view and all empty parent containers. return topmost non-empty
78// parent
73swayc_t *destroy_view(swayc_t *view); 79swayc_t *destroy_view(swayc_t *view);
74 80
81// Container Lookup
82
83swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types);
84swayc_t *swayc_parent_by_layout(swayc_t *container, enum swayc_layouts);
85
75swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data); 86swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data);
76void container_map(swayc_t *, void (*f)(swayc_t *, void *), void *); 87void container_map(swayc_t *, void (*f)(swayc_t *, void *), void *);
77 88
diff --git a/sway/commands.c b/sway/commands.c
index 644b8005..3ac7f4dd 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -390,7 +390,6 @@ static bool cmd_layout(struct sway_config *config, int argc, char **argv) {
390 return false; 390 return false;
391 } 391 }
392 swayc_t *parent = get_focused_container(&root_container); 392 swayc_t *parent = get_focused_container(&root_container);
393
394 while (parent->type == C_VIEW) { 393 while (parent->type == C_VIEW) {
395 parent = parent->parent; 394 parent = parent->parent;
396 } 395 }
@@ -512,9 +511,7 @@ static bool cmd_fullscreen(struct sway_config *config, int argc, char **argv) {
512 // Resize workspace if going from fullscreen -> notfullscreen 511 // Resize workspace if going from fullscreen -> notfullscreen
513 // otherwise just resize container 512 // otherwise just resize container
514 if (current) { 513 if (current) {
515 while (container->type != C_WORKSPACE) { 514 container = swayc_parent_by_type(container, C_WORKSPACE);
516 container = container->parent;
517 }
518 } 515 }
519 // Only resize container when going into fullscreen 516 // Only resize container when going into fullscreen
520 arrange_windows(container, -1, -1); 517 arrange_windows(container, -1, -1);
diff --git a/sway/container.c b/sway/container.c
index 4559a5f5..7ccc2e09 100644
--- a/sway/container.c
+++ b/sway/container.c
@@ -8,6 +8,8 @@
8#include "layout.h" 8#include "layout.h"
9#include "log.h" 9#include "log.h"
10 10
11#define ASSERT_NONNULL(PTR) \
12 sway_assert (PTR, "%s: " #PTR "must be non-null", __func__)
11 13
12static swayc_t *new_swayc(enum swayc_types type) { 14static swayc_t *new_swayc(enum swayc_types type) {
13 swayc_t *c = calloc(1, sizeof(swayc_t)); 15 swayc_t *c = calloc(1, sizeof(swayc_t));
@@ -20,37 +22,40 @@ static swayc_t *new_swayc(enum swayc_types type) {
20 return c; 22 return c;
21} 23}
22 24
23static void free_swayc(swayc_t *c) { 25static void free_swayc(swayc_t *cont) {
26 if (!ASSERT_NONNULL(cont)) {
27 return;
28 }
24 // TODO does not properly handle containers with children, 29 // TODO does not properly handle containers with children,
25 // TODO but functions that call this usually check for that 30 // TODO but functions that call this usually check for that
26 if (c->children) { 31 if (cont->children) {
27 if (c->children->length) { 32 if (cont->children->length) {
28 int i; 33 int i;
29 for (i = 0; i < c->children->length; ++i) { 34 for (i = 0; i < cont->children->length; ++i) {
30 free_swayc(c->children->items[i]); 35 free_swayc(cont->children->items[i]);
31 } 36 }
32 } 37 }
33 list_free(c->children); 38 list_free(cont->children);
34 } 39 }
35 if (c->floating) { 40 if (cont->floating) {
36 if (c->floating->length) { 41 if (cont->floating->length) {
37 int i; 42 int i;
38 for (i = 0; i < c->floating->length; ++i) { 43 for (i = 0; i < cont->floating->length; ++i) {
39 free_swayc(c->floating->items[i]); 44 free_swayc(cont->floating->items[i]);
40 } 45 }
41 } 46 }
42 list_free(c->floating); 47 list_free(cont->floating);
43 } 48 }
44 if (c->parent) { 49 if (cont->parent) {
45 remove_child(c); 50 remove_child(cont);
46 } 51 }
47 if (c->name) { 52 if (cont->name) {
48 free(c->name); 53 free(cont->name);
49 } 54 }
50 free(c); 55 free(cont);
51} 56}
52 57
53/* New containers */ 58// New containers
54 59
55static bool workspace_test(swayc_t *view, void *name) { 60static bool workspace_test(swayc_t *view, void *name) {
56 return strcasecmp(view->name, (char *)name) == 0; 61 return strcasecmp(view->name, (char *)name) == 0;
@@ -103,6 +108,9 @@ swayc_t *new_output(wlc_handle handle) {
103} 108}
104 109
105swayc_t *new_workspace(swayc_t *output, const char *name) { 110swayc_t *new_workspace(swayc_t *output, const char *name) {
111 if (!ASSERT_NONNULL(output)) {
112 return NULL;
113 }
106 sway_log(L_DEBUG, "Added workspace %s for output %u", name, (unsigned int)output->handle); 114 sway_log(L_DEBUG, "Added workspace %s for output %u", name, (unsigned int)output->handle);
107 swayc_t *workspace = new_swayc(C_WORKSPACE); 115 swayc_t *workspace = new_swayc(C_WORKSPACE);
108 116
@@ -120,6 +128,9 @@ swayc_t *new_workspace(swayc_t *output, const char *name) {
120} 128}
121 129
122swayc_t *new_container(swayc_t *child, enum swayc_layouts layout) { 130swayc_t *new_container(swayc_t *child, enum swayc_layouts layout) {
131 if (!ASSERT_NONNULL(child)) {
132 return NULL;
133 }
123 swayc_t *cont = new_swayc(C_CONTAINER); 134 swayc_t *cont = new_swayc(C_CONTAINER);
124 135
125 sway_log(L_DEBUG, "creating container %p around %p", cont, child); 136 sway_log(L_DEBUG, "creating container %p around %p", cont, child);
@@ -162,6 +173,9 @@ swayc_t *new_container(swayc_t *child, enum swayc_layouts layout) {
162} 173}
163 174
164swayc_t *new_view(swayc_t *sibling, wlc_handle handle) { 175swayc_t *new_view(swayc_t *sibling, wlc_handle handle) {
176 if (!ASSERT_NONNULL(sibling)) {
177 return NULL;
178 }
165 const char *title = wlc_view_get_title(handle); 179 const char *title = wlc_view_get_title(handle);
166 swayc_t *view = new_swayc(C_VIEW); 180 swayc_t *view = new_swayc(C_VIEW);
167 sway_log(L_DEBUG, "Adding new view %lu:%s to container %p %d", 181 sway_log(L_DEBUG, "Adding new view %lu:%s to container %p %d",
@@ -172,14 +186,14 @@ swayc_t *new_view(swayc_t *sibling, wlc_handle handle) {
172 view->visible = true; 186 view->visible = true;
173 view->is_focused = true; 187 view->is_focused = true;
174 // Setup geometry 188 // Setup geometry
189 const struct wlc_geometry* geometry = wlc_view_get_geometry(handle);
175 view->width = 0; 190 view->width = 0;
176 view->height = 0; 191 view->height = 0;
192 view->desired_width = geometry->size.w;
193 view->desired_height = geometry->size.h;
177 194
178 view->gaps = config->gaps_inner; 195 view->gaps = config->gaps_inner;
179 196
180 view->desired_width = -1;
181 view->desired_height = -1;
182
183 view->is_floating = false; 197 view->is_floating = false;
184 198
185 if (sibling->type == C_WORKSPACE) { 199 if (sibling->type == C_WORKSPACE) {
@@ -225,9 +239,12 @@ swayc_t *new_floating_view(wlc_handle handle) {
225 return view; 239 return view;
226} 240}
227 241
228/* Destroy container */ 242// Destroy container
229 243
230swayc_t *destroy_output(swayc_t *output) { 244swayc_t *destroy_output(swayc_t *output) {
245 if (!ASSERT_NONNULL(output)) {
246 return NULL;
247 }
231 if (output->children->length == 0) { 248 if (output->children->length == 0) {
232 // TODO move workspaces to other outputs 249 // TODO move workspaces to other outputs
233 } 250 }
@@ -237,23 +254,21 @@ swayc_t *destroy_output(swayc_t *output) {
237} 254}
238 255
239swayc_t *destroy_workspace(swayc_t *workspace) { 256swayc_t *destroy_workspace(swayc_t *workspace) {
257 if (!ASSERT_NONNULL(workspace)) {
258 return NULL;
259 }
240 // NOTE: This is called from elsewhere without checking children length 260 // NOTE: This is called from elsewhere without checking children length
241 // TODO move containers to other workspaces? 261 // TODO move containers to other workspaces?
242 // for now just dont delete 262 // for now just dont delete
243 263
244 // Do not destroy this if it's the last workspace on this output 264 // Do not destroy this if it's the last workspace on this output
245 swayc_t *output = workspace->parent; 265 swayc_t *output = swayc_parent_by_type(workspace, C_OUTPUT);
246 while (output && output->type != C_OUTPUT) { 266 if (output && output->children->length == 1) {
247 output = output->parent; 267 return NULL;
248 }
249 if (output) {
250 if (output->children->length == 1) {
251 return NULL;
252 }
253 } 268 }
254 269
255 if (workspace->children->length == 0) { 270 if (workspace->children->length == 0) {
256 sway_log(L_DEBUG, "Workspace: Destroying workspace '%s'", workspace->name); 271 sway_log(L_DEBUG, "%s: '%s'", __func__, workspace->name);
257 swayc_t *parent = workspace->parent; 272 swayc_t *parent = workspace->parent;
258 free_swayc(workspace); 273 free_swayc(workspace);
259 return parent; 274 return parent;
@@ -262,6 +277,9 @@ swayc_t *destroy_workspace(swayc_t *workspace) {
262} 277}
263 278
264swayc_t *destroy_container(swayc_t *container) { 279swayc_t *destroy_container(swayc_t *container) {
280 if (!ASSERT_NONNULL(container)) {
281 return NULL;
282 }
265 while (container->children->length == 0 && container->type == C_CONTAINER) { 283 while (container->children->length == 0 && container->type == C_CONTAINER) {
266 sway_log(L_DEBUG, "Container: Destroying container '%p'", container); 284 sway_log(L_DEBUG, "Container: Destroying container '%p'", container);
267 swayc_t *parent = container->parent; 285 swayc_t *parent = container->parent;
@@ -272,8 +290,7 @@ swayc_t *destroy_container(swayc_t *container) {
272} 290}
273 291
274swayc_t *destroy_view(swayc_t *view) { 292swayc_t *destroy_view(swayc_t *view) {
275 if (view == NULL) { 293 if (!ASSERT_NONNULL(view)) {
276 sway_log(L_DEBUG, "Warning: NULL passed into destroy_view");
277 return NULL; 294 return NULL;
278 } 295 }
279 sway_log(L_DEBUG, "Destroying view '%p'", view); 296 sway_log(L_DEBUG, "Destroying view '%p'", view);
@@ -287,6 +304,34 @@ swayc_t *destroy_view(swayc_t *view) {
287 return parent; 304 return parent;
288} 305}
289 306
307// Container lookup
308
309swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) {
310 if (!ASSERT_NONNULL(container)) {
311 return NULL;
312 }
313 if (!sway_assert(type < C_TYPES && type >= C_ROOT, "%s: invalid type", __func__)) {
314 return NULL;
315 }
316 do {
317 container = container->parent;
318 } while(container && container->type != type);
319 return container;
320}
321
322swayc_t *swayc_parent_by_layout(swayc_t *container, enum swayc_layouts layout) {
323 if (!ASSERT_NONNULL(container)) {
324 return NULL;
325 }
326 if (!sway_assert(layout < L_LAYOUTS && layout >= L_NONE, "%s: invalid layout", __func__)) {
327 return NULL;
328 }
329 do {
330 container = container->parent;
331 } while (container && container->layout != layout);
332 return container;
333}
334
290swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data) { 335swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data) {
291 if (!container->children) { 336 if (!container->children) {
292 return NULL; 337 return NULL;
@@ -316,25 +361,27 @@ swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *da
316} 361}
317 362
318void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) { 363void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) {
319 if (!container || !container->children || !container->children->length) { 364 if (container && container->children && container->children->length) {
320 return; 365 int i;
321 } 366 for (i = 0; i < container->children->length; ++i) {
322 int i; 367 swayc_t *child = container->children->items[i];
323 for (i = 0; i < container->children->length; ++i) {
324 swayc_t *child = container->children->items[i];
325 f(child, data);
326 container_map(child, f, data);
327 }
328 if (container->type == C_WORKSPACE) {
329 for (i = 0; i < container->floating->length; ++i) {
330 swayc_t *child = container->floating->items[i];
331 f(child, data); 368 f(child, data);
332 container_map(child, f, data); 369 container_map(child, f, data);
333 } 370 }
371 if (container->type == C_WORKSPACE) {
372 for (i = 0; i < container->floating->length; ++i) {
373 swayc_t *child = container->floating->items[i];
374 f(child, data);
375 container_map(child, f, data);
376 }
377 }
334 } 378 }
335} 379}
336 380
337void set_view_visibility(swayc_t *view, void *data) { 381void set_view_visibility(swayc_t *view, void *data) {
382 if (!ASSERT_NONNULL(view)) {
383 return;
384 }
338 uint32_t *p = data; 385 uint32_t *p = data;
339 if (view->type == C_VIEW) { 386 if (view->type == C_VIEW) {
340 wlc_view_set_mask(view->handle, *p); 387 wlc_view_set_mask(view->handle, *p);
@@ -348,6 +395,9 @@ void set_view_visibility(swayc_t *view, void *data) {
348} 395}
349 396
350void reset_gaps(swayc_t *view, void *data) { 397void reset_gaps(swayc_t *view, void *data) {
398 if (!ASSERT_NONNULL(view)) {
399 return;
400 }
351 if (view->type == C_OUTPUT) { 401 if (view->type == C_OUTPUT) {
352 view->gaps = config->gaps_outer; 402 view->gaps = config->gaps_outer;
353 } 403 }
diff --git a/sway/handlers.c b/sway/handlers.c
index 5993223d..79628fe5 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -20,10 +20,7 @@ static struct wlc_origin mouse_origin;
20static bool pointer_test(swayc_t *view, void *_origin) { 20static bool pointer_test(swayc_t *view, void *_origin) {
21 const struct wlc_origin *origin = _origin; 21 const struct wlc_origin *origin = _origin;
22 // Determine the output that the view is under 22 // Determine the output that the view is under
23 swayc_t *parent = view; 23 swayc_t *parent = swayc_parent_by_type(view, C_OUTPUT);
24 while (parent->type != C_OUTPUT) {
25 parent = parent->parent;
26 }
27 if (origin->x >= view->x && origin->y >= view->y 24 if (origin->x >= view->x && origin->y >= view->y
28 && origin->x < view->x + view->width && origin->y < view->y + view->height 25 && origin->x < view->x + view->width && origin->y < view->y + view->height
29 && view->visible && parent == root_container.focused) { 26 && view->visible && parent == root_container.focused) {
@@ -191,10 +188,7 @@ static bool handle_view_created(wlc_handle handle) {
191 188
192 if (newview) { 189 if (newview) {
193 set_focused_container(newview); 190 set_focused_container(newview);
194 swayc_t *output = newview->parent; 191 swayc_t *output = swayc_parent_by_type(newview, C_OUTPUT);
195 while (output && output->type != C_OUTPUT) {
196 output = output->parent;
197 }
198 arrange_windows(output, -1, -1); 192 arrange_windows(output, -1, -1);
199 } 193 }
200 return true; 194 return true;
@@ -262,10 +256,7 @@ static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit s
262 arrange_windows(c->parent, -1, -1); 256 arrange_windows(c->parent, -1, -1);
263 // Set it as focused window for that workspace if its going fullscreen 257 // Set it as focused window for that workspace if its going fullscreen
264 if (toggle) { 258 if (toggle) {
265 swayc_t *ws = c; 259 swayc_t *ws = swayc_parent_by_type(c, C_WORKSPACE);
266 while (ws->type != C_WORKSPACE) {
267 ws = ws->parent;
268 }
269 // Set ws focus to c 260 // Set ws focus to c
270 set_focused_container_for(ws, c); 261 set_focused_container_for(ws, c);
271 } 262 }
diff --git a/sway/layout.c b/sway/layout.c
index 78b3dd27..8c011fdb 100644
--- a/sway/layout.c
+++ b/sway/layout.c
@@ -161,10 +161,7 @@ void arrange_windows(swayc_t *container, int width, int height) {
161 } 161 }
162 }; 162 };
163 if (wlc_view_get_state(container->handle) & WLC_BIT_FULLSCREEN) { 163 if (wlc_view_get_state(container->handle) & WLC_BIT_FULLSCREEN) {
164 swayc_t *parent = container; 164 swayc_t *parent = swayc_parent_by_type(container, C_OUTPUT);
165 while (parent->type != C_OUTPUT) {
166 parent = parent->parent;
167 }
168 geometry.origin.x = 0; 165 geometry.origin.x = 0;
169 geometry.origin.y = 0; 166 geometry.origin.y = 0;
170 geometry.size.w = parent->width; 167 geometry.size.w = parent->width;
@@ -263,10 +260,7 @@ void arrange_windows(swayc_t *container, int width, int height) {
263 } 260 }
264 }; 261 };
265 if (wlc_view_get_state(view->handle) & WLC_BIT_FULLSCREEN) { 262 if (wlc_view_get_state(view->handle) & WLC_BIT_FULLSCREEN) {
266 swayc_t *parent = view; 263 swayc_t *parent = swayc_parent_by_type(view, C_OUTPUT);
267 while (parent->type != C_OUTPUT) {
268 parent = parent->parent;
269 }
270 geometry.origin.x = 0; 264 geometry.origin.x = 0;
271 geometry.origin.y = 0; 265 geometry.origin.y = 0;
272 geometry.size.w = parent->width; 266 geometry.size.w = parent->width;
diff --git a/sway/workspace.c b/sway/workspace.c
index 0f44d3b0..d436da8e 100644
--- a/sway/workspace.c
+++ b/sway/workspace.c
@@ -75,9 +75,7 @@ char *workspace_next_name(void) {
75 75
76swayc_t *workspace_create(const char* name) { 76swayc_t *workspace_create(const char* name) {
77 swayc_t *parent = get_focused_container(&root_container); 77 swayc_t *parent = get_focused_container(&root_container);
78 while (parent->type != C_OUTPUT) { 78 parent = swayc_parent_by_type(parent, C_OUTPUT);
79 parent = parent->parent;
80 }
81 return new_workspace(parent, name); 79 return new_workspace(parent, name);
82} 80}
83 81