diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 136d618b..c9290108 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h @@ -78,6 +78,9 @@ struct sway_container { enum sway_container_layout layout; enum sway_container_layout prev_split_layout; + // Whether stickiness has been enabled on this container. Use + // `container_is_sticky_[or_child]` rather than accessing this field + // directly; it'll also check that the container is floating. bool is_sticky; // For C_ROOT, this has no meaning @@ -367,4 +370,8 @@ bool container_is_scratchpad_hidden(struct sway_container *con); bool container_is_scratchpad_hidden_or_child(struct sway_container *con); +bool container_is_sticky(struct sway_container *con); + +bool container_is_sticky_or_child(struct sway_container *con); + #endif diff --git a/sway/commands/move.c b/sway/commands/move.c index 876a5616..204596c0 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c @@ -482,7 +482,7 @@ static struct cmd_results *cmd_move_container(bool no_auto_back_and_forth, // We have to create the workspace, but if the container is // sticky and the workspace is going to be created on the same // output, we'll bail out first. - if (container->is_sticky && container_is_floating_or_child(container)) { + if (container_is_sticky_or_child(container)) { struct sway_output *new_output = workspace_get_initial_output(ws_name); if (old_output == new_output) { @@ -521,8 +521,8 @@ static struct cmd_results *cmd_move_container(bool no_auto_back_and_forth, return cmd_move_to_scratchpad(); } - if (container->is_sticky && container_is_floating_or_child(container) && - old_output && node_has_ancestor(destination, &old_output->node)) { + if (container_is_sticky_or_child(container) && old_output && + node_has_ancestor(destination, &old_output->node)) { return cmd_results_new(CMD_FAILURE, "Can't move sticky " "container to another workspace on the same output"); } diff --git a/sway/commands/sticky.c b/sway/commands/sticky.c index 9df1fe09..3c93a276 100644 --- a/sway/commands/sticky.c +++ b/sway/commands/sticky.c @@ -25,7 +25,7 @@ struct cmd_results *cmd_sticky(int argc, char **argv) { container->is_sticky = parse_boolean(argv[0], container->is_sticky); - if (container->is_sticky && container_is_floating_or_child(container) && + if (container_is_sticky_or_child(container) && !container_is_scratchpad_hidden(container)) { // move container to active workspace struct sway_workspace *active_workspace = diff --git a/sway/input/seat.c b/sway/input/seat.c index 24d7e903..2b41d1cb 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -1151,7 +1151,7 @@ void seat_set_focus(struct sway_seat *seat, struct sway_node *node) { for (int i = 0; i < new_output_last_ws->floating->length; ++i) { struct sway_container *floater = new_output_last_ws->floating->items[i]; - if (floater->is_sticky) { + if (container_is_sticky(floater)) { container_detach(floater); workspace_add_floating(new_workspace, floater); --i; diff --git a/sway/tree/container.c b/sway/tree/container.c index 8557210f..10d621b4 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -1609,3 +1609,11 @@ bool container_is_scratchpad_hidden_or_child(struct sway_container *con) { con = container_toplevel_ancestor(con); return con->scratchpad && !con->workspace; } + +bool container_is_sticky(struct sway_container *con) { + return con->is_sticky && container_is_floating(con); +} + +bool container_is_sticky_or_child(struct sway_container *con) { + return container_is_sticky(container_toplevel_ancestor(con)); +} diff --git a/sway/tree/view.c b/sway/tree/view.c index d699b01e..354f2d34 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -1244,13 +1244,9 @@ bool view_is_visible(struct sway_view *view) { return false; } } - // Determine if view is nested inside a floating container which is sticky - struct sway_container *floater = view->container; - while (floater->parent) { - floater = floater->parent; - } - bool is_sticky = container_is_floating(floater) && floater->is_sticky; - if (!is_sticky && workspace && !workspace_is_visible(workspace)) { + + if (!container_is_sticky_or_child(view->container) && workspace && + !workspace_is_visible(workspace)) { return false; } // Check view isn't in a tabbed or stacked container on an inactive tab diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 476c2568..ffcbe933 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -498,7 +498,7 @@ bool workspace_is_empty(struct sway_workspace *ws) { // Sticky views are not considered to be part of this workspace for (int i = 0; i < ws->floating->length; ++i) { struct sway_container *floater = ws->floating->items[i]; - if (!floater->is_sticky) { + if (!container_is_sticky(floater)) { return false; } } @@ -819,7 +819,7 @@ size_t workspace_num_tiling_views(struct sway_workspace *ws) { } static void count_sticky_containers(struct sway_container *con, void *data) { - if (container_is_floating(con) && con->is_sticky) { + if (container_is_sticky(con)) { size_t *count = data; *count += 1; }