diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index a5f74de94..b21e5d75e 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h @@ -373,4 +373,9 @@ bool container_is_sticky_or_child(struct sway_container *con); */ int container_squash(struct sway_container *con); +bool container_has_con_id(struct sway_container *con, size_t *con_id); + +/** Returns a container with the given con_id */ +struct sway_container *container_find_con_id(size_t *con_id); + #endif diff --git a/sway/commands/move.c b/sway/commands/move.c index 9768ee0aa..64f7a074e 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c @@ -25,7 +25,8 @@ static const char expected_syntax[] = "Expected 'move <[px] px>' or " "'move [--no-auto-back-and-forth] [to] workspace ' or " "'move [to] output ' or " - "'move [to] mark '"; + "'move [to] mark ' or " + "'move [to] con_id '"; static struct sway_output *output_in_direction(const char *direction_string, struct sway_output *reference, int ref_lx, int ref_ly) { @@ -520,6 +521,14 @@ static struct cmd_results *cmd_move_container(bool no_auto_back_and_forth, "Mark '%s' not found", argv[1]); } destination = &dest_con->node; + } else if (strcasecmp(argv[0], "con_id") == 0) { + size_t con_id = atoi(argv[1]); + struct sway_container *dest_con = container_find_con_id(&con_id); + if (dest_con == NULL) { + return cmd_results_new(CMD_FAILURE, + "No container with con_id '%s' found", argv[1]); + } + destination = &dest_con->node; } else { return cmd_results_new(CMD_INVALID, expected_syntax); } @@ -982,6 +991,7 @@ static const char expected_full_syntax[] = "Expected " " |next|prev|next_on_output|prev_on_output|current|(number )'" " or 'move [window|container] [to] output |left|right|up|down'" " or 'move [window|container] [to] mark '" + " or 'move [window|container] [to] con_id '" " or 'move [window|container] [to] scratchpad'" " or 'move workspace to [output] |left|right|up|down'" " or 'move [window|container] [to] [absolute] position [px] [px]'" @@ -1040,7 +1050,8 @@ struct cmd_results *cmd_move(int argc, char **argv) { if (strcasecmp(argv[0], "workspace") == 0 || strcasecmp(argv[0], "output") == 0 || - strcasecmp(argv[0], "mark") == 0) { + strcasecmp(argv[0], "mark") == 0 || + strcasecmp(argv[0], "con_id") == 0) { return cmd_move_container(no_auto_back_and_forth, argc, argv); } else if (strcasecmp(argv[0], "scratchpad") == 0) { return cmd_move_to_scratchpad(); diff --git a/sway/sway.5.scd b/sway/sway.5.scd index 168761e1a..9f993f8d0 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd @@ -231,6 +231,10 @@ set|plus|minus|toggle *move* [container|window] [to] mark Moves the focused container to the specified mark. +*move* [container|window] [to] con_id + Moves the focused container to become a direct descendant of the specified + con_id. If the destination can't have descendants, the command does nothing. + *move* [--no-auto-back-and-forth] [container|window] [to] workspace [number] Moves the focused container to the specified workspace. The string _number_ is optional and is used to match a workspace with the same number, even if diff --git a/sway/tree/container.c b/sway/tree/container.c index 09766ce5c..495cb7b75 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -1821,3 +1821,16 @@ int container_squash(struct sway_container *con) { } return change; } + +bool container_has_con_id(struct sway_container *con, size_t *con_id) { + return con->node.id == *con_id; +} + +static bool find_by_con_id(struct sway_container *con, void *data) { + size_t *con_id = data; + return con->node.id == *con_id; +} + +struct sway_container *container_find_con_id(size_t *con_id) { + return root_find_container(find_by_con_id, con_id); +}