diff --git a/src/config.h b/src/config.h index 0a2d1b8..aff3817 100644 --- a/src/config.h +++ b/src/config.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -51,21 +52,31 @@ const layout_t layouts[] = { {"><>", NULL}, }; -/* 新建窗口规则,以 NULL 结束 */ +/* 默认 tags 规则 */ +const rule_tag_t browser_tag[] = { + {.monitor_amount = 1, .tags = 1 << 1}, + {0}, +}; +const rule_tag_t mpv_tag[] = { + {.monitor_amount = 1, .monitor_index = 0, .tags = 1 << 3}, + {.monitor_amount = 2, .monitor_index = 1, .tags = 1 << 2}, + {0}, +}; +const rule_tag_t emacs_tag[] = { + {.monitor_amount = 1, .monitor_index = 0, .tags = 1 << 2}, + {.monitor_amount = 2, .monitor_index = 0, .tags = 1 << 1}, + {0}, +}; +/* 新建窗口规则 */ const rule_t rules[] = { - /* client 固定规则 */ - {.class = "firefox", .maximize = true}, - {.class = "Google-chrome", .maximize = true}, - {.class = "mpv", .fullscreen = true}, - {.class = "Emacs", .switch_to_tag = true, .maximize = true}, - - /* client 默认 tag 规则 */ - {.class = "firefox", .monitor_index = 0, .tags = 1 << 1}, - {.class = "Google-chrome", .monitor_index = 0, .tags = 1 << 1}, - {.class = "mpv", .monitor_amount = 1, .monitor_index = 0, .tags = 1 << 3}, - {.class = "mpv", .monitor_amount = 2, .monitor_index = 1, .tags = 1 << 2}, - {.class = "Emacs", .monitor_amount = 1, .monitor_index = 0, .tags = 1 << 2}, - {.class = "Emacs", .monitor_amount = 2, .monitor_index = 0, .tags = 1 << 1}, + {.class = "firefox", .action = {.maximize = true}, .tag = browser_tag}, + {.class = "Google-chrome", .action = {.maximize = true}, .tag = browser_tag}, + {.class = "mpv", .action = {.fullscreen = true}, .tag = mpv_tag}, + { + .class = "Emacs", + .action = {.switch_to_tag = true, .maximize = true}, + .tag = emacs_tag, + }, }; #define SUPER XCB_MOD_MASK_4 diff --git a/src/include/types.h b/src/include/types.h index d0a113c..fdd9478 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -57,21 +57,26 @@ typedef struct wallpaper_config_t { char **path_list; } wallpaper_config_t; -typedef struct rule_t { - const char *class; - const char *instance; - const char *title; - - /* 规则适用的屏幕总数,若设置为 0 ,则此条规则适用于任意屏幕数 */ +/* 窗口默认屏幕和 tags */ +typedef struct rule_tag_t { const uint32_t monitor_amount; - - uint32_t tags; /* tags 必须设置为大于 0 才是有效设置 */ - uint32_t monitor_index; /* 仅当 tags 为有效设置时该设置才生效 */ - + uint32_t monitor_index; + uint32_t tags; +} rule_tag_t; +typedef struct rule_action_t { bool switch_to_tag; bool fullscreen; bool maximize; bool floating; +} rule_action_t; +/* 新建窗口规则 */ +typedef struct rule_t { + /* 规则匹配字段组 */ + const char *class; + const char *instance; + const char *title; + const rule_tag_t *tag; /* 默认所在屏幕和 tags 设置,以 {0} 结尾 */ + const rule_action_t action; } rule_t; typedef union user_action_arg_t { diff --git a/src/main.c b/src/main.c index e017729..8a592d5 100644 --- a/src/main.c +++ b/src/main.c @@ -145,6 +145,21 @@ static void print_client(client_t *c) { printf("name: %s\n", c->name); printf("===== client info end ======\n"); } +static void print_rule(const rule_t *r) { + printf("==================== rule ====================\n"); + printf("class: %s, instance: %s, title: %s\n", r->class, r->instance, + r->title); + printf("floating: %s, maximize: %s, fullscreen: %s, switch to tag: %s\n", + bool2string(r->action.floating), bool2string(r->action.maximize), + bool2string(r->action.fullscreen), + bool2string(r->action.switch_to_tag)); + for (uint32_t i = 0; r->tag && r->tag[i].monitor_amount; i++) { + const rule_tag_t *t = &r->tag[i]; + printf("monitor amount: %u, monitor index: %u, tags: %b\n", + t->monitor_amount, t->monitor_index, t->tags); + } + printf("================== rule end ==================\n"); +} /* 调试函数结束 */ void init_monitors(void) { @@ -533,35 +548,45 @@ void apply_rules(client_t *client) { window_class_instance_t class_instance; get_window_class_instance(client->window, &class_instance); - printf("class: %s, instance: %s\n", class_instance.class, - class_instance.instance); - bool switch_to_tag = 0; for (int i = 0; i < LENGTH(rules); i++) { const rule_t *r = &rules[i]; - if (!((!r->monitor_amount || monitor_amount == r->monitor_amount) && - (!r->title || strstr(client->name, r->title)) && + if (!((!r->title || strstr(client->name, r->title)) && (!r->class || strstr(class_instance.class, r->class)) && (!r->instance || strstr(class_instance.instance, r->instance)))) { continue; } - switch_to_tag = r->switch_to_tag; - client->fullscreen = r->fullscreen; - client->maximize = r->maximize; - client->floating = r->floating; + print_rule(r); - if (r->tags) { - monitor_t *m = monitors; - for (uint32_t i = 0; i < r->monitor_index; i++) m = m ? m->next : NULL; - if (!m) continue; - uint32_t tags_mask = 0; - for (uint32_t i = 0; m->tags[i]; i++) { - tags_mask |= 1 << 0; + switch_to_tag = r->action.switch_to_tag; + client->fullscreen = r->action.fullscreen; + client->maximize = r->action.maximize; + client->floating = r->action.floating; + + if (!r->tag) continue; + + const rule_tag_t *tag = NULL; + for (uint32_t i = 0;; i++) { + const rule_tag_t *t = &r->tag[i]; + if (!t->monitor_amount) break; + + if (t->monitor_amount == monitor_amount) { + tag = t; + break; } - client->tags = r->tags & tags_mask; + } + if (tag) { + monitor_t *m = monitors; + for (uint32_t i = 0; i < tag->monitor_index; i++) m = m ? m->next : NULL; + if (!m) continue; + + uint32_t tags_mask = 0; + for (uint32_t i = 0; m->tags[i]; i++) tags_mask |= (1 << i); + client->tags = tag->tags & tags_mask; } } + if (!client->tags) { client->monitor = current_monitor; client->tags = current_monitor->selected_tags; @@ -571,6 +596,7 @@ void apply_rules(client_t *client) { current_monitor->selected_tags = client->tags; } + print_client(client); printf("apply rules done\n"); } @@ -614,7 +640,6 @@ void apply_monitor_layout(monitor_t *monitor) { if (!monitor || !monitor->layout || !monitor->layout->arrange) return; monitor->layout->arrange(monitor); - print_client(monitor->clients); for (client_t *c = next_visible_client(monitor->clients); c; c = next_visible_client(c->next)) { printf("apply window[0x%x] rect: x: %d, y: %d, w: %u, h: %u, bw: %u\n",