Skip to content

Commit

Permalink
#2123 allow rules to only apply once
Browse files Browse the repository at this point in the history
  • Loading branch information
koekeishiya committed Feb 26, 2024
1 parent f5035ab commit 26e9bd8
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 38 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Make space visible on display without stealing focus (the space must belong to the display) [#2113](https://github.com/koekeishiya/yabai/issues/2113)
- Allow re-applying existing rules to all known windows [#2121](https://github.com/koekeishiya/yabai/issues/2121)
- Restore application_activated and application_deactivated signals [#2122](https://github.com/koekeishiya/yabai/issues/2122)
- Rules can now be configured to apply *only once* for all known windows [#2123](https://github.com/koekeishiya/yabai/issues/2123)

### Changed
- Preserve relative space ordering when moving spaces to other displays [#2114](https://github.com/koekeishiya/yabai/issues/2114)
Expand Down
4 changes: 2 additions & 2 deletions doc/yabai.1
Original file line number Diff line number Diff line change
Expand Up @@ -695,9 +695,9 @@ The following properties require System Integrity Protection to be partially dis
yabai \-m rule \fI<COMMAND>\fP
.SS "COMMAND"
.sp
\fB\-\-add [\fI<ARGUMENT>\fP]\fP
\fB\-\-add [\-\-one\-shot] [\fI<ARGUMENT>\fP]\fP
.RS 4
Add a new rule.
Add a new rule. If \fI\-\-one\-shot\fP is present, only apply once to all known windows.
.RE
.sp
\fB\-\-remove \fI<RULE_SEL>\fP\fP
Expand Down
4 changes: 2 additions & 2 deletions doc/yabai.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -510,8 +510,8 @@ yabai -m rule '<COMMAND>'
COMMAND
^^^^^^^

*--add ['<ARGUMENT>']*::
Add a new rule.
*--add [--one-shot] ['<ARGUMENT>']*::
Add a new rule. If '--one-shot' is present, only apply once to all known windows.

*--remove '<RULE_SEL>'*::
Remove an existing rule with the given index or label.
Expand Down
12 changes: 11 additions & 1 deletion src/message.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ extern bool g_verbose;
#define COMMAND_RULE_REAPPLY "--reapply"
#define COMMAND_RULE_LS "--list"

#define ARGUMENT_RULE_ONE_SHOT "--one-shot"
#define ARGUMENT_RULE_KEY_APP "app"
#define ARGUMENT_RULE_KEY_TITLE "title"
#define ARGUMENT_RULE_KEY_ROLE "role"
Expand Down Expand Up @@ -2214,9 +2215,15 @@ static void handle_domain_rule(FILE *rsp, struct token domain, char *message)
char *unsupported_exclusion = NULL;
bool did_parse = true;
bool has_filter = false;
bool one_shot = false;
struct rule rule = {};

struct token token = get_token(&message);
if (token_equals(token, ARGUMENT_RULE_ONE_SHOT)) {
one_shot = true;
token = get_token(&message);
}

while (token_is_valid(token)) {
char *key = NULL;
char *value = NULL;
Expand Down Expand Up @@ -2391,8 +2398,11 @@ static void handle_domain_rule(FILE *rsp, struct token domain, char *message)
did_parse = false;
}

if (did_parse) {
if (did_parse && !one_shot) {
rule_add(&rule);
} else if (did_parse && one_shot) {
rule_apply(&rule);
rule_destroy(&rule);
} else {
rule_destroy(&rule);
}
Expand Down
64 changes: 32 additions & 32 deletions src/rule.c
Original file line number Diff line number Diff line change
@@ -1,31 +1,6 @@
extern struct space_manager g_space_manager;
extern struct window_manager g_window_manager;

static void rule_apply(struct rule *rule)
{
for (int window_index = 0; window_index < g_window_manager.window.capacity; ++window_index) {
struct bucket *bucket = g_window_manager.window.buckets[window_index];
while (bucket) {
if (bucket->value) {
struct window *window = bucket->value;
if (window->is_root) {
char *window_title = window_title_ts(window);
char *window_role = window_role_ts(window);
char *window_subrole = window_subrole_ts(window);
window_manager_apply_manage_rule_to_window(&g_space_manager, &g_window_manager, window, rule, window_title, window_role, window_subrole);

if (window_manager_is_window_eligible(window)) {
window->is_eligible = true;
window_manager_apply_rule_to_window(&g_space_manager, &g_window_manager, window, rule, window_title, window_role, window_subrole);
}
}
}

bucket = bucket->next;
}
}
}

void rule_serialize(FILE *rsp, struct rule *rule, int index)
{
fprintf(rsp,
Expand Down Expand Up @@ -98,6 +73,38 @@ bool rule_reapply_by_label(char *label)
return false;
}

void rule_apply(struct rule *rule)
{
for (int window_index = 0; window_index < g_window_manager.window.capacity; ++window_index) {
struct bucket *bucket = g_window_manager.window.buckets[window_index];
while (bucket) {
if (bucket->value) {
struct window *window = bucket->value;
if (window->is_root) {
char *window_title = window_title_ts(window);
char *window_role = window_role_ts(window);
char *window_subrole = window_subrole_ts(window);
window_manager_apply_manage_rule_to_window(&g_space_manager, &g_window_manager, window, rule, window_title, window_role, window_subrole);

if (window_manager_is_window_eligible(window)) {
window->is_eligible = true;
window_manager_apply_rule_to_window(&g_space_manager, &g_window_manager, window, rule, window_title, window_role, window_subrole);
}
}
}

bucket = bucket->next;
}
}
}

void rule_add(struct rule *rule)
{
if (rule->label) rule_remove_by_label(rule->label);
buf_push(g_window_manager.rules, *rule);
rule_apply(rule);
}

bool rule_remove_by_index(int index)
{
for (int i = 0; i < buf_len(g_window_manager.rules); ++i) {
Expand All @@ -124,13 +131,6 @@ bool rule_remove_by_label(char *label)
return false;
}

void rule_add(struct rule *rule)
{
if (rule->label) rule_remove_by_label(rule->label);
buf_push(g_window_manager.rules, *rule);
rule_apply(rule);
}

void rule_destroy(struct rule *rule)
{
if (rule->app_regex_valid) regfree(&rule->app_regex);
Expand Down
3 changes: 2 additions & 1 deletion src/rule.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@ void rule_serialize(FILE *rsp, struct rule *rule, int index);
void rule_reapply_all(void);
bool rule_reapply_by_index(int index);
bool rule_reapply_by_label(char *label);
void rule_apply(struct rule *rule);
void rule_add(struct rule *rule);
bool rule_remove_by_index(int index);
bool rule_remove_by_label(char *label);
void rule_add(struct rule *rule);
void rule_destroy(struct rule *rule);

#endif

0 comments on commit 26e9bd8

Please sign in to comment.