From 4d1edfcba90854bd7f37ecb1b36fe4f05c37dda3 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Tue, 15 May 2018 11:24:16 +1000 Subject: [PATCH] Change unmark implemention to match i3's --- include/sway/config.h | 1 + sway/commands.c | 6 ++--- sway/commands/mark.c | 2 +- sway/commands/unmark.c | 51 ++++++++++++++++++++++++++++++++---------- 4 files changed, 44 insertions(+), 16 deletions(-) diff --git a/include/sway/config.h b/include/sway/config.h index f77c3b503..33f521567 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -368,6 +368,7 @@ struct sway_config { struct seat_config *seat_config; struct sway_seat *seat; struct sway_container *current_container; + bool using_criteria; } handler_context; }; diff --git a/sway/commands.c b/sway/commands.c index 31d241a82..9b6d64592 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -302,7 +302,7 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat) { head = exec; do { // Extract criteria (valid for this command list only). - bool has_criteria = false; + config->handler_context.using_criteria = false; if (*head == '[') { char *error = NULL; struct criteria *criteria = criteria_parse(head, &error); @@ -315,7 +315,7 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat) { views = criteria_get_views(criteria); head += strlen(criteria->raw); criteria_destroy(criteria); - has_criteria = true; + config->handler_context.using_criteria = true; // Skip leading whitespace head += strspn(head, whitespace); } @@ -352,7 +352,7 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat) { goto cleanup; } - if (!has_criteria) { + if (!config->handler_context.using_criteria) { // without criteria, the command acts upon the focused // container config->handler_context.current_container = diff --git a/sway/commands/mark.c b/sway/commands/mark.c index 782e8ab99..b131f2f32 100644 --- a/sway/commands/mark.c +++ b/sway/commands/mark.c @@ -57,7 +57,7 @@ struct cmd_results *cmd_mark(int argc, char **argv) { view_find_and_unmark(mark); - if (!toggle || (toggle && !had_mark)) { + if (!toggle || !had_mark) { list_add(view->marks, strdup(mark)); } diff --git a/sway/commands/unmark.c b/sway/commands/unmark.c index a7d39432a..ea2a57098 100644 --- a/sway/commands/unmark.c +++ b/sway/commands/unmark.c @@ -7,26 +7,53 @@ #include "log.h" #include "stringop.h" +static void remove_all_marks_iterator(struct sway_container *con, void *data) { + if (con->type == C_VIEW) { + view_clear_marks(con->sway_view); + } +} + +// unmark Remove all marks from all views +// unmark foo Remove single mark from whichever view has it +// [criteria] unmark Remove all marks from matched view +// [criteria] unmark foo Remove single mark from matched view + struct cmd_results *cmd_unmark(int argc, char **argv) { - if (argc == 0) { - // Remove all marks from the current container + // Determine the view + struct sway_view *view = NULL; + if (config->handler_context.using_criteria) { struct sway_container *container = config->handler_context.current_container; if (container->type != C_VIEW) { return cmd_results_new(CMD_INVALID, "unmark", "Only views can have marks"); } - view_clear_marks(container->sway_view); - } else { - // Remove a single mark from whichever container has it - char *mark = join_args(argv, argc); - if (!view_find_and_unmark(mark)) { - free(mark); - return cmd_results_new(CMD_INVALID, "unmark", - "No view exists with that mark"); - } - free(mark); + view = container->sway_view; } + // Determine the mark + char *mark = NULL; + if (argc > 0) { + mark = join_args(argv, argc); + } + + if (view && mark) { + // Remove the mark from the given view + if (view_has_mark(view, mark)) { + view_find_and_unmark(mark); + } + } else if (view && !mark) { + // Clear all marks from the given view + view_clear_marks(view); + } else if (!view && mark) { + // Remove mark from whichever view has it + view_find_and_unmark(mark); + } else { + // Remove all marks from all views + container_for_each_descendant_dfs(&root_container, + remove_all_marks_iterator, NULL); + } + free(mark); + return cmd_results_new(CMD_SUCCESS, NULL, NULL); }