aboutsummaryrefslogtreecommitdiffstats
path: root/sway/commands/assign.c
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-05-09 14:23:20 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-05-11 09:38:53 +1000
commit3b0c26d149dfe5e05df338692db8255a01f0998d (patch)
treec39e377cb96297df8547311a0aa4cfe8fa85b517 /sway/commands/assign.c
parentMerge pull request #1948 from RyanDwyer/focus-parent-border (diff)
downloadsway-3b0c26d149dfe5e05df338692db8255a01f0998d.tar.gz
sway-3b0c26d149dfe5e05df338692db8255a01f0998d.tar.zst
sway-3b0c26d149dfe5e05df338692db8255a01f0998d.zip
Overhaul criteria implementation
The criteria struct now uses properties for each token type rather than the list_t list of tokens. The reason for this is that different token types have different data types: pcre, string and number to name a few. This solution should be more flexible moving forward. A bonus of this is that criteria is now easier to understand when looking at the struct definition. The criteria parser has been rewritten because the previous one didn't support valueless pairs (eg. [class="foo" floating]). Criteria now has types. Types at the moment are CT_COMMAND, CT_ASSIGN_WORKSPACE and CT_ASSIGN_OUTPUT. i3 uses types as well. Previously the assign command was creating a criteria with 'move to workspace <name>' as its command, but this caused the window to appear briefly on the focused workspace before being moved to the assigned workspace. It now creates the view directly in the assigned workspace. Each view will only execute a given criteria once. This is achieved by storing a list of executed criteria in the view. This is the same strategy used by i3. Escaping now works properly. Previously you could do things like [class="Fire\"fox"] and the stored value would be 'Fire\"fox', but it should be (and now is) 'Fire"fox'. The public functions in criteria.c are now all prefixed with criteria_. Xwayland views now listen to the set_title, set_class and set_window_type events and criteria will be run when these happen. XDG shell has none of these events so it continues to update the title in handle_commit. Each view type's get_prop function has been split into get_string_prop and get_int_prop because some properties like the X11 window ID and window type are numeric. The following new criteria tokens are now supported: * id (X11 window ID) * instance * tiling * workspace
Diffstat (limited to 'sway/commands/assign.c')
-rw-r--r--sway/commands/assign.c58
1 files changed, 26 insertions, 32 deletions
diff --git a/sway/commands/assign.c b/sway/commands/assign.c
index eb7329aa..9d15e166 100644
--- a/sway/commands/assign.c
+++ b/sway/commands/assign.c
@@ -5,6 +5,7 @@
5#include "sway/criteria.h" 5#include "sway/criteria.h"
6#include "list.h" 6#include "list.h"
7#include "log.h" 7#include "log.h"
8#include "stringop.h"
8 9
9struct cmd_results *cmd_assign(int argc, char **argv) { 10struct cmd_results *cmd_assign(int argc, char **argv) {
10 struct cmd_results *error = NULL; 11 struct cmd_results *error = NULL;
@@ -12,46 +13,39 @@ struct cmd_results *cmd_assign(int argc, char **argv) {
12 return error; 13 return error;
13 } 14 }
14 15
15 char *criteria = *argv++; 16 // Create criteria
17 char *err_str = NULL;
18 struct criteria *criteria = criteria_parse(argv[0], &err_str);
19 if (!criteria) {
20 error = cmd_results_new(CMD_INVALID, "assign", err_str);
21 free(err_str);
22 return error;
23 }
24
25 ++argv;
26 int target_len = argc - 1;
16 27
17 if (strncmp(*argv, "→", strlen("→")) == 0) { 28 if (strncmp(*argv, "→", strlen("→")) == 0) {
18 if (argc < 3) { 29 if (argc < 3) {
19 return cmd_results_new(CMD_INVALID, "assign", "Missing workspace"); 30 return cmd_results_new(CMD_INVALID, "assign", "Missing workspace");
20 } 31 }
21 argv++; 32 ++argv;
33 --target_len;
22 } 34 }
23 35
24 char *movecmd = "move container to workspace "; 36 if (strcmp(*argv, "output") == 0) {
25 size_t arglen = strlen(movecmd) + strlen(*argv) + 1; 37 criteria->type = CT_ASSIGN_OUTPUT;
26 char *cmdlist = calloc(1, arglen); 38 ++argv;
27 if (!cmdlist) { 39 --target_len;
28 return cmd_results_new(CMD_FAILURE, "assign", "Unable to allocate command list"); 40 } else {
41 criteria->type = CT_ASSIGN_WORKSPACE;
29 } 42 }
30 snprintf(cmdlist, arglen, "%s%s", movecmd, *argv);
31 43
32 struct criteria *crit = malloc(sizeof(struct criteria)); 44 criteria->target = join_args(argv, target_len);
33 if (!crit) {
34 free(cmdlist);
35 return cmd_results_new(CMD_FAILURE, "assign", "Unable to allocate criteria");
36 }
37 crit->crit_raw = strdup(criteria);
38 crit->cmdlist = cmdlist;
39 crit->tokens = create_list();
40 char *err_str = extract_crit_tokens(crit->tokens, crit->crit_raw);
41 45
42 if (err_str) { 46 list_add(config->criteria, criteria);
43 error = cmd_results_new(CMD_INVALID, "assign", err_str); 47 wlr_log(L_DEBUG, "assign: '%s' -> '%s' added", criteria->raw,
44 free(err_str); 48 criteria->target);
45 free_criteria(crit); 49
46 } else if (crit->tokens->length == 0) { 50 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
47 error = cmd_results_new(CMD_INVALID, "assign", "Found no name/value pairs in criteria");
48 free_criteria(crit);
49 } else if (list_seq_find(config->criteria, criteria_cmp, crit) != -1) {
50 wlr_log(L_DEBUG, "assign: Duplicate, skipping.");
51 free_criteria(crit);
52 } else {
53 wlr_log(L_DEBUG, "assign: '%s' -> '%s' added", crit->crit_raw, crit->cmdlist);
54 list_add(config->criteria, crit);
55 }
56 return error ? error : cmd_results_new(CMD_SUCCESS, NULL, NULL);
57} 51}