From a06cb7cd01acfbb5e31dd1aacbbde7887a0509b9 Mon Sep 17 00:00:00 2001 From: "S. Christoffer Eliesen" Date: Tue, 17 Nov 2015 19:27:01 +0100 Subject: criteria: Add. Learn for_window command. A criteria is a string in the form of `[class="regex.*" title="str"]`. It is stored in a struct with a list of *tokens* which is a attribute/value pair (stored as a `crit_token` struct). Most tokens will also have a precompiled regex stored that will be used during criteria matching. for_window command: When a new view is created its metadata is tested against all stored criteria, and if a match is found the associated command list is executed. Unfortunately some metadata is not available in sway at the moment (specifically `instance`, `window_role` and `urgent`). Any criteria string that tries to match an unsupported attribute will fail. (Note that while the criteria code can be used to parse any criteria string it is currently only used by the `for_window` command.) --- sway/commands.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'sway/commands.c') diff --git a/sway/commands.c b/sway/commands.c index 42105d5f..6a4af43c 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -23,6 +23,7 @@ #include "sway.h" #include "resize.h" #include "input_state.h" +#include "criteria.h" typedef struct cmd_results *sway_cmd(int argc, char **argv); @@ -41,6 +42,7 @@ static sway_cmd cmd_floating; static sway_cmd cmd_floating_mod; static sway_cmd cmd_focus; static sway_cmd cmd_focus_follows_mouse; +static sway_cmd cmd_for_window; static sway_cmd cmd_fullscreen; static sway_cmd cmd_gaps; static sway_cmd cmd_kill; @@ -1241,6 +1243,37 @@ static struct cmd_results *cmd_log_colors(int argc, char **argv) { return cmd_results_new(CMD_SUCCESS, NULL, NULL); } +static struct cmd_results *cmd_for_window(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "for_window", EXPECTED_AT_LEAST, 2))) { + return error; + } + // add command to a criteria/command pair that is run against views when they appear. + char *criteria = argv[0], *cmdlist = join_args(argv + 1, argc - 1); + + struct criteria *crit = malloc(sizeof(struct criteria)); + crit->crit_raw = strdup(criteria); + crit->cmdlist = cmdlist; + crit->tokens = create_list(); + char *err_str = extract_crit_tokens(crit->tokens, crit->crit_raw); + + if (err_str) { + error = cmd_results_new(CMD_INVALID, "for_window", err_str); + free(err_str); + free_criteria(crit); + } else if (crit->tokens->length == 0) { + error = cmd_results_new(CMD_INVALID, "for_window", "Found no name/value pairs in criteria"); + free_criteria(crit); + } else if (list_seq_find(config->criteria, criteria_cmp, crit) != -1) { + sway_log(L_DEBUG, "for_window: Duplicate, skipping."); + free_criteria(crit); + } else { + sway_log(L_DEBUG, "for_window: '%s' -> '%s' added", crit->crit_raw, crit->cmdlist); + list_add(config->criteria, crit); + } + return error ? error : cmd_results_new(CMD_SUCCESS, NULL, NULL); +} + static struct cmd_results *cmd_fullscreen(int argc, char **argv) { struct cmd_results *error = NULL; if (config->reading) return cmd_results_new(CMD_FAILURE, "fullscreen", "Can't be used in config file."); @@ -1353,6 +1386,7 @@ static struct cmd_handler handlers[] = { { "floating_modifier", cmd_floating_mod }, { "focus", cmd_focus }, { "focus_follows_mouse", cmd_focus_follows_mouse }, + { "for_window", cmd_for_window }, { "fullscreen", cmd_fullscreen }, { "gaps", cmd_gaps }, { "kill", cmd_kill }, -- cgit v1.2.3