diff options
author | ftilde <ftilde@tamepointer.de> | 2020-12-12 00:11:58 +0100 |
---|---|---|
committer | Tudor Brindus <me@tbrindus.ca> | 2021-02-25 09:48:39 -0500 |
commit | 1afedcb94c0517b5434e2220e63b997cf01427bd (patch) | |
tree | 3fae6d855a165e7364540a1474508caa8ae1b708 | |
parent | c6e7cf1ae554f36e5120962ace779737827ad088 (diff) |
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.h | 2 | ||||
-rw-r--r-- | sway/commands.c | 23 | ||||
-rw-r--r-- | sway/commands/scratchpad.c | 9 | ||||
-rw-r--r-- | sway/commands/unmark.c | 2 |
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 { struct sway_node *node; struct sway_container *container; struct sway_workspace *workspace; - bool using_criteria; + bool node_overridden; // True if the node is selected by means other than focus struct { int argc; 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) { handlers, sizeof(handlers)); } -static void set_config_node(struct sway_node *node) { +static void set_config_node(struct sway_node *node, bool node_overridden) { config->handler_context.node = node; config->handler_context.container = NULL; config->handler_context.workspace = NULL; + config->handler_context.node_overridden = node_overridden; if (node == NULL) { return; @@ -202,6 +203,7 @@ list_t *execute_command(char *_exec, struct sway_seat *seat, char *cmd; char matched_delim = ';'; list_t *containers = NULL; + bool using_criteria = false; if (seat == NULL) { // 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, for (; isspace(*head); ++head) {} // Extract criteria (valid for this command list only). if (matched_delim == ';') { - config->handler_context.using_criteria = false; + using_criteria = false; if (*head == '[') { char *error = NULL; struct criteria *criteria = criteria_parse(head, &error); @@ -239,7 +241,7 @@ list_t *execute_command(char *_exec, struct sway_seat *seat, containers = criteria_get_containers(criteria); head += strlen(criteria->raw); criteria_destroy(criteria); - config->handler_context.using_criteria = true; + using_criteria = true; // Skip leading whitespace for (; isspace(*head); ++head) {} } @@ -278,11 +280,14 @@ list_t *execute_command(char *_exec, struct sway_seat *seat, argv[i] = do_var_replacement(argv[i]); } - if (!config->handler_context.using_criteria) { - // The container or workspace which this command will run on. - struct sway_node *node = con ? &con->node : - seat_get_focus_inactive(seat, &root->node); - set_config_node(node); + + if (!using_criteria) { + if (con) { + set_config_node(&con->node, true); + } else { + set_config_node(seat_get_focus_inactive(seat, &root->node), + false); + } struct cmd_results *res = handler->handle(argc-1, argv+1); list_add(res_list, res); if (res->status == CMD_INVALID) { @@ -296,7 +301,7 @@ list_t *execute_command(char *_exec, struct sway_seat *seat, struct cmd_results *fail_res = NULL; for (int i = 0; i < containers->length; ++i) { struct sway_container *container = containers->items[i]; - set_config_node(&container->node); + set_config_node(&container->node, true); struct cmd_results *res = handler->handle(argc-1, argv+1); if (res->status == CMD_SUCCESS) { 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) { return cmd_results_new(CMD_INVALID, "Scratchpad is empty"); } - if (config->handler_context.using_criteria) { + if (config->handler_context.node_overridden) { struct sway_container *con = config->handler_context.container; // If the container is in a floating split container, // operate on the split container instead of the child. - if (container_is_floating_or_child(con)) { + if (con && container_is_floating_or_child(con)) { while (con->pending.parent) { con = con->pending.parent; } @@ -118,8 +118,9 @@ struct cmd_results *cmd_scratchpad(int argc, char **argv) { // If using criteria, this command is executed for every container which // matches the criteria. If this container isn't in the scratchpad, - // we'll just silently return a success. - if (!con->scratchpad) { + // we'll just silently return a success. The same is true if the + // overridden node is not a container. + if (!con || !con->scratchpad) { return cmd_results_new(CMD_SUCCESS, NULL); } 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) { struct cmd_results *cmd_unmark(int argc, char **argv) { // Determine the container struct sway_container *con = NULL; - if (config->handler_context.using_criteria) { + if (config->handler_context.node_overridden) { con = config->handler_context.container; } |