aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2017-04-26 15:29:42 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2017-04-26 15:29:42 -0400
commit51143a75afe284d6c08e8a52516cba6afe834ac0 (patch)
tree33d37bb6aeb26d7db7c59a444cd72b95be35b3c8
parentMerge pull request #1194 from snoack/version (diff)
downloadsway-51143a75afe284d6c08e8a52516cba6afe834ac0.tar.gz
sway-51143a75afe284d6c08e8a52516cba6afe834ac0.tar.zst
sway-51143a75afe284d6c08e8a52516cba6afe834ac0.zip
Implement no_focus
Ref #2
-rw-r--r--include/sway/commands.h1
-rw-r--r--include/sway/config.h1
-rw-r--r--include/sway/criteria.h3
-rw-r--r--sway/commands.c1
-rw-r--r--sway/commands/no_focus.c41
-rw-r--r--sway/config.c6
-rw-r--r--sway/criteria.c10
-rw-r--r--sway/handlers.c12
8 files changed, 72 insertions, 3 deletions
diff --git a/include/sway/commands.h b/include/sway/commands.h
index 91f2ae01..078652e7 100644
--- a/include/sway/commands.h
+++ b/include/sway/commands.h
@@ -135,6 +135,7 @@ sway_cmd cmd_mouse_warping;
135sway_cmd cmd_move; 135sway_cmd cmd_move;
136sway_cmd cmd_new_float; 136sway_cmd cmd_new_float;
137sway_cmd cmd_new_window; 137sway_cmd cmd_new_window;
138sway_cmd cmd_no_focus;
138sway_cmd cmd_orientation; 139sway_cmd cmd_orientation;
139sway_cmd cmd_output; 140sway_cmd cmd_output;
140sway_cmd cmd_permit; 141sway_cmd cmd_permit;
diff --git a/include/sway/config.h b/include/sway/config.h
index 2de90434..35f8d5f7 100644
--- a/include/sway/config.h
+++ b/include/sway/config.h
@@ -250,6 +250,7 @@ struct sway_config {
250 list_t *output_configs; 250 list_t *output_configs;
251 list_t *input_configs; 251 list_t *input_configs;
252 list_t *criteria; 252 list_t *criteria;
253 list_t *no_focus;
253 list_t *active_bar_modifiers; 254 list_t *active_bar_modifiers;
254 struct sway_mode *current_mode; 255 struct sway_mode *current_mode;
255 struct bar_config *current_bar; 256 struct bar_config *current_bar;
diff --git a/include/sway/criteria.h b/include/sway/criteria.h
index 022c48a8..c5ed9857 100644
--- a/include/sway/criteria.h
+++ b/include/sway/criteria.h
@@ -36,4 +36,7 @@ list_t *criteria_for(swayc_t *cont);
36// Returns a list of all containers that match the given list of tokens. 36// Returns a list of all containers that match the given list of tokens.
37list_t *container_for(list_t *tokens); 37list_t *container_for(list_t *tokens);
38 38
39// Returns true if any criteria in the given list matches this container
40bool criteria_any(swayc_t *cont, list_t *criteria);
41
39#endif 42#endif
diff --git a/sway/commands.c b/sway/commands.c
index 4d7af301..01e5e6b5 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -198,6 +198,7 @@ static struct cmd_handler handlers[] = {
198 { "move", cmd_move }, 198 { "move", cmd_move },
199 { "new_float", cmd_new_float }, 199 { "new_float", cmd_new_float },
200 { "new_window", cmd_new_window }, 200 { "new_window", cmd_new_window },
201 { "no_focus", cmd_no_focus },
201 { "output", cmd_output }, 202 { "output", cmd_output },
202 { "permit", cmd_permit }, 203 { "permit", cmd_permit },
203 { "reject", cmd_reject }, 204 { "reject", cmd_reject },
diff --git a/sway/commands/no_focus.c b/sway/commands/no_focus.c
new file mode 100644
index 00000000..b3b88e5a
--- /dev/null
+++ b/sway/commands/no_focus.c
@@ -0,0 +1,41 @@
1#define _XOPEN_SOURCE 500
2#include <string.h>
3#include "sway/commands.h"
4#include "sway/criteria.h"
5#include "list.h"
6#include "log.h"
7#include "stringop.h"
8
9struct cmd_results *cmd_no_focus(int argc, char **argv) {
10 struct cmd_results *error = NULL;
11 if ((error = checkarg(argc, "no_focus", EXPECTED_EQUAL_TO, 1))) {
12 return error;
13 }
14 // add command to a criteria/command pair that is run against views when they appear.
15 char *criteria = argv[0];
16
17 struct criteria *crit = malloc(sizeof(struct criteria));
18 if (!crit) {
19 return cmd_results_new(CMD_FAILURE, "no_focus", "Unable to allocate criteria");
20 }
21 crit->crit_raw = strdup(criteria);
22 crit->tokens = create_list();
23 crit->cmdlist = NULL;
24 char *err_str = extract_crit_tokens(crit->tokens, crit->crit_raw);
25
26 if (err_str) {
27 error = cmd_results_new(CMD_INVALID, "no_focus", err_str);
28 free(err_str);
29 free_criteria(crit);
30 } else if (crit->tokens->length == 0) {
31 error = cmd_results_new(CMD_INVALID, "no_focus", "Found no name/value pairs in criteria");
32 free_criteria(crit);
33 } else if (list_seq_find(config->no_focus, criteria_cmp, crit) != -1) {
34 sway_log(L_DEBUG, "no_focus: Duplicate, skipping.");
35 free_criteria(crit);
36 } else {
37 sway_log(L_DEBUG, "no_focus: '%s' added", crit->crit_raw);
38 list_add(config->no_focus, crit);
39 }
40 return error ? error : cmd_results_new(CMD_SUCCESS, NULL, NULL);
41}
diff --git a/sway/config.c b/sway/config.c
index 0014b33a..19b1882f 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -249,6 +249,11 @@ void free_config(struct sway_config *config) {
249 } 249 }
250 list_free(config->criteria); 250 list_free(config->criteria);
251 251
252 for (i = 0; config->no_focus && i < config->no_focus->length; ++i) {
253 free_criteria(config->no_focus->items[i]);
254 }
255 list_free(config->no_focus);
256
252 for (i = 0; config->input_configs && i < config->input_configs->length; ++i) { 257 for (i = 0; config->input_configs && i < config->input_configs->length; ++i) {
253 free_input_config(config->input_configs->items[i]); 258 free_input_config(config->input_configs->items[i]);
254 } 259 }
@@ -291,6 +296,7 @@ static void config_defaults(struct sway_config *config) {
291 if (!(config->workspace_outputs = create_list())) goto cleanup; 296 if (!(config->workspace_outputs = create_list())) goto cleanup;
292 if (!(config->pid_workspaces = create_list())) goto cleanup; 297 if (!(config->pid_workspaces = create_list())) goto cleanup;
293 if (!(config->criteria = create_list())) goto cleanup; 298 if (!(config->criteria = create_list())) goto cleanup;
299 if (!(config->no_focus = create_list())) goto cleanup;
294 if (!(config->input_configs = create_list())) goto cleanup; 300 if (!(config->input_configs = create_list())) goto cleanup;
295 if (!(config->output_configs = create_list())) goto cleanup; 301 if (!(config->output_configs = create_list())) goto cleanup;
296 302
diff --git a/sway/criteria.c b/sway/criteria.c
index ee6d4d1c..1ea8311e 100644
--- a/sway/criteria.c
+++ b/sway/criteria.c
@@ -359,6 +359,16 @@ void free_criteria(struct criteria *crit) {
359 free(crit); 359 free(crit);
360} 360}
361 361
362bool criteria_any(swayc_t *cont, list_t *criteria) {
363 for (int i = 0; i < criteria->length; i++) {
364 struct criteria *bc = criteria->items[i];
365 if (criteria_test(cont, bc->tokens)) {
366 return true;
367 }
368 }
369 return false;
370}
371
362list_t *criteria_for(swayc_t *cont) { 372list_t *criteria_for(swayc_t *cont) {
363 list_t *criteria = config->criteria, *matches = create_list(); 373 list_t *criteria = config->criteria, *matches = create_list();
364 for (int i = 0; i < criteria->length; i++) { 374 for (int i = 0; i < criteria->length; i++) {
diff --git a/sway/handlers.c b/sway/handlers.c
index a8de135f..5e031321 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -390,8 +390,10 @@ static bool handle_view_created(wlc_handle handle) {
390 } 390 }
391 } 391 }
392 392
393 swayc_t *prev_focus = get_focused_container(&root_container);
394
393 if (!focused || focused->type == C_OUTPUT) { 395 if (!focused || focused->type == C_OUTPUT) {
394 focused = get_focused_container(&root_container); 396 focused = prev_focus;
395 // Move focus from floating view 397 // Move focus from floating view
396 if (focused->is_floating) { 398 if (focused->is_floating) {
397 // To workspace if there are no children 399 // To workspace if there are no children
@@ -458,7 +460,11 @@ static bool handle_view_created(wlc_handle handle) {
458 460
459 if (newview) { 461 if (newview) {
460 ipc_event_window(newview, "new"); 462 ipc_event_window(newview, "new");
461 set_focused_container(newview); 463 swayc_t *workspace = swayc_parent_by_type(newview, C_WORKSPACE);
464 if ((workspace && workspace->children->length == 1)
465 || !criteria_any(newview, config->no_focus)) {
466 set_focused_container(newview);
467 }
462 wlc_view_set_mask(handle, VISIBLE); 468 wlc_view_set_mask(handle, VISIBLE);
463 swayc_t *output = swayc_parent_by_type(newview, C_OUTPUT); 469 swayc_t *output = swayc_parent_by_type(newview, C_OUTPUT);
464 arrange_windows(output, -1, -1); 470 arrange_windows(output, -1, -1);
@@ -477,7 +483,7 @@ static bool handle_view_created(wlc_handle handle) {
477 // refocus in-between command lists 483 // refocus in-between command lists
478 set_focused_container(newview); 484 set_focused_container(newview);
479 } 485 }
480 swayc_t *workspace = swayc_parent_by_type(focused, C_WORKSPACE); 486 workspace = swayc_parent_by_type(focused, C_WORKSPACE);
481 if (workspace && workspace->fullscreen) { 487 if (workspace && workspace->fullscreen) {
482 set_focused_container(workspace->fullscreen); 488 set_focused_container(workspace->fullscreen);
483 } 489 }