From 48bc15e758c37e73f3eb6ae76f4ad758148dbfb1 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sun, 16 Sep 2018 14:04:25 +1000 Subject: [PATCH 1/2] Make seat_get_active_child ignore floating children seat_get_active_child is used to get the active tiling child in a few places, such as outputs getting their active workspace and tabbed/stacked containers getting their visible child. When a workspace uses a tabbed or stacked layout and contains a focused floating view, calling seat_get_active_child on the workspace would incorrectly return the floating view. This changes it so it will return the tiling child. This fixes the following bug: * Create layout T[view view] then float one of the views * Attempt to click the tiling view to give it focus - it wouldn't work because seat_get_active_child would return the floating view --- sway/input/seat.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/sway/input/seat.c b/sway/input/seat.c index ab5047b2a..6d02970d5 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -888,9 +888,17 @@ struct sway_node *seat_get_active_child(struct sway_seat *seat, struct sway_seat_node *current; wl_list_for_each(current, &seat->focus_stack, link) { struct sway_node *node = current->node; - if (node_get_parent(node) == parent) { - return node; + if (node_get_parent(node) != parent) { + continue; } + if (parent->type == N_WORKSPACE) { + // Only consider tiling children + struct sway_workspace *ws = parent->sway_workspace; + if (list_find(ws->tiling, node->sway_container) == -1) { + continue; + } + } + return node; } return NULL; } From f6e218a64371b02afdf6b7812a52d70b13635ef3 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sun, 16 Sep 2018 22:01:54 +1000 Subject: [PATCH 2/2] Rename seat_get_active_child to seat_get_active_tiling_child Also renames container to con in one function to prevent ugly line wrapping. --- include/sway/input/seat.h | 2 +- sway/commands/focus.c | 2 +- sway/commands/move.c | 2 +- sway/desktop/output.c | 2 +- sway/desktop/transaction.c | 3 ++- sway/input/seat.c | 2 +- sway/tree/container.c | 4 ++-- sway/tree/view.c | 14 +++++++------- 8 files changed, 16 insertions(+), 15 deletions(-) diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h index 7b756ef3d..ebb0cd431 100644 --- a/include/sway/input/seat.h +++ b/include/sway/input/seat.h @@ -155,7 +155,7 @@ struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat, /** * Return the immediate child of container which was most recently focused. */ -struct sway_node *seat_get_active_child(struct sway_seat *seat, +struct sway_node *seat_get_active_tiling_child(struct sway_seat *seat, struct sway_node *parent); /** diff --git a/sway/commands/focus.c b/sway/commands/focus.c index d63077e6c..44adb95bd 100644 --- a/sway/commands/focus.c +++ b/sway/commands/focus.c @@ -261,7 +261,7 @@ struct cmd_results *cmd_focus(int argc, char **argv) { } if (direction == MOVE_CHILD) { - struct sway_node *focus = seat_get_active_child(seat, node); + struct sway_node *focus = seat_get_active_tiling_child(seat, node); if (focus) { seat_set_focus(seat, focus); cursor_send_pointer_motion(seat->cursor, 0, true); diff --git a/sway/commands/move.c b/sway/commands/move.c index 8f0ef230c..42b305d19 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c @@ -149,7 +149,7 @@ static void container_move_to_container_from_direction( } wlr_log(WLR_DEBUG, "Reparenting container (perpendicular)"); - struct sway_node *focus_inactive = seat_get_active_child( + struct sway_node *focus_inactive = seat_get_active_tiling_child( config->handler_context.seat, &destination->node); if (!focus_inactive || focus_inactive == &destination->node) { // The container has no children diff --git a/sway/desktop/output.c b/sway/desktop/output.c index a5db15cd7..cfb5a710f 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -232,7 +232,7 @@ static void scale_box(struct wlr_box *box, float scale) { struct sway_workspace *output_get_active_workspace(struct sway_output *output) { struct sway_seat *seat = input_manager_current_seat(input_manager); - struct sway_node *focus = seat_get_active_child(seat, &output->node); + struct sway_node *focus = seat_get_active_tiling_child(seat, &output->node); if (!focus) { return output->workspaces->items[0]; } diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index b4eec933f..d747e279f 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -176,7 +176,8 @@ static void copy_container_state(struct sway_container *container, state->focused = seat_get_focus(seat) == &container->node; if (!container->view) { - struct sway_node *focus = seat_get_active_child(seat, &container->node); + struct sway_node *focus = + seat_get_active_tiling_child(seat, &container->node); state->focused_inactive_child = focus ? focus->sway_container : NULL; } } diff --git a/sway/input/seat.c b/sway/input/seat.c index 6d02970d5..49fe46ba8 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -880,7 +880,7 @@ struct sway_container *seat_get_focus_inactive_floating(struct sway_seat *seat, return NULL; } -struct sway_node *seat_get_active_child(struct sway_seat *seat, +struct sway_node *seat_get_active_tiling_child(struct sway_seat *seat, struct sway_node *parent) { if (node_is_view(parent)) { return parent; diff --git a/sway/tree/container.c b/sway/tree/container.c index f906449a6..476877449 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -220,7 +220,7 @@ static struct sway_container *container_at_tabbed(struct sway_node *parent, } // Surfaces - struct sway_node *current = seat_get_active_child(seat, parent); + struct sway_node *current = seat_get_active_tiling_child(seat, parent); return current ? tiling_container_at(current, lx, ly, surface, sx, sy) : NULL; } @@ -248,7 +248,7 @@ static struct sway_container *container_at_stacked(struct sway_node *parent, } // Surfaces - struct sway_node *current = seat_get_active_child(seat, parent); + struct sway_node *current = seat_get_active_tiling_child(seat, parent); return current ? tiling_container_at(current, lx, ly, surface, sx, sy) : NULL; } diff --git a/sway/tree/view.c b/sway/tree/view.c index 78f85de24..e4e1c1611 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -1001,17 +1001,17 @@ bool view_is_visible(struct sway_view *view) { bool is_sticky = container_is_floating(floater) && floater->is_sticky; // Check view isn't in a tabbed or stacked container on an inactive tab struct sway_seat *seat = input_manager_current_seat(input_manager); - struct sway_container *container = view->container; - while (container) { - enum sway_container_layout layout = container_parent_layout(container); + struct sway_container *con = view->container; + while (con) { + enum sway_container_layout layout = container_parent_layout(con); if (layout == L_TABBED || layout == L_STACKED) { - struct sway_node *parent = container->parent ? - &container->parent->node : &container->workspace->node; - if (seat_get_active_child(seat, parent) != &container->node) { + struct sway_node *parent = con->parent ? + &con->parent->node : &con->workspace->node; + if (seat_get_active_tiling_child(seat, parent) != &con->node) { return false; } } - container = container->parent; + con = con->parent; } // Check view isn't hidden by another fullscreen view if (workspace->fullscreen &&