diff --git a/README.md b/README.md index 7574a9a..ee8e26e 100644 --- a/README.md +++ b/README.md @@ -173,7 +173,7 @@ The following messages are handled: - `balance` — Adjust the split ratios so that all windows occupy the same area. -- `rule PATTERN [DESKTOP_NAME] [floating]` — Create a new rule (`PATTERN` must match the class or instance name). +- `rule PATTERN [DESKTOP_NAME] [floating] [follow]` — Create a new rule (`PATTERN` must match the class or instance name). - `remove_rule UID ...` — Remove the rules with the given UIDs. diff --git a/bspwm.1 b/bspwm.1 index 1af0f37..6963394 100644 --- a/bspwm.1 +++ b/bspwm.1 @@ -248,7 +248,7 @@ Flip the window tree. .B balance Adjust the split ratios so that all windows occupy the same area. .TP -.BI rule " PATTERN [DESKTOP_NAME] [floating]" +.BI rule " PATTERN [DESKTOP_NAME] [floating] [follow]" Create a new rule (PATTERN must match the class or instance name). .TP .BI remove_rule " UID ..." diff --git a/messages.c b/messages.c index 285702d..7f3bd8c 100644 --- a/messages.c +++ b/messages.c @@ -367,6 +367,8 @@ void process_message(char *msg, char *rsp) while (arg != NULL) { if (strcmp(arg, "floating") == 0) { rule->effect.floating = true; + } else if (strcmp(arg, "follow") == 0) { + rule->effect.follow = true; } else { desktop_location_t loc; if (locate_desktop(arg, &loc)) { diff --git a/rules.c b/rules.c index f53ea3f..2762f29 100644 --- a/rules.c +++ b/rules.c @@ -60,7 +60,7 @@ bool is_match(rule_t *r, xcb_window_t win) return false; } -void handle_rules(xcb_window_t win, monitor_t **m, desktop_t **d, bool *floating, bool *transient, bool *fullscreen, bool *takes_focus, bool *manage) +void handle_rules(xcb_window_t win, monitor_t **m, desktop_t **d, bool *floating, bool *follow, bool *transient, bool *fullscreen, bool *takes_focus, bool *manage) { xcb_ewmh_get_atoms_reply_t win_type; @@ -113,6 +113,8 @@ void handle_rules(xcb_window_t win, monitor_t **m, desktop_t **d, bool *floating rule_effect_t efc = rule->effect; if (efc.floating) *floating = true; + if (efc.follow) + *follow = true; if (efc.monitor != NULL && efc.desktop != NULL) { *m = efc.monitor; *d = efc.desktop; @@ -127,7 +129,7 @@ void list_rules(char *rsp) char line[MAXLEN]; for (rule_t *r = rule_head; r != NULL; r = r->next) { - snprintf(line, sizeof(line), "%02X %s %s %s\n", r->uid, r->cause.name, (r->effect.desktop != NULL ? r->effect.desktop->name : "\b"), (r->effect.floating ? "floating" : "\b")); + snprintf(line, sizeof(line), "%2X %s %s %s %s\n", r->uid, r->cause.name, (r->effect.desktop != NULL ? r->effect.desktop->name : "\b"), (r->effect.floating ? "floating" : "\b"), (r->effect.follow ? "follow" : "\b")); strncat(rsp, line, REMLEN(rsp)); } } diff --git a/rules.h b/rules.h index 682d625..a003ecd 100644 --- a/rules.h +++ b/rules.h @@ -6,7 +6,7 @@ void remove_rule(rule_t *); void remove_rule_by_uid(unsigned int); rule_t *find_rule(unsigned int); bool is_match(rule_t *, xcb_window_t); -void handle_rules(xcb_window_t, monitor_t **, desktop_t **, bool *, bool *, bool *, bool *, bool *); +void handle_rules(xcb_window_t, monitor_t **, desktop_t **, bool *, bool *, bool *, bool *, bool *, bool *); void list_rules(char *); #endif diff --git a/types.c b/types.c index 9d5eafe..250785d 100644 --- a/types.c +++ b/types.c @@ -144,6 +144,7 @@ rule_t *make_rule(void) rule_t *r = malloc(sizeof(rule_t)); r->uid = ++rule_uid; r->effect.floating = false; + r->effect.follow = false; r->effect.monitor = NULL; r->effect.desktop = NULL; r->prev = NULL; diff --git a/types.h b/types.h index 6e00d7d..7b59f1c 100644 --- a/types.h +++ b/types.h @@ -175,6 +175,7 @@ typedef struct { typedef struct { bool floating; + bool follow; monitor_t *monitor; desktop_t *desktop; } rule_effect_t; diff --git a/window.c b/window.c index c2fc838..0734b63 100644 --- a/window.c +++ b/window.c @@ -96,9 +96,9 @@ void manage_window(monitor_t *m, desktop_t *d, xcb_window_t win) if (override_redirect || locate_window(win, &loc)) return; - bool floating = false, transient = false, fullscreen = false, takes_focus = true, manage = true; + bool floating = false, follow = false, transient = false, fullscreen = false, takes_focus = true, manage = true; - handle_rules(win, &m, &d, &floating, &transient, &fullscreen, &takes_focus, &manage); + handle_rules(win, &m, &d, &floating, &follow, &transient, &fullscreen, &takes_focus, &manage); if (!manage) { disable_shadow(win); @@ -162,6 +162,11 @@ void manage_window(monitor_t *m, desktop_t *d, xcb_window_t win) uint32_t values[] = {(focus_follows_pointer ? CLIENT_EVENT_MASK_FFP : CLIENT_EVENT_MASK)}; xcb_change_window_attributes(dpy, c->window, XCB_CW_EVENT_MASK, values); + if (follow) { + select_monitor(m); + select_desktop(d); + } + num_clients++; ewmh_set_wm_desktop(birth, d); ewmh_update_client_list();