From 7706d83160267be61accb1b6f7bdc2f43299cae7 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sat, 31 Mar 2018 00:44:17 -0400 Subject: basic split containers --- sway/tree/container.c | 7 ++-- sway/tree/layout.c | 99 +++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 89 insertions(+), 17 deletions(-) (limited to 'sway/tree') diff --git a/sway/tree/container.c b/sway/tree/container.c index 746dbf1f..7b88cccb 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -38,7 +38,7 @@ static void notify_new_container(struct sway_container *container) { ipc_event_window(container, "new"); } -static struct sway_container *container_create(enum sway_container_type type) { +struct sway_container *container_create(enum sway_container_type type) { // next id starts at 1 because 0 is assigned to root_container in layout.c static size_t next_id = 1; struct sway_container *c = calloc(1, sizeof(struct sway_container)); @@ -66,13 +66,14 @@ struct sway_container *container_destroy(struct sway_container *cont) { wl_signal_emit(&cont->events.destroy, cont); struct sway_container *parent = cont->parent; - if (cont->children) { + if (cont->children != NULL) { // remove children until there are no more, container_destroy calls // container_remove_child, which removes child from this container - while (cont->children->length) { + while (cont->children->length != 0) { container_destroy(cont->children->items[0]); } list_free(cont->children); + cont->children = NULL; } if (cont->marks) { list_foreach(cont->marks, free); diff --git a/sway/tree/layout.c b/sway/tree/layout.c index ce0682dc..62df19e9 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -1,4 +1,5 @@ #define _POSIX_C_SOURCE 200809L +#include #include #include #include @@ -100,6 +101,8 @@ void container_add_child(struct sway_container *parent, parent, parent->type, parent->width, parent->height); list_add(parent->children, child); child->parent = parent; + // TODO: set focus for this container? + sway_input_manager_set_focus(input_manager, child); } struct sway_container *container_reap_empty(struct sway_container *container) { @@ -135,7 +138,7 @@ struct sway_container *container_remove_child(struct sway_container *child) { } } child->parent = NULL; - return container_reap_empty(parent); + return parent; } void container_move_to(struct sway_container* container, @@ -322,7 +325,12 @@ static void apply_horiz_layout(struct sway_container *container, wlr_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %f by %f)", child, child->type, width, scale); - view_set_position(child->sway_view, child_x, y); + if (child->type == C_VIEW) { + view_set_position(child->sway_view, child_x, y); + } else { + child->x = child_x; + child->y = y; + } if (i == end - 1) { double remaining_width = x + width - child_x; @@ -505,9 +513,9 @@ static struct sway_container *sway_output_from_wlr(struct wlr_output *output) { return NULL; } -static struct sway_container *get_swayc_in_direction_under( - struct sway_container *container, enum movement_direction dir, - struct sway_seat *seat, struct sway_container *limit) { +struct sway_container *container_get_in_direction( + struct sway_container *container, struct sway_seat *seat, + enum movement_direction dir) { if (dir == MOVE_CHILD) { return sway_seat_get_focus_inactive(seat, container); } @@ -559,7 +567,6 @@ static struct sway_container *get_swayc_in_direction_under( struct sway_container *wrap_candidate = NULL; while (true) { - // Test if we can even make a difference here bool can_move = false; int desired; int idx = index_child(container); @@ -589,7 +596,7 @@ static struct sway_container *get_swayc_in_direction_under( } if (next->children && next->children->length) { // TODO consider floating children as well - return sway_seat_get_focus_inactive(seat, next); + return sway_seat_get_focus_by_type(seat, next, C_VIEW); } else { return next; } @@ -619,21 +626,22 @@ static struct sway_container *get_swayc_in_direction_under( wrap_candidate = parent->children->items[0]; } if (config->force_focus_wrapping) { - return wrap_candidate; + return sway_seat_get_focus_by_type(seat, wrap_candidate, C_VIEW); } } } else { wlr_log(L_DEBUG, "cont %d-%p dir %i sibling %d: %p", idx, container, dir, desired, parent->children->items[desired]); - return parent->children->items[desired]; + return sway_seat_get_focus_by_type(seat, + parent->children->items[desired], C_VIEW); } } if (!can_move) { container = parent; parent = parent->parent; - if (!parent || container == limit) { + if (!parent) { // wrapping is the last chance return wrap_candidate; } @@ -641,8 +649,71 @@ static struct sway_container *get_swayc_in_direction_under( } } -struct sway_container *container_get_in_direction( - struct sway_container *container, struct sway_seat *seat, - enum movement_direction dir) { - return get_swayc_in_direction_under(container, dir, seat, NULL); +struct sway_container *container_replace_child(struct sway_container *child, + struct sway_container *new_child) { + struct sway_container *parent = child->parent; + if (parent == NULL) { + return NULL; + } + int i = index_child(child); + + // TODO floating + parent->children->items[i] = new_child; + new_child->parent = parent; + child->parent = NULL; + + // Set geometry for new child + new_child->x = child->x; + new_child->y = child->y; + new_child->width = child->width; + new_child->height = child->height; + + // reset geometry for child + child->width = 0; + child->height = 0; + + return parent; +} + +struct sway_container *container_split(struct sway_container *child, + enum sway_container_layout layout) { + // TODO floating: cannot split a floating container + if (!sway_assert(child, "child cannot be null")) { + return NULL; + } + struct sway_container *cont = container_create(C_CONTAINER); + + wlr_log(L_DEBUG, "creating container %p around %p", cont, child); + + cont->prev_layout = L_NONE; + cont->layout = layout; + cont->width = child->width; + cont->height = child->height; + cont->x = child->x; + cont->y = child->y; + + /* Container inherits all of workspaces children, layout and whatnot */ + if (child->type == C_WORKSPACE) { + struct sway_container *workspace = child; + // reorder focus + int i; + for (i = 0; i < workspace->children->length; ++i) { + ((struct sway_container *)workspace->children->items[i])->parent = + cont; + } + + // Swap children + list_t *tmp_list = workspace->children; + workspace->children = cont->children; + cont->children = tmp_list; + // add container to workspace chidren + container_add_child(workspace, cont); + // give them proper layouts + cont->layout = workspace->workspace_layout; + cont->prev_layout = workspace->prev_layout; + } else { // Or is built around container + container_replace_child(child, cont); + container_add_child(cont, child); + } + return cont; } -- cgit v1.2.3 From e7ecb001d70c71f799547d15cd45c235412af402 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sat, 31 Mar 2018 13:20:05 -0400 Subject: reap container parent on destroy --- sway/commands/kill.c | 1 - sway/tree/container.c | 7 ++++++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'sway/tree') diff --git a/sway/commands/kill.c b/sway/commands/kill.c index 80120832..e6036cb3 100644 --- a/sway/commands/kill.c +++ b/sway/commands/kill.c @@ -19,7 +19,6 @@ struct cmd_results *cmd_kill(int argc, char **argv) { break; case C_CONTAINER: con = container_destroy(con); - con = container_reap_empty(con); arrange_windows(con, -1, -1); break; case C_VIEW: diff --git a/sway/tree/container.c b/sway/tree/container.c index 7b88cccb..f972ac24 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -58,7 +58,7 @@ struct sway_container *container_create(enum sway_container_type type) { return c; } -struct sway_container *container_destroy(struct sway_container *cont) { +static struct sway_container *_container_destroy(struct sway_container *cont) { if (cont == NULL) { return NULL; } @@ -89,6 +89,11 @@ struct sway_container *container_destroy(struct sway_container *cont) { return parent; } +struct sway_container *container_destroy(struct sway_container *cont) { + cont = _container_destroy(cont); + return container_reap_empty(cont->parent); +} + struct sway_container *container_output_create( struct sway_output *sway_output) { struct wlr_box size; -- cgit v1.2.3 From 6f7b33e6919b2a8467ea1638ee56ac0232408793 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sat, 31 Mar 2018 15:22:10 -0400 Subject: handle container destroy in the seat --- include/sway/tree/container.h | 3 ++ sway/input/seat.c | 104 +++++++++++++++++++++++++++++------------- sway/tree/container.c | 13 ++++++ 3 files changed, 88 insertions(+), 32 deletions(-) (limited to 'sway/tree') diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 46f1c5ab..285f1011 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h @@ -150,4 +150,7 @@ void container_for_each_descendant_dfs(struct sway_container *container, bool container_has_anscestor(struct sway_container *descendant, struct sway_container *anscestor); +bool container_has_child(struct sway_container *con, + struct sway_container *child); + #endif diff --git a/sway/input/seat.c b/sway/input/seat.c index e0fd314a..e3d53cb6 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -27,6 +27,7 @@ static void seat_device_destroy(struct sway_seat_device *seat_device) { } void sway_seat_destroy(struct sway_seat *seat) { + // TODO destroy seat containers struct sway_seat_device *seat_device, *next; wl_list_for_each_safe(seat_device, next, &seat->devices, link) { seat_device_destroy(seat_device); @@ -36,30 +37,57 @@ void sway_seat_destroy(struct sway_seat *seat) { wlr_seat_destroy(seat->wlr_seat); } +static struct sway_seat_container *seat_container_from_container( + struct sway_seat *seat, struct sway_container *con); + +static void seat_container_destroy(struct sway_seat_container *seat_con) { + struct sway_container *con = seat_con->container; + struct sway_container *child = NULL; + + if (con->children != NULL) { + for (int i = 0; i < con->children->length; ++i) { + child = con->children->items[i]; + struct sway_seat_container *seat_child = + seat_container_from_container(seat_con->seat, child); + seat_container_destroy(seat_child); + } + } + + wl_list_remove(&seat_con->destroy.link); + wl_list_remove(&seat_con->link); + free(seat_con); +} + static void handle_seat_container_destroy(struct wl_listener *listener, void *data) { struct sway_seat_container *seat_con = wl_container_of(listener, seat_con, destroy); struct sway_seat *seat = seat_con->seat; struct sway_container *con = seat_con->container; + struct sway_container *parent = con->parent; + struct sway_container *focus = sway_seat_get_focus(seat); - bool is_focus = (sway_seat_get_focus(seat) == con); + // TODO handle workspace switch in the seat? + bool set_focus = + (focus == con || container_has_child(con, focus)) && + con->type != C_WORKSPACE; - wl_list_remove(&seat_con->link); + seat_container_destroy(seat_con); - if (is_focus) { - // pick next focus - sway_seat_set_focus(seat, NULL); - struct sway_container *next = sway_seat_get_focus_inactive(seat, con->parent); - if (next == NULL) { - next = con->parent; - } - sway_seat_set_focus(seat, next); - } + if (set_focus && con->type != C_WORKSPACE) { + struct sway_container *next_focus = NULL; + while (next_focus == NULL) { + next_focus = sway_seat_get_focus_by_type(seat, parent, C_VIEW); + parent = parent->parent; - wl_list_remove(&seat_con->destroy.link); + if (next_focus == NULL && parent->type == C_WORKSPACE) { + next_focus = parent; + break; + } + } - free(seat_con); + sway_seat_set_focus(seat, next_focus); + } } static struct sway_seat_container *seat_container_from_container( @@ -293,11 +321,37 @@ void sway_seat_configure_xcursor(struct sway_seat *seat) { seat->cursor->cursor->y); } +static void seat_send_focus(struct sway_seat *seat, + struct sway_container *con) { + if (con->type != C_VIEW) { + return; + } + struct sway_view *view = con->sway_view; + if (view->type == SWAY_XWAYLAND_VIEW) { + struct wlr_xwayland *xwayland = + seat->input->server->xwayland; + wlr_xwayland_set_seat(xwayland, seat->wlr_seat); + } + view_set_activated(view, true); + struct wlr_keyboard *keyboard = + wlr_seat_get_keyboard(seat->wlr_seat); + if (keyboard) { + wlr_seat_keyboard_notify_enter(seat->wlr_seat, + view->surface, keyboard->keycodes, + keyboard->num_keycodes, &keyboard->modifiers); + } else { + wlr_seat_keyboard_notify_enter( + seat->wlr_seat, view->surface, NULL, 0, NULL); + } + +} + void sway_seat_set_focus_warp(struct sway_seat *seat, struct sway_container *container, bool warp) { struct sway_container *last_focus = sway_seat_get_focus(seat); if (container && last_focus == container) { + seat_send_focus(seat, container); return; } @@ -312,23 +366,7 @@ void sway_seat_set_focus_warp(struct sway_seat *seat, wl_list_insert(&seat->focus_stack, &seat_con->link); if (container->type == C_VIEW) { - struct sway_view *view = container->sway_view; - view_set_activated(view, true); - if (view->type == SWAY_XWAYLAND_VIEW) { - struct wlr_xwayland *xwayland = - seat->input->server->xwayland; - wlr_xwayland_set_seat(xwayland, seat->wlr_seat); - } - struct wlr_keyboard *keyboard = - wlr_seat_get_keyboard(seat->wlr_seat); - if (keyboard) { - wlr_seat_keyboard_notify_enter(seat->wlr_seat, - view->surface, keyboard->keycodes, - keyboard->num_keycodes, &keyboard->modifiers); - } else { - wlr_seat_keyboard_notify_enter( - seat->wlr_seat, view->surface, NULL, 0, NULL); - } + seat_send_focus(seat, container); } } @@ -378,7 +416,8 @@ void sway_seat_set_focus(struct sway_seat *seat, sway_seat_set_focus_warp(seat, container, true); } -struct sway_container *sway_seat_get_focus_inactive(struct sway_seat *seat, struct sway_container *container) { +struct sway_container *sway_seat_get_focus_inactive(struct sway_seat *seat, + struct sway_container *container) { return sway_seat_get_focus_by_type(seat, container, C_TYPES); } @@ -401,7 +440,8 @@ struct sway_container *sway_seat_get_focus_by_type(struct sway_seat *seat, } while (parent) { - if (parent == container && (type == C_TYPES || current->container->type == type)) { + if (parent == container && (type == C_TYPES || + current->container->type == type)) { return current->container; } parent = parent->parent; diff --git a/sway/tree/container.c b/sway/tree/container.c index f972ac24..e2fe9e7c 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -401,3 +401,16 @@ bool container_has_anscestor(struct sway_container *descendant, } return false; } + +bool find_child_func(struct sway_container *con, void *data) { + struct sway_container *child = data; + return con == child; +} + +bool container_has_child(struct sway_container *con, + struct sway_container *child) { + if (child->type == C_VIEW || child->children->length == 0) { + return false; + } + return container_find(con, find_child_func, child); +} -- cgit v1.2.3 From eda425fdabb4050eb2ecc8741793d83e3a7bf154 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sat, 31 Mar 2018 18:52:02 -0400 Subject: fix some segfaults --- sway/input/seat.c | 7 +++++-- sway/tree/container.c | 19 ++++++++++++------- sway/tree/layout.c | 4 ++-- 3 files changed, 19 insertions(+), 11 deletions(-) (limited to 'sway/tree') diff --git a/sway/input/seat.c b/sway/input/seat.c index adc4cb0a..a1b1caa8 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -94,6 +94,7 @@ static void handle_seat_container_destroy(struct wl_listener *listener, // TODO handle workspace switch in the seat? bool set_focus = + focus != NULL && (focus == con || container_has_child(con, focus)) && con->type != C_WORKSPACE; @@ -103,12 +104,13 @@ static void handle_seat_container_destroy(struct wl_listener *listener, struct sway_container *next_focus = NULL; while (next_focus == NULL) { next_focus = sway_seat_get_focus_by_type(seat, parent, C_VIEW); - parent = parent->parent; if (next_focus == NULL && parent->type == C_WORKSPACE) { next_focus = parent; break; } + + parent = parent->parent; } // the structure change might have caused it to move up to the top of @@ -440,7 +442,8 @@ struct sway_container *sway_seat_get_focus_by_type(struct sway_seat *seat, wl_list_for_each(current, &seat->focus_stack, link) { parent = current->container->parent; - if (current->container == container) { + if (current->container == container && + (type == C_TYPES || container->type == type)) { return current->container; } diff --git a/sway/tree/container.c b/sway/tree/container.c index e2fe9e7c..b3c6d80f 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -69,11 +69,11 @@ static struct sway_container *_container_destroy(struct sway_container *cont) { if (cont->children != NULL) { // remove children until there are no more, container_destroy calls // container_remove_child, which removes child from this container - while (cont->children->length != 0) { - container_destroy(cont->children->items[0]); + while (cont->children != NULL && cont->children->length != 0) { + struct sway_container *child = cont->children->items[0]; + container_remove_child(child); + container_destroy(child); } - list_free(cont->children); - cont->children = NULL; } if (cont->marks) { list_foreach(cont->marks, free); @@ -85,13 +85,17 @@ static struct sway_container *_container_destroy(struct sway_container *cont) { if (cont->name) { free(cont->name); } + list_free(cont->children); + cont->children = NULL; free(cont); return parent; } struct sway_container *container_destroy(struct sway_container *cont) { - cont = _container_destroy(cont); - return container_reap_empty(cont->parent); + struct sway_container *parent = _container_destroy(cont); + parent = container_reap_empty(parent); + arrange_windows(&root_container, -1, -1); + return parent; } struct sway_container *container_output_create( @@ -409,7 +413,8 @@ bool find_child_func(struct sway_container *con, void *data) { bool container_has_child(struct sway_container *con, struct sway_container *child) { - if (child->type == C_VIEW || child->children->length == 0) { + if (child == NULL || child->type == C_VIEW || + child->children->length == 0) { return false; } return container_find(con, find_child_func, child); diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 62df19e9..5098c8d1 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -106,11 +106,11 @@ void container_add_child(struct sway_container *parent, } struct sway_container *container_reap_empty(struct sway_container *container) { - if (!sway_assert(container, "reaping null container")) { + if (container == NULL) { return NULL; } wlr_log(L_DEBUG, "reaping %p %s", container, container->name); - while (container != &root_container && container->children->length == 0) { + while (container->type != C_VIEW && container != &root_container && container->children->length == 0) { if (container->type == C_WORKSPACE) { if (!workspace_is_visible(container)) { struct sway_container *parent = container->parent; -- cgit v1.2.3 From 27e394f8b07fed21f791f2a06b93c3bfc0f991b7 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sat, 31 Mar 2018 19:45:30 -0400 Subject: fix children list segfault --- sway/tree/container.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sway/tree') diff --git a/sway/tree/container.c b/sway/tree/container.c index b3c6d80f..f4c82abe 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -71,8 +71,8 @@ static struct sway_container *_container_destroy(struct sway_container *cont) { // container_remove_child, which removes child from this container while (cont->children != NULL && cont->children->length != 0) { struct sway_container *child = cont->children->items[0]; - container_remove_child(child); container_destroy(child); + list_del(cont->children, 0); } } if (cont->marks) { -- cgit v1.2.3 From 357a4401fa117416f3182a5f91d27b52b114f3ee Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Mon, 2 Apr 2018 14:15:40 -0400 Subject: address feedback --- sway/commands/split.c | 1 + sway/input/seat.c | 1 - sway/tree/container.c | 2 +- sway/tree/layout.c | 5 ++--- 4 files changed, 4 insertions(+), 5 deletions(-) (limited to 'sway/tree') diff --git a/sway/commands/split.c b/sway/commands/split.c index 6df20e88..fe4013e9 100644 --- a/sway/commands/split.c +++ b/sway/commands/split.c @@ -76,6 +76,7 @@ struct cmd_results *cmd_split(int argc, char **argv) { strcasecmp(argv[0], "toggle") == 0) { struct sway_container *focused = config->handler_context.current_container; + if (focused->parent->layout == L_VERT) { _do_split(argc - 1, argv + 1, L_HORIZ); } else { diff --git a/sway/input/seat.c b/sway/input/seat.c index a1b1caa8..1fd204d4 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -92,7 +92,6 @@ static void handle_seat_container_destroy(struct wl_listener *listener, struct sway_container *parent = con->parent; struct sway_container *focus = sway_seat_get_focus(seat); - // TODO handle workspace switch in the seat? bool set_focus = focus != NULL && (focus == con || container_has_child(con, focus)) && diff --git a/sway/tree/container.c b/sway/tree/container.c index 41ba973f..9205d929 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -424,7 +424,7 @@ bool container_has_anscestor(struct sway_container *descendant, return false; } -bool find_child_func(struct sway_container *con, void *data) { +static bool find_child_func(struct sway_container *con, void *data) { struct sway_container *child = data; return con == child; } diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 83e4fe37..e13c2ac4 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -101,8 +101,6 @@ void container_add_child(struct sway_container *parent, parent, parent->type, parent->width, parent->height); list_add(parent->children, child); child->parent = parent; - // TODO: set focus for this container? - sway_input_manager_set_focus(input_manager, child); } struct sway_container *container_reap_empty(struct sway_container *container) { @@ -632,7 +630,8 @@ struct sway_container *container_get_in_direction( wrap_candidate = parent->children->items[0]; } if (config->force_focus_wrapping) { - return sway_seat_get_focus_by_type(seat, wrap_candidate, C_VIEW); + return sway_seat_get_focus_by_type(seat, + wrap_candidate, C_VIEW); } } } else { -- cgit v1.2.3 From d070244362f7d34bc15418154e52f8c968fbad41 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Mon, 2 Apr 2018 15:40:40 -0400 Subject: fix workspace splits --- sway/commands/split.c | 25 ++----------------------- sway/tree/layout.c | 38 +++++++++++++++++++++----------------- 2 files changed, 23 insertions(+), 40 deletions(-) (limited to 'sway/tree') diff --git a/sway/commands/split.c b/sway/commands/split.c index fe4013e9..ca116aef 100644 --- a/sway/commands/split.c +++ b/sway/commands/split.c @@ -25,29 +25,8 @@ static struct cmd_results *_do_split(int argc, char **argv, int layout) { } struct sway_container *focused = config->handler_context.current_container; - - // TODO floating: dont split - - /* Case that focus is on an workspace with 0/1 children.change its layout */ - if (focused->type == C_WORKSPACE && focused->children->length <= 1) { - wlr_log(L_DEBUG, "changing workspace layout"); - container_set_layout(focused, layout); - } else if (focused->type != C_WORKSPACE && - focused->parent->children->length == 1) { - /* Case of no siblings. change parent layout */ - wlr_log(L_DEBUG, "changing container layout"); - container_set_layout(focused->parent, layout); - } else { - // regular case where new split container is build around focused - // container or in case of workspace, container inherits its children - wlr_log(L_DEBUG, - "Adding new container around current focused container"); - wlr_log(L_INFO, "FOCUSED SIZE: %.f %.f", - focused->width, focused->height); - - struct sway_container *parent = container_split(focused, layout); - arrange_windows(parent, -1, -1); - } + struct sway_container *parent = container_split(focused, layout); + arrange_windows(parent, -1, -1); // TODO borders: update borders diff --git a/sway/tree/layout.c b/sway/tree/layout.c index e13c2ac4..bea15f8a 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -405,7 +405,12 @@ void apply_vert_layout(struct sway_container *container, wlr_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %f by %f)", child, child->type, height, scale); - view_set_position(child->sway_view, x, child_y); + if (child->type == C_VIEW) { + view_set_position(child->sway_view, x, child_y); + } else { + child->x = x; + child->y = child_y; + } if (i == end - 1) { double remaining_height = y + height - child_y; @@ -691,34 +696,33 @@ struct sway_container *container_split(struct sway_container *child, wlr_log(L_DEBUG, "creating container %p around %p", cont, child); cont->prev_layout = L_NONE; - cont->layout = layout; cont->width = child->width; cont->height = child->height; cont->x = child->x; cont->y = child->y; - /* Container inherits all of workspaces children, layout and whatnot */ if (child->type == C_WORKSPACE) { + struct sway_seat *seat = sway_input_manager_get_default_seat(input_manager); struct sway_container *workspace = child; - // reorder focus - int i; - for (i = 0; i < workspace->children->length; ++i) { - ((struct sway_container *)workspace->children->items[i])->parent = - cont; + bool set_focus = (sway_seat_get_focus(seat) == workspace); + + while (workspace->children->length) { + struct sway_container *ws_child = workspace->children->items[0]; + container_remove_child(ws_child); + container_add_child(cont, ws_child); } - // Swap children - list_t *tmp_list = workspace->children; - workspace->children = cont->children; - cont->children = tmp_list; - // add container to workspace chidren container_add_child(workspace, cont); - // give them proper layouts - cont->layout = workspace->workspace_layout; - cont->prev_layout = workspace->prev_layout; - } else { // Or is built around container + container_set_layout(workspace, layout); + + if (set_focus) { + sway_seat_set_focus(seat, cont); + } + } else { + cont->layout = layout; container_replace_child(child, cont); container_add_child(cont, child); } + return cont; } -- cgit v1.2.3