diff --git a/include/sway/commands.h b/include/sway/commands.h index 389c382eb..a29fdad82 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h @@ -106,6 +106,7 @@ sway_cmd cmd_exec_process; sway_cmd cmd_allow_tearing; sway_cmd cmd_assign; +sway_cmd cmd_assign_parent_workspace; sway_cmd cmd_bar; sway_cmd cmd_bindcode; sway_cmd cmd_bindgesture; diff --git a/include/sway/criteria.h b/include/sway/criteria.h index fad278e02..e7e76e5b7 100644 --- a/include/sway/criteria.h +++ b/include/sway/criteria.h @@ -17,6 +17,7 @@ enum criteria_type { CT_ASSIGN_WORKSPACE = 1 << 2, CT_ASSIGN_WORKSPACE_NUMBER = 1 << 3, CT_NO_FOCUS = 1 << 4, + CT_ASSIGN_PARENT_WORKSPACE = 1 << 5, }; enum pattern_type { diff --git a/sway/commands.c b/sway/commands.c index c2c12ee65..0e7e50166 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -43,6 +43,7 @@ struct cmd_results *checkarg(int argc, const char *name, enum expected_args type /* Keep alphabetized */ static const struct cmd_handler handlers[] = { { "assign", cmd_assign }, + { "assign_parent_workspace", cmd_assign_parent_workspace }, { "bar", cmd_bar }, { "bindcode", cmd_bindcode }, { "bindgesture", cmd_bindgesture }, diff --git a/sway/commands/assign_parent_workspace.c b/sway/commands/assign_parent_workspace.c new file mode 100644 index 000000000..ab809eef0 --- /dev/null +++ b/sway/commands/assign_parent_workspace.c @@ -0,0 +1,34 @@ +#include +#include "sway/commands.h" +#include "sway/criteria.h" +#include "list.h" +#include "log.h" + +struct cmd_results *cmd_assign_parent_workspace(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "assign_parent_workspace", EXPECTED_AT_LEAST, 1))) { + return error; + } + + char *err_str = NULL; + struct criteria *criteria = criteria_parse(argv[0], &err_str); + if (!criteria) { + error = cmd_results_new(CMD_INVALID, "%s", err_str); + free(err_str); + return error; + } + + criteria->type = CT_ASSIGN_PARENT_WORKSPACE; + + // Check if it already exists + if (criteria_already_exists(criteria)) { + sway_log(SWAY_DEBUG, "assign_parent_workspace already exists: '%s'", criteria->raw); + criteria_destroy(criteria); + return cmd_results_new(CMD_SUCCESS, NULL); + } + + list_add(config->criteria, criteria); + sway_log(SWAY_DEBUG, "assign_parent_workspace: '%s' added", criteria->raw); + + return cmd_results_new(CMD_SUCCESS, NULL); +} diff --git a/sway/meson.build b/sway/meson.build index cb03a4d28..c2e8b2f92 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -44,6 +44,7 @@ sway_sources = files( 'commands/allow_tearing.c', 'commands/assign.c', + 'commands/assign_parent_workspace.c', 'commands/bar.c', 'commands/bind.c', 'commands/border.c', diff --git a/sway/tree/view.c b/sway/tree/view.c index 4e2b7f4ae..a4dc98606 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -619,15 +619,9 @@ static struct sway_workspace *get_parent_workspace(struct sway_view *view) { static struct sway_workspace *select_workspace(struct sway_view *view) { struct sway_seat *seat = input_manager_current_seat(); - // Check if the view has a parent window, and if so, use its workspace - struct sway_workspace *parent_ws = get_parent_workspace(view); - if (parent_ws) { - return parent_ws; - } - // Check if there's any `assign` criteria for the view list_t *criterias = criteria_for_view(view, - CT_ASSIGN_WORKSPACE | CT_ASSIGN_WORKSPACE_NUMBER | CT_ASSIGN_OUTPUT); + CT_ASSIGN_WORKSPACE | CT_ASSIGN_WORKSPACE_NUMBER | CT_ASSIGN_OUTPUT | CT_ASSIGN_PARENT_WORKSPACE); struct sway_workspace *ws = NULL; for (int i = 0; i < criterias->length; ++i) { struct criteria *criteria = criterias->items[i]; @@ -637,6 +631,12 @@ static struct sway_workspace *select_workspace(struct sway_view *view) { ws = output_get_active_workspace(output); break; } + } else if (criteria->type == CT_ASSIGN_PARENT_WORKSPACE) { + // Assign to parent's workspace if parent exists + ws = get_parent_workspace(view); + if (ws) { + break; + } } else { // CT_ASSIGN_WORKSPACE(_NUMBER) ws = criteria->type == CT_ASSIGN_WORKSPACE_NUMBER ?