aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar ftilde <ftilde@tamepointer.de>2020-12-12 00:11:58 +0100
committerLibravatar Tudor Brindus <me@tbrindus.ca>2021-02-25 09:48:39 -0500
commit1afedcb94c0517b5434e2220e63b997cf01427bd (patch)
tree3fae6d855a165e7364540a1474508caa8ae1b708
parentfocus: beyond fullscreen when focused explicitly (diff)
downloadsway-1afedcb94c0517b5434e2220e63b997cf01427bd.tar.gz
sway-1afedcb94c0517b5434e2220e63b997cf01427bd.tar.zst
sway-1afedcb94c0517b5434e2220e63b997cf01427bd.zip
Fix for_window criteria and mouse button bindings
Previously, the special case handling of scratchpad and unmark commands was (probably accidentally) limited to criteria directly handled in the execute_command function. This would exclude: 1. for_window criteria, as these are handled externally for views and 2. and mouse bindings which select target the node currently under the mouse cursor. As a concrete example `for_window [app_id="foobar"] move scratchpad, scratchpad show` would show (or hide due to the toggling functionality) another window from the scratchpad, instead of showing the window with app_id "foobar". This commit replaces the "using_criteria" flag with "node_overridden" with the more general notion of signifying that the node (and container/workspace) in the current command handler context of the sway config is not defined by the currently focused node, but instead overridden by other means, i.e., criteria or mouse position.
-rw-r--r--include/sway/config.h2
-rw-r--r--sway/commands.c23
-rw-r--r--sway/commands/scratchpad.c9
-rw-r--r--sway/commands/unmark.c2
4 files changed, 21 insertions, 15 deletions
diff --git a/include/sway/config.h b/include/sway/config.h
index 59f22ae2..2a1df2b6 100644
--- a/include/sway/config.h
+++ b/include/sway/config.h
@@ -559,7 +559,7 @@ struct sway_config {
559 struct sway_node *node; 559 struct sway_node *node;
560 struct sway_container *container; 560 struct sway_container *container;
561 struct sway_workspace *workspace; 561 struct sway_workspace *workspace;
562 bool using_criteria; 562 bool node_overridden; // True if the node is selected by means other than focus
563 struct { 563 struct {
564 int argc; 564 int argc;
565 char **argv; 565 char **argv;
diff --git a/sway/commands.c b/sway/commands.c
index ede6c60c..b09a04c7 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -174,10 +174,11 @@ static const struct cmd_handler *find_core_handler(char *line) {
174 handlers, sizeof(handlers)); 174 handlers, sizeof(handlers));
175} 175}
176 176
177static void set_config_node(struct sway_node *node) { 177static void set_config_node(struct sway_node *node, bool node_overridden) {
178 config->handler_context.node = node; 178 config->handler_context.node = node;
179 config->handler_context.container = NULL; 179 config->handler_context.container = NULL;
180 config->handler_context.workspace = NULL; 180 config->handler_context.workspace = NULL;
181 config->handler_context.node_overridden = node_overridden;
181 182
182 if (node == NULL) { 183 if (node == NULL) {
183 return; 184 return;
@@ -202,6 +203,7 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
202 char *cmd; 203 char *cmd;
203 char matched_delim = ';'; 204 char matched_delim = ';';
204 list_t *containers = NULL; 205 list_t *containers = NULL;
206 bool using_criteria = false;
205 207
206 if (seat == NULL) { 208 if (seat == NULL) {
207 // passing a NULL seat means we just pick the default seat 209 // passing a NULL seat means we just pick the default seat
@@ -225,7 +227,7 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
225 for (; isspace(*head); ++head) {} 227 for (; isspace(*head); ++head) {}
226 // Extract criteria (valid for this command list only). 228 // Extract criteria (valid for this command list only).
227 if (matched_delim == ';') { 229 if (matched_delim == ';') {
228 config->handler_context.using_criteria = false; 230 using_criteria = false;
229 if (*head == '[') { 231 if (*head == '[') {
230 char *error = NULL; 232 char *error = NULL;
231 struct criteria *criteria = criteria_parse(head, &error); 233 struct criteria *criteria = criteria_parse(head, &error);
@@ -239,7 +241,7 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
239 containers = criteria_get_containers(criteria); 241 containers = criteria_get_containers(criteria);
240 head += strlen(criteria->raw); 242 head += strlen(criteria->raw);
241 criteria_destroy(criteria); 243 criteria_destroy(criteria);
242 config->handler_context.using_criteria = true; 244 using_criteria = true;
243 // Skip leading whitespace 245 // Skip leading whitespace
244 for (; isspace(*head); ++head) {} 246 for (; isspace(*head); ++head) {}
245 } 247 }
@@ -278,11 +280,14 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
278 argv[i] = do_var_replacement(argv[i]); 280 argv[i] = do_var_replacement(argv[i]);
279 } 281 }
280 282
281 if (!config->handler_context.using_criteria) { 283
282 // The container or workspace which this command will run on. 284 if (!using_criteria) {
283 struct sway_node *node = con ? &con->node : 285 if (con) {
284 seat_get_focus_inactive(seat, &root->node); 286 set_config_node(&con->node, true);
285 set_config_node(node); 287 } else {
288 set_config_node(seat_get_focus_inactive(seat, &root->node),
289 false);
290 }
286 struct cmd_results *res = handler->handle(argc-1, argv+1); 291 struct cmd_results *res = handler->handle(argc-1, argv+1);
287 list_add(res_list, res); 292 list_add(res_list, res);
288 if (res->status == CMD_INVALID) { 293 if (res->status == CMD_INVALID) {
@@ -296,7 +301,7 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
296 struct cmd_results *fail_res = NULL; 301 struct cmd_results *fail_res = NULL;
297 for (int i = 0; i < containers->length; ++i) { 302 for (int i = 0; i < containers->length; ++i) {
298 struct sway_container *container = containers->items[i]; 303 struct sway_container *container = containers->items[i];
299 set_config_node(&container->node); 304 set_config_node(&container->node, true);
300 struct cmd_results *res = handler->handle(argc-1, argv+1); 305 struct cmd_results *res = handler->handle(argc-1, argv+1);
301 if (res->status == CMD_SUCCESS) { 306 if (res->status == CMD_SUCCESS) {
302 free_cmd_results(res); 307 free_cmd_results(res);
diff --git a/sway/commands/scratchpad.c b/sway/commands/scratchpad.c
index a1285df5..c995f2f0 100644
--- a/sway/commands/scratchpad.c
+++ b/sway/commands/scratchpad.c
@@ -105,12 +105,12 @@ struct cmd_results *cmd_scratchpad(int argc, char **argv) {
105 return cmd_results_new(CMD_INVALID, "Scratchpad is empty"); 105 return cmd_results_new(CMD_INVALID, "Scratchpad is empty");
106 } 106 }
107 107
108 if (config->handler_context.using_criteria) { 108 if (config->handler_context.node_overridden) {
109 struct sway_container *con = config->handler_context.container; 109 struct sway_container *con = config->handler_context.container;
110 110
111 // If the container is in a floating split container, 111 // If the container is in a floating split container,
112 // operate on the split container instead of the child. 112 // operate on the split container instead of the child.
113 if (container_is_floating_or_child(con)) { 113 if (con && container_is_floating_or_child(con)) {
114 while (con->pending.parent) { 114 while (con->pending.parent) {
115 con = con->pending.parent; 115 con = con->pending.parent;
116 } 116 }
@@ -118,8 +118,9 @@ struct cmd_results *cmd_scratchpad(int argc, char **argv) {
118 118
119 // If using criteria, this command is executed for every container which 119 // If using criteria, this command is executed for every container which
120 // matches the criteria. If this container isn't in the scratchpad, 120 // matches the criteria. If this container isn't in the scratchpad,
121 // we'll just silently return a success. 121 // we'll just silently return a success. The same is true if the
122 if (!con->scratchpad) { 122 // overridden node is not a container.
123 if (!con || !con->scratchpad) {
123 return cmd_results_new(CMD_SUCCESS, NULL); 124 return cmd_results_new(CMD_SUCCESS, NULL);
124 } 125 }
125 scratchpad_toggle_container(con); 126 scratchpad_toggle_container(con);
diff --git a/sway/commands/unmark.c b/sway/commands/unmark.c
index cedfcfb2..19274dfb 100644
--- a/sway/commands/unmark.c
+++ b/sway/commands/unmark.c
@@ -21,7 +21,7 @@ static void remove_all_marks_iterator(struct sway_container *con, void *data) {
21struct cmd_results *cmd_unmark(int argc, char **argv) { 21struct cmd_results *cmd_unmark(int argc, char **argv) {
22 // Determine the container 22 // Determine the container
23 struct sway_container *con = NULL; 23 struct sway_container *con = NULL;
24 if (config->handler_context.using_criteria) { 24 if (config->handler_context.node_overridden) {
25 con = config->handler_context.container; 25 con = config->handler_context.container;
26 } 26 }
27 27