diff options
-rw-r--r-- | include/input_state.h | 3 | ||||
-rw-r--r-- | include/layout.h | 2 | ||||
-rw-r--r-- | sway/handlers.c | 109 | ||||
-rw-r--r-- | sway/input_state.c | 3 | ||||
-rw-r--r-- | sway/layout.c | 6 | ||||
-rw-r--r-- | sway/type | 113 |
6 files changed, 221 insertions, 15 deletions
diff --git a/include/input_state.h b/include/input_state.h index 782b4b19..711ad633 100644 --- a/include/input_state.h +++ b/include/input_state.h | |||
@@ -34,6 +34,9 @@ extern struct pointer_state { | |||
34 | bool drag; | 34 | bool drag; |
35 | bool resize; | 35 | bool resize; |
36 | } floating; | 36 | } floating; |
37 | struct pointer_tiling { | ||
38 | bool resize; | ||
39 | } tiling; | ||
37 | struct pointer_lock { | 40 | struct pointer_lock { |
38 | bool left; | 41 | bool left; |
39 | bool right; | 42 | bool right; |
diff --git a/include/layout.h b/include/layout.h index 566e3246..20044b95 100644 --- a/include/layout.h +++ b/include/layout.h | |||
@@ -18,7 +18,7 @@ swayc_t *replace_child(swayc_t *child, swayc_t *new_child); | |||
18 | swayc_t *remove_child(swayc_t *child); | 18 | swayc_t *remove_child(swayc_t *child); |
19 | 19 | ||
20 | // Layout | 20 | // Layout |
21 | void arrange_windows(swayc_t *container, int width, int height); | 21 | void arrange_windows(swayc_t *container, double width, double height); |
22 | 22 | ||
23 | // Focus | 23 | // Focus |
24 | void unfocus_all(swayc_t *container); | 24 | void unfocus_all(swayc_t *container); |
diff --git a/sway/handlers.c b/sway/handlers.c index 5993223d..a71328e3 100644 --- a/sway/handlers.c +++ b/sway/handlers.c | |||
@@ -1,6 +1,7 @@ | |||
1 | #include <xkbcommon/xkbcommon.h> | 1 | #include <xkbcommon/xkbcommon.h> |
2 | #include <stdlib.h> | 2 | #include <stdlib.h> |
3 | #include <stdbool.h> | 3 | #include <stdbool.h> |
4 | #include <math.h> | ||
4 | #include <wlc/wlc.h> | 5 | #include <wlc/wlc.h> |
5 | #include <ctype.h> | 6 | #include <ctype.h> |
6 | 7 | ||
@@ -351,7 +352,7 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct | |||
351 | return false; | 352 | return false; |
352 | } | 353 | } |
353 | // Do checks to determine if proper keys are being held | 354 | // Do checks to determine if proper keys are being held |
354 | swayc_t *view = get_focused_view(active_workspace); | 355 | swayc_t *view = container_under_pointer(); |
355 | uint32_t edge = 0; | 356 | uint32_t edge = 0; |
356 | if (pointer_state.floating.drag && view) { | 357 | if (pointer_state.floating.drag && view) { |
357 | if (view->is_floating) { | 358 | if (view->is_floating) { |
@@ -426,6 +427,91 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct | |||
426 | } | 427 | } |
427 | } | 428 | } |
428 | } | 429 | } |
430 | } | ||
431 | } else if (pointer_state.tiling.resize && view) { | ||
432 | if (!view->is_floating) { | ||
433 | // Handle layout resizes -- Find the biggest parent container then apply resizes to that | ||
434 | // and its bordering siblings | ||
435 | swayc_t *parent = view; | ||
436 | double dx = mouse_origin.x - prev_pos.x; | ||
437 | double dy = mouse_origin.y - prev_pos.y; | ||
438 | if (pointer_state.lock.top) { | ||
439 | while (parent->type != C_WORKSPACE) { | ||
440 | // TODO: Absolute value is a bad hack here to compensate for rounding. Find a better | ||
441 | // way of doing this. | ||
442 | if (fabs(parent->parent->y + parent->parent->height - (view->y + view->height)) <= 1) { | ||
443 | parent = parent->parent; | ||
444 | } else { | ||
445 | break; | ||
446 | } | ||
447 | } | ||
448 | if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) { | ||
449 | sway_log(L_DEBUG, "Top is locked, found biggest valid parent at: %p", parent); | ||
450 | swayc_t *sibling = get_swayc_in_direction(parent, MOVE_DOWN); | ||
451 | if (sibling) { | ||
452 | sway_log(L_DEBUG, "Found sibling at: %p", sibling); | ||
453 | recursive_resize(parent, dy, WLC_RESIZE_EDGE_BOTTOM); | ||
454 | recursive_resize(sibling, -1 * dy, WLC_RESIZE_EDGE_TOP); | ||
455 | } | ||
456 | } | ||
457 | } else { | ||
458 | while (parent->type != C_WORKSPACE) { | ||
459 | if (fabs(parent->parent->y - view->y) <= 1) { | ||
460 | parent = parent->parent; | ||
461 | } else { | ||
462 | break; | ||
463 | } | ||
464 | } | ||
465 | if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) { | ||
466 | sway_log(L_DEBUG, "Bot is locked, found biggest valid parent at: %p", parent); | ||
467 | swayc_t *sibling = get_swayc_in_direction(parent, MOVE_UP); | ||
468 | if (sibling) { | ||
469 | sway_log(L_DEBUG, "Found sibling at: %p", sibling); | ||
470 | recursive_resize(parent, -1 * dy, WLC_RESIZE_EDGE_TOP); | ||
471 | recursive_resize(sibling, dy, WLC_RESIZE_EDGE_BOTTOM); | ||
472 | } | ||
473 | } | ||
474 | } | ||
475 | |||
476 | parent = view; | ||
477 | if (pointer_state.lock.left) { | ||
478 | while (parent->type != C_WORKSPACE) { | ||
479 | if (fabs(parent->parent->x + parent->parent->width - (view->x + view->width)) <= 1) { | ||
480 | parent = parent->parent; | ||
481 | } else { | ||
482 | sway_log(L_DEBUG, "view: %f vs parent: %f", view->x + view->width, parent->parent->x + parent->parent->width); | ||
483 | break; | ||
484 | } | ||
485 | } | ||
486 | sway_log(L_DEBUG, "Left is locked, found biggest valid parent at: %p", parent); | ||
487 | if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) { | ||
488 | sway_log(L_DEBUG, "Left is locked, found biggest valid parent at: %p", parent); | ||
489 | swayc_t *sibling = get_swayc_in_direction(parent, MOVE_RIGHT); | ||
490 | if (sibling) { | ||
491 | sway_log(L_DEBUG, "Found sibling at: %p", sibling); | ||
492 | recursive_resize(parent, dx, WLC_RESIZE_EDGE_RIGHT); | ||
493 | recursive_resize(sibling, -1 * dx, WLC_RESIZE_EDGE_LEFT); | ||
494 | } | ||
495 | } | ||
496 | } else { | ||
497 | while (parent->type != C_WORKSPACE) { | ||
498 | if (fabs(parent->parent->x - view->x) <= 1 && parent->parent) { | ||
499 | parent = parent->parent; | ||
500 | } else { | ||
501 | break; | ||
502 | } | ||
503 | } | ||
504 | if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) { | ||
505 | sway_log(L_DEBUG, "Right is locked, found biggest valid parent at: %p", parent); | ||
506 | swayc_t *sibling = get_swayc_in_direction(parent, MOVE_LEFT); | ||
507 | if (sibling) { | ||
508 | sway_log(L_DEBUG, "Found sibling at: %p", sibling); | ||
509 | recursive_resize(parent, -1 * dx, WLC_RESIZE_EDGE_LEFT); | ||
510 | recursive_resize(sibling, dx, WLC_RESIZE_EDGE_RIGHT); | ||
511 | } | ||
512 | } | ||
513 | } | ||
514 | arrange_windows(active_workspace, -1, -1); | ||
429 | } | 515 | } |
430 | } | 516 | } |
431 | if (config->focus_follows_mouse && prev_handle != handle) { | 517 | if (config->focus_follows_mouse && prev_handle != handle) { |
@@ -472,7 +558,16 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w | |||
472 | pointer_state.r_held = true; | 558 | pointer_state.r_held = true; |
473 | } | 559 | } |
474 | swayc_t *pointer = container_under_pointer(); | 560 | swayc_t *pointer = container_under_pointer(); |
475 | set_focused_container(pointer); | 561 | if (pointer) { |
562 | set_focused_container(pointer); | ||
563 | int midway_x = pointer->x + pointer->width/2; | ||
564 | int midway_y = pointer->y + pointer->height/2; | ||
565 | pointer_state.lock.bottom = origin->y < midway_y; | ||
566 | pointer_state.lock.top = !pointer_state.lock.bottom; | ||
567 | pointer_state.lock.right = origin->x < midway_x; | ||
568 | pointer_state.lock.left = !pointer_state.lock.right; | ||
569 | } | ||
570 | |||
476 | if (pointer->is_floating) { | 571 | if (pointer->is_floating) { |
477 | int i; | 572 | int i; |
478 | for (i = 0; i < pointer->parent->floating->length; i++) { | 573 | for (i = 0; i < pointer->parent->floating->length; i++) { |
@@ -484,19 +579,14 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w | |||
484 | } | 579 | } |
485 | arrange_windows(pointer->parent, -1, -1); | 580 | arrange_windows(pointer->parent, -1, -1); |
486 | if (modifiers->mods & config->floating_mod) { | 581 | if (modifiers->mods & config->floating_mod) { |
487 | int midway_x = pointer->x + pointer->width/2; | ||
488 | int midway_y = pointer->y + pointer->height/2; | ||
489 | |||
490 | pointer_state.floating.drag = pointer_state.l_held; | 582 | pointer_state.floating.drag = pointer_state.l_held; |
491 | pointer_state.floating.resize = pointer_state.r_held; | 583 | pointer_state.floating.resize = pointer_state.r_held; |
492 | pointer_state.lock.bottom = origin->y < midway_y; | ||
493 | pointer_state.lock.top = !pointer_state.lock.bottom; | ||
494 | pointer_state.lock.right = origin->x < midway_x; | ||
495 | pointer_state.lock.left = !pointer_state.lock.right; | ||
496 | start_floating(pointer); | 584 | start_floating(pointer); |
497 | } | 585 | } |
498 | // Dont want pointer sent to window while dragging or resizing | 586 | // Dont want pointer sent to window while dragging or resizing |
499 | return (pointer_state.floating.drag || pointer_state.floating.resize); | 587 | return (pointer_state.floating.drag || pointer_state.floating.resize); |
588 | } else { | ||
589 | pointer_state.tiling.resize = pointer_state.r_held; | ||
500 | } | 590 | } |
501 | return (pointer && pointer != focused); | 591 | return (pointer && pointer != focused); |
502 | } else { | 592 | } else { |
@@ -508,6 +598,7 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w | |||
508 | if (button == M_RIGHT_CLICK) { | 598 | if (button == M_RIGHT_CLICK) { |
509 | pointer_state.r_held = false; | 599 | pointer_state.r_held = false; |
510 | pointer_state.floating.resize = false; | 600 | pointer_state.floating.resize = false; |
601 | pointer_state.tiling.resize = false; | ||
511 | pointer_state.lock = (struct pointer_lock){false ,false ,false ,false}; | 602 | pointer_state.lock = (struct pointer_lock){false ,false ,false ,false}; |
512 | } | 603 | } |
513 | } | 604 | } |
diff --git a/sway/input_state.c b/sway/input_state.c index a7f88d4a..e592cfc1 100644 --- a/sway/input_state.c +++ b/sway/input_state.c | |||
@@ -41,7 +41,7 @@ void release_key(keycode key) { | |||
41 | } | 41 | } |
42 | } | 42 | } |
43 | 43 | ||
44 | struct pointer_state pointer_state = {0, 0, {0, 0}, {0, 0, 0, 0}}; | 44 | struct pointer_state pointer_state = {0, 0, {0, 0}, {0}, {0, 0, 0, 0}}; |
45 | 45 | ||
46 | static struct wlc_geometry saved_floating; | 46 | static struct wlc_geometry saved_floating; |
47 | 47 | ||
@@ -65,4 +65,3 @@ void reset_floating(swayc_t *view) { | |||
65 | pointer_state.floating = (struct pointer_floating){0,0}; | 65 | pointer_state.floating = (struct pointer_floating){0,0}; |
66 | pointer_state.lock = (struct pointer_lock){0,0,0,0}; | 66 | pointer_state.lock = (struct pointer_lock){0,0,0,0}; |
67 | } | 67 | } |
68 | |||
diff --git a/sway/layout.c b/sway/layout.c index 50e7b592..12b27987 100644 --- a/sway/layout.c +++ b/sway/layout.c | |||
@@ -109,7 +109,7 @@ swayc_t *remove_child(swayc_t *child) { | |||
109 | } | 109 | } |
110 | 110 | ||
111 | 111 | ||
112 | void arrange_windows(swayc_t *container, int width, int height) { | 112 | void arrange_windows(swayc_t *container, double width, double height) { |
113 | int i; | 113 | int i; |
114 | if (width == -1 || height == -1) { | 114 | if (width == -1 || height == -1) { |
115 | sway_log(L_DEBUG, "Arranging layout for %p", container); | 115 | sway_log(L_DEBUG, "Arranging layout for %p", container); |
@@ -209,7 +209,7 @@ void arrange_windows(swayc_t *container, int width, int height) { | |||
209 | sway_log(L_DEBUG, "Arranging %p horizontally", container); | 209 | sway_log(L_DEBUG, "Arranging %p horizontally", container); |
210 | for (i = 0; i < container->children->length; ++i) { | 210 | for (i = 0; i < container->children->length; ++i) { |
211 | swayc_t *child = container->children->items[i]; | 211 | swayc_t *child = container->children->items[i]; |
212 | sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %d by %f)", child, child->type, width, scale); | 212 | sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %f by %f)", child, child->type, width, scale); |
213 | child->x = x + container->x; | 213 | child->x = x + container->x; |
214 | child->y = y + container->y; | 214 | child->y = y + container->y; |
215 | arrange_windows(child, child->width * scale, height); | 215 | arrange_windows(child, child->width * scale, height); |
@@ -236,7 +236,7 @@ void arrange_windows(swayc_t *container, int width, int height) { | |||
236 | sway_log(L_DEBUG, "Arranging %p vertically", container); | 236 | sway_log(L_DEBUG, "Arranging %p vertically", container); |
237 | for (i = 0; i < container->children->length; ++i) { | 237 | for (i = 0; i < container->children->length; ++i) { |
238 | swayc_t *child = container->children->items[i]; | 238 | swayc_t *child = container->children->items[i]; |
239 | sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %d by %f)", child, child->type, height, scale); | 239 | sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %f by %f)", child, child->type, height, scale); |
240 | child->x = x + container->x; | 240 | child->x = x + container->x; |
241 | child->y = y + container->y; | 241 | child->y = y + container->y; |
242 | arrange_windows(child, width, child->height * scale); | 242 | arrange_windows(child, width, child->height * scale); |
diff --git a/sway/type b/sway/type new file mode 100644 index 00000000..c7bebe5e --- /dev/null +++ b/sway/type | |||
@@ -0,0 +1,113 @@ | |||
1 | workspace.c:78:9: while (parent->type != C_OUTPUT) { | ||
2 | workspace.c:79:12: parent = parent->parent; | ||
3 | |||
4 | focus.c:16:6: if (parent->focused != c) { | ||
5 | focus.c:30:8: if (parent->focused) { | ||
6 | focus.c:31:19: swayc_t *ws = parent->focused; | ||
7 | focus.c:38:25: wlc_output_set_mask(parent->handle, 2); | ||
8 | focus.c:39:8: c->parent->focused = c; | ||
9 | focus.c:53:5: c->parent->focused = c; | ||
10 | focus.c:71:20: while (parent && !parent->is_focused) { | ||
11 | focus.c:72:12: parent = parent->focused; | ||
12 | focus.c:143:13: if (find->parent->focused != find) { | ||
13 | focus.c:167:19: while (parent && parent->type != C_VIEW) { | ||
14 | focus.c:168:7: if (parent->type == C_WORKSPACE && parent->focused == NULL) { | ||
15 | focus.c:171:12: parent = parent->focused; | ||
16 | |||
17 | handlers.c:24:9: while (parent->type != C_OUTPUT) { | ||
18 | handlers.c:25:12: parent = parent->parent; | ||
19 | handlers.c:436:18: while (parent->parent && parent->y + parent->height == view->y + view->height && parent->type != L_WORKSPACE) { | ||
20 | handlers.c:437:30: parent = parent->parent; | ||
21 | handlers.c:440:50: if (parent == &root_container || parent->children->length == 1) { | ||
22 | handlers.c:444:18: while (parent->parent && parent->y == view->y) { | ||
23 | handlers.c:445:30: parent = parent->parent; | ||
24 | handlers.c:448:50: if (parent == &root_container || parent->children->length == 1) { | ||
25 | handlers.c:454:18: while (parent->parent && parent->x + parent->width == view->x + view->width) { | ||
26 | handlers.c:455:30: parent = parent->parent; | ||
27 | handlers.c:458:50: if (parent == &root_container || parent->children->length == 1) { | ||
28 | handlers.c:462:18: while (parent->parent && parent->x + parent->width == view->x) { | ||
29 | handlers.c:463:30: parent = parent->parent; | ||
30 | handlers.c:466:50: if (parent == &root_container || parent->children->length == 1) { | ||
31 | handlers.c:528:29: for (i = 0; i < pointer->parent->floating->length; i++) { | ||
32 | handlers.c:529:18: if (pointer->parent->floating->items[i] == pointer) { | ||
33 | handlers.c:530:24: list_del(pointer->parent->floating, i); | ||
34 | handlers.c:531:24: list_add(pointer->parent->floating, pointer); | ||
35 | |||
36 | container.c:284:6: if (parent->type == C_CONTAINER) { | ||
37 | |||
38 | layout.c:23:18: for (i = 0; i < parent->children->length; ++i) { | ||
39 | layout.c:24:7: if (parent->children->items[i] == child) { | ||
40 | layout.c:33:40: child->width, child->height, parent, parent->type, parent->width, parent->height); | ||
41 | layout.c:34:11: list_add(parent->children, child); | ||
42 | layout.c:37:6: if (parent->children->length == 1) { | ||
43 | layout.c:56:11: if (i == parent->children->length) { | ||
44 | layout.c:59:14: list_insert(parent->children, i+1, child); | ||
45 | layout.c:70:2: parent->children->items[i] = new_child; | ||
46 | layout.c:73:13: if (child->parent->focused == child) { | ||
47 | layout.c:85:19: for (i = 0; i < parent->floating->length; ++i) { | ||
48 | layout.c:86:8: if (parent->floating->items[i] == child) { | ||
49 | layout.c:87:14: list_del(parent->floating, i); | ||
50 | layout.c:93:19: for (i = 0; i < parent->children->length; ++i) { | ||
51 | layout.c:94:8: if (parent->children->items[i] == child) { | ||
52 | layout.c:95:14: list_del(parent->children, i); | ||
53 | layout.c:101:6: if (parent->focused == child) { | ||
54 | layout.c:102:7: if (parent->children->length > 0) { | ||
55 | layout.c:103:38: set_focused_container_for(parent, parent->children->items[i?i-1:0]); | ||
56 | layout.c:105:4: parent->focused = NULL; | ||
57 | layout.c:165:12: while (parent->type != C_OUTPUT) { | ||
58 | layout.c:166:15: parent = parent->parent; | ||
59 | layout.c:170:23: geometry.size.w = parent->width; | ||
60 | layout.c:171:23: geometry.size.h = parent->height; | ||
61 | layout.c:267:13: while (parent->type != C_OUTPUT) { | ||
62 | layout.c:268:16: parent = parent->parent; | ||
63 | layout.c:272:24: geometry.size.w = parent->width; | ||
64 | layout.c:273:24: geometry.size.h = parent->height; | ||
65 | layout.c:294:6: if (parent->children == NULL) { | ||
66 | layout.c:300:6: if (parent->type == C_WORKSPACE) { | ||
67 | layout.c:301:19: for (i = 0; i < parent->floating->length; ++i) { | ||
68 | layout.c:302:21: swayc_t *child = parent->floating->items[i]; | ||
69 | layout.c:309:18: for (i = 0; i < parent->children->length; ++i) { | ||
70 | layout.c:310:20: swayc_t *child = parent->children->items[i]; | ||
71 | layout.c:327:7: if (parent->type == C_OUTPUT) { | ||
72 | layout.c:338:8: if (parent->layout == L_HORIZ || parent->type == C_ROOT) { | ||
73 | layout.c:343:8: if (parent->layout == L_VERT) { | ||
74 | layout.c:350:20: for (i = 0; i < parent->children->length; ++i) { | ||
75 | layout.c:351:22: swayc_t *child = parent->children->items[i]; | ||
76 | layout.c:357:34: if (desired < 0 || desired >= parent->children->length) { | ||
77 | layout.c:360:12: return parent->children->items[desired]; | ||
78 | layout.c:365:13: parent = parent->parent; | ||
79 | |||
80 | commands.c:394:9: while (parent->type == C_VIEW) { | ||
81 | commands.c:395:12: parent = parent->parent; | ||
82 | commands.c:399:3: parent->layout = L_HORIZ; | ||
83 | commands.c:401:3: parent->layout = L_VERT; | ||
84 | commands.c:403:7: if (parent->layout == L_VERT) { | ||
85 | commands.c:404:4: parent->layout = L_HORIZ; | ||
86 | commands.c:406:4: parent->layout = L_VERT; | ||
87 | commands.c:409:26: arrange_windows(parent, parent->width, parent->height); | ||
88 | commands.c:454:10: while (parent->parent) { | ||
89 | commands.c:455:8: if (parent->parent->layout == L_HORIZ) { | ||
90 | commands.c:456:21: for (i = 0; i < parent->parent->children->length; i++) { | ||
91 | commands.c:457:16: sibling = parent->parent->children->items[i]; | ||
92 | commands.c:459:24: if (sibling->x < parent->x) { | ||
93 | commands.c:461:31: } else if (sibling->x > parent->x) { | ||
94 | commands.c:470:13: parent = parent->parent; | ||
95 | commands.c:475:87: sway_log(L_DEBUG, "Found the proper parent: %p. It has %d l conts, and %d r conts", parent->parent, lnumber, rnumber); | ||
96 | commands.c:477:19: for (i = 0; i < parent->parent->children->length; i++) { | ||
97 | commands.c:478:14: sibling = parent->parent->children->items[i]; | ||
98 | commands.c:480:22: if (sibling->x < parent->x) { | ||
99 | commands.c:488:29: } else if (sibling->x > parent->x) { | ||
100 | commands.c:517:10: while (parent->parent) { | ||
101 | commands.c:518:8: if (parent->parent->layout == L_VERT) { | ||
102 | commands.c:519:21: for (i = 0; i < parent->parent->children->length; i++) { | ||
103 | commands.c:520:16: sibling = parent->parent->children->items[i]; | ||
104 | commands.c:522:24: if (sibling->y < parent->y) { | ||
105 | commands.c:524:31: } else if (sibling->y > parent->y) { | ||
106 | commands.c:533:13: parent = parent->parent; | ||
107 | commands.c:538:87: sway_log(L_DEBUG, "Found the proper parent: %p. It has %d b conts, and %d t conts", parent->parent, bnumber, tnumber); | ||
108 | commands.c:540:19: for (i = 0; i < parent->parent->children->length; i++) { | ||
109 | commands.c:541:14: sibling = parent->parent->children->items[i]; | ||
110 | commands.c:543:22: if (sibling->y < parent->y) { | ||
111 | commands.c:551:29: } else if (sibling->x > parent->x) { | ||
112 | commands.c:603:54: } else if (focused->type != C_WORKSPACE && focused->parent->children->length == 1) { | ||
113 | commands.c:606:12: focused->parent->layout = layout; | ||