From 7562ca735641691e8aa04c1330eab63ca1ff4988 Mon Sep 17 00:00:00 2001 From: lilly-lizard Date: Tue, 7 Apr 2026 06:49:51 +1200 Subject: [PATCH 1/7] silent varients of tag assignment commands --- src/config/parse_config.h | 13 ++++++++++ src/dispatch/bind_declare.h | 3 +++ src/dispatch/bind_define.h | 50 ++++++++++++++++++++++++++++++------- 3 files changed, 57 insertions(+), 9 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 830d22ba..a07c2034 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -957,9 +957,15 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value, } else if (strcmp(func_name, "tagtoleft") == 0) { func = tagtoleft; (*arg).i = atoi(arg_value); + } else if (strcmp(func_name, "tagtoleftsilent") == 0) { + func = tagtoleftsilent; + (*arg).i = atoi(arg_value); } else if (strcmp(func_name, "tagtoright") == 0) { func = tagtoright; (*arg).i = atoi(arg_value); + } else if (strcmp(func_name, "tagtorightsilent") == 0) { + func = tagtorightsilent; + (*arg).i = atoi(arg_value); } else if (strcmp(func_name, "killclient") == 0) { func = killclient; } else if (strcmp(func_name, "centerwin") == 0) { @@ -1052,6 +1058,13 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value, if ((*arg).i == UNDIR) { (*arg).v = strdup(arg_value); }; + } else if (strcmp(func_name, "tagmonsilent") == 0) { + func = tagmonsilent; + (*arg).i = parse_direction(arg_value); + (*arg).i2 = atoi(arg_value2); + if ((*arg).i == UNDIR) { + (*arg).v = strdup(arg_value); + }; } else if (strcmp(func_name, "incgaps") == 0) { func = incgaps; (*arg).i = atoi(arg_value); diff --git a/src/dispatch/bind_declare.h b/src/dispatch/bind_declare.h index 22ef6123..fc0fa2de 100644 --- a/src/dispatch/bind_declare.h +++ b/src/dispatch/bind_declare.h @@ -8,7 +8,9 @@ int32_t switch_proportion_preset(const Arg *arg); int32_t zoom(const Arg *arg); int32_t tagsilent(const Arg *arg); int32_t tagtoleft(const Arg *arg); +int32_t tagtoleftsilent(const Arg *arg); int32_t tagtoright(const Arg *arg); +int32_t tagtorightsilent(const Arg *arg); int32_t tagcrossmon(const Arg *arg); int32_t viewtoleft(const Arg *arg); int32_t viewtoright(const Arg *arg); @@ -20,6 +22,7 @@ int32_t togglefullscreen(const Arg *arg); int32_t togglemaximizescreen(const Arg *arg); int32_t togglegaps(const Arg *arg); int32_t tagmon(const Arg *arg); +int32_t tagmonsilent(const Arg *arg); int32_t spawn(const Arg *arg); int32_t spawn_shell(const Arg *arg); int32_t spawn_on_empty(const Arg *arg); diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index bd065141..d7725425 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -1044,6 +1044,14 @@ int32_t tag(const Arg *arg) { } int32_t tagmon(const Arg *arg) { + tagmon_general(arg, false); +} + +int32_t tagmonsilent(const Arg *arg) { + tagmon_general(arg, true); +} + +int32_t tagmon_general(const Arg *arg, bool silent) { Monitor *m = NULL, *cm = NULL; Client *c = focustop(selmon); @@ -1073,7 +1081,9 @@ int32_t tagmon(const Arg *arg) { uint32_t target; if (c->mon == m) { - view(&(Arg){.ui = newtags}, true); + if (!silent) { + view(&(Arg){.ui = newtags}, true); + } return 0; } @@ -1081,7 +1091,7 @@ int32_t tagmon(const Arg *arg) { selmon->sel = NULL; } - setmon(c, m, newtags, true); + setmon(c, m, newtags, !silent); // todo silent, last arg = false client_update_oldmonname_record(c, m); reset_foreign_tolevel(c); @@ -1097,18 +1107,22 @@ int32_t tagmon(const Arg *arg) { // 重新计算居中的坐标 if (c->isfloating) { c->geom = c->float_geom; - target = get_tags_first_tag(c->tags); - view(&(Arg){.ui = target}, true); - focusclient(c, 1); + if (!silent) { + target = get_tags_first_tag(c->tags); + view(&(Arg){.ui = target}, true); + focusclient(c, 1); + } resize(c, c->geom, 1); } else { selmon = c->mon; - target = get_tags_first_tag(c->tags); - view(&(Arg){.ui = target}, true); - focusclient(c, 1); + if (!silent) { + target = get_tags_first_tag(c->tags); + view(&(Arg){.ui = target}, true); + focusclient(c, 1); + } arrange(selmon, false, false); } - if (warpcursor) { + if (warpcursor && !silent) { warp_cursor_to_selmon(c->mon); } return 0; @@ -1144,6 +1158,15 @@ int32_t tagtoleft(const Arg *arg) { return 0; } +int32_t tagtoleftsilent(const Arg *arg) { + if (selmon->sel != NULL && + __builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 && + selmon->tagset[selmon->seltags] > 1) { + tagsilent(&(Arg){.ui = selmon->tagset[selmon->seltags] >> 1, .i = arg->i}); + } + return 0; +} + int32_t tagtoright(const Arg *arg) { if (selmon->sel != NULL && __builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 && @@ -1153,6 +1176,15 @@ int32_t tagtoright(const Arg *arg) { return 0; } +int32_t tagtorightsilent(const Arg *arg) { + if (selmon->sel != NULL && + __builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 && + selmon->tagset[selmon->seltags] & (TAGMASK >> 1)) { + tagsilent(&(Arg){.ui = selmon->tagset[selmon->seltags] << 1, .i = arg->i}); + } + return 0; +} + int32_t toggle_named_scratchpad(const Arg *arg) { Client *target_client = NULL; char *arg_id = arg->v; From 1a86dc804b4f7f5ab0802a8eec5425539f5bbbe3 Mon Sep 17 00:00:00 2001 From: lilly-lizard Date: Tue, 14 Apr 2026 08:20:14 +1200 Subject: [PATCH 2/7] view to left/right wrap around --- src/dispatch/bind_define.h | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 764aa51f..8971c07e 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -1099,14 +1099,6 @@ int32_t tag(const Arg *arg) { return 0; } -int32_t tagmon(const Arg *arg) { - tagmon_general(arg, false); -} - -int32_t tagmonsilent(const Arg *arg) { - tagmon_general(arg, true); -} - int32_t tagmon_general(const Arg *arg, bool silent) { Monitor *m = NULL, *cm = NULL; if (!selmon) @@ -1154,6 +1146,10 @@ int32_t tagmon_general(const Arg *arg, bool silent) { reset_foreign_tolevel(c); + if (silent) { + focusclient(focustop(selmon), 1); + } + c->float_geom.width = (int32_t)(c->float_geom.width * c->mon->w.width / selmon->w.width); c->float_geom.height = @@ -1172,7 +1168,6 @@ int32_t tagmon_general(const Arg *arg, bool silent) { } resize(c, c->geom, 1); } else { - selmon = c->mon; if (!silent) { target = get_tags_first_tag(c->tags); view(&(Arg){.ui = target}, true); @@ -1183,9 +1178,18 @@ int32_t tagmon_general(const Arg *arg, bool silent) { if (config.warpcursor && !silent) { warp_cursor_to_selmon(c->mon); } + return 0; } +int32_t tagmon(const Arg *arg) { + return tagmon_general(arg, false); +} + +int32_t tagmonsilent(const Arg *arg) { + return tagmon_general(arg, true); +} + int32_t tagsilent(const Arg *arg) { Client *fc = NULL; Client *target_client = NULL; @@ -1489,12 +1493,15 @@ int32_t viewtoleft(const Arg *arg) { if (!selmon) return 0; - uint32_t target = selmon->tagset[selmon->seltags]; - if (selmon->isoverview || selmon->pertag->curtag == 0) { return 0; } + uint32_t target = selmon->tagset[selmon->seltags]; + if (target & 1) { + // 1 wraps around to 9 + target |= 1 << LENGTH(tags); + } target >>= 1; if (target == 0) { @@ -1516,12 +1523,17 @@ int32_t viewtoright(const Arg *arg) { return 0; } uint32_t target = selmon->tagset[selmon->seltags]; + target <<= 1; + if (target & 1 << LENGTH(tags)) { + // 9 wraps around to 1 + target |= 1; + } if (!selmon || (target) == selmon->tagset[selmon->seltags]) return 0; if (!(target & TAGMASK)) { - return 0; + target = 1; } view(&(Arg){.ui = target & TAGMASK, .i = arg->i}, true); From cd83239be41f75493130a7a128abc5c8f433d004 Mon Sep 17 00:00:00 2001 From: lilly-lizard Date: Tue, 14 Apr 2026 13:51:16 +1200 Subject: [PATCH 3/7] tag to left/right wrap around --- src/dispatch/bind_define.h | 62 ++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 8971c07e..965bddec 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -1211,46 +1211,64 @@ int32_t tagsilent(const Arg *arg) { return 0; } -int32_t tagtoleft(const Arg *arg) { +int32_t tagtoleft_general(const Arg *arg, bool silent) { if (!selmon) return 0; if (selmon->sel != NULL && - __builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 && - selmon->tagset[selmon->seltags] > 1) { - tag(&(Arg){.ui = selmon->tagset[selmon->seltags] >> 1, .i = arg->i}); + __builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1) { + + uint32_t target = selmon->tagset[selmon->seltags]; + if (target & 1) { + // 1 wraps around to 9 + target |= 1 << LENGTH(tags); + } + target >>= 1; + + if (silent) + tagsilent(&(Arg){.ui = target, .i = arg->i}); + else + tag(&(Arg){.ui = target, .i = arg->i}); } return 0; } +int32_t tagtoleft(const Arg *arg) { + return tagtoleft_general(arg, false); +} + int32_t tagtoleftsilent(const Arg *arg) { + return tagtoleft_general(arg, true); +} + +int32_t tagtoright_general(const Arg *arg, bool silent) { + if (!selmon) + return 0; + if (selmon->sel != NULL && - __builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 && - selmon->tagset[selmon->seltags] > 1) { - tagsilent(&(Arg){.ui = selmon->tagset[selmon->seltags] >> 1, .i = arg->i}); + __builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1) { + + uint32_t target = selmon->tagset[selmon->seltags]; + target <<= 1; + if (target & 1 << LENGTH(tags)) { + // 9 wraps around to 1 + target |= 1; + } + + if (silent) + tagsilent(&(Arg){.ui = target, .i = arg->i}); + else + tag(&(Arg){.ui = target, .i = arg->i}); } return 0; } int32_t tagtoright(const Arg *arg) { - if (!selmon) - return 0; - - if (selmon->sel != NULL && - __builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 && - selmon->tagset[selmon->seltags] & (TAGMASK >> 1)) { - tag(&(Arg){.ui = selmon->tagset[selmon->seltags] << 1, .i = arg->i}); - } - return 0; + return tagtoright_general(arg, false); } int32_t tagtorightsilent(const Arg *arg) { - if (selmon->sel != NULL && - __builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 && - selmon->tagset[selmon->seltags] & (TAGMASK >> 1)) { - tagsilent(&(Arg){.ui = selmon->tagset[selmon->seltags] << 1, .i = arg->i}); - } - return 0; + return tagtoright_general(arg, true); } int32_t toggle_named_scratchpad(const Arg *arg) { From def7376912c2dbf01ee0ce59395ef656fe35648a Mon Sep 17 00:00:00 2001 From: lilly-lizard Date: Tue, 14 Apr 2026 14:32:17 +1200 Subject: [PATCH 4/7] removed tagmonsilent (haven't figured out how to do this right yet) --- src/dispatch/bind_declare.h | 1 - src/dispatch/bind_define.h | 40 ++++++++++--------------------------- 2 files changed, 11 insertions(+), 30 deletions(-) diff --git a/src/dispatch/bind_declare.h b/src/dispatch/bind_declare.h index d1476595..82993861 100644 --- a/src/dispatch/bind_declare.h +++ b/src/dispatch/bind_declare.h @@ -22,7 +22,6 @@ int32_t togglefullscreen(const Arg *arg); int32_t togglemaximizescreen(const Arg *arg); int32_t togglegaps(const Arg *arg); int32_t tagmon(const Arg *arg); -int32_t tagmonsilent(const Arg *arg); int32_t spawn(const Arg *arg); int32_t spawn_shell(const Arg *arg); int32_t spawn_on_empty(const Arg *arg); diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 965bddec..1bd68436 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -1099,7 +1099,7 @@ int32_t tag(const Arg *arg) { return 0; } -int32_t tagmon_general(const Arg *arg, bool silent) { +int32_t tagmon(const Arg *arg) { Monitor *m = NULL, *cm = NULL; if (!selmon) return 0; @@ -1131,9 +1131,7 @@ int32_t tagmon_general(const Arg *arg, bool silent) { uint32_t target; if (c->mon == m) { - if (!silent) { - view(&(Arg){.ui = newtags}, true); - } + view(&(Arg){.ui = newtags}, true); return 0; } @@ -1141,15 +1139,11 @@ int32_t tagmon_general(const Arg *arg, bool silent) { selmon->sel = NULL; } - setmon(c, m, newtags, !silent); + setmon(c, m, newtags, true); client_update_oldmonname_record(c, m); reset_foreign_tolevel(c); - if (silent) { - focusclient(focustop(selmon), 1); - } - c->float_geom.width = (int32_t)(c->float_geom.width * c->mon->w.width / selmon->w.width); c->float_geom.height = @@ -1161,35 +1155,23 @@ int32_t tagmon_general(const Arg *arg, bool silent) { // 重新计算居中的坐标 if (c->isfloating) { c->geom = c->float_geom; - if (!silent) { - target = get_tags_first_tag(c->tags); - view(&(Arg){.ui = target}, true); - focusclient(c, 1); - } + target = get_tags_first_tag(c->tags); + view(&(Arg){.ui = target}, true); + focusclient(c, 1); resize(c, c->geom, 1); } else { - if (!silent) { - target = get_tags_first_tag(c->tags); - view(&(Arg){.ui = target}, true); - focusclient(c, 1); - } + selmon = c->mon; + target = get_tags_first_tag(c->tags); + view(&(Arg){.ui = target}, true); + focusclient(c, 1); arrange(selmon, false, false); } - if (config.warpcursor && !silent) { + if (config.warpcursor) { warp_cursor_to_selmon(c->mon); } - return 0; } -int32_t tagmon(const Arg *arg) { - return tagmon_general(arg, false); -} - -int32_t tagmonsilent(const Arg *arg) { - return tagmon_general(arg, true); -} - int32_t tagsilent(const Arg *arg) { Client *fc = NULL; Client *target_client = NULL; From 9764e905125d19d576b4530fed86fe494334ffe2 Mon Sep 17 00:00:00 2001 From: lilly-lizard Date: Tue, 14 Apr 2026 14:32:56 +1200 Subject: [PATCH 5/7] removed tagmonsilent --- src/config/parse_config.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index a8aab8d2..bb75c0d7 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -1079,13 +1079,6 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value, if ((*arg).i == UNDIR) { (*arg).v = strdup(arg_value); }; - } else if (strcmp(func_name, "tagmonsilent") == 0) { - func = tagmonsilent; - (*arg).i = parse_direction(arg_value); - (*arg).i2 = atoi(arg_value2); - if ((*arg).i == UNDIR) { - (*arg).v = strdup(arg_value); - }; } else if (strcmp(func_name, "incgaps") == 0) { func = incgaps; (*arg).i = atoi(arg_value); From e3f30ca065b851772cc04ef9eb7226bf701f0fa5 Mon Sep 17 00:00:00 2001 From: lilly-lizard Date: Sun, 19 Apr 2026 10:03:11 +1200 Subject: [PATCH 6/7] added docs for tagtoleftsilent and tagtorightsilent --- docs/bindings/keys.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/bindings/keys.md b/docs/bindings/keys.md index b3a4ab64..c1f67815 100644 --- a/docs/bindings/keys.md +++ b/docs/bindings/keys.md @@ -126,7 +126,9 @@ bindr=Super,Super_L,spawn,rofi -show run | `tag` | `1-9 [,synctag]` | Move window to tag. Optional `synctag` (0/1) syncs to all monitors. | | `tagsilent` | `1-9` | Move window to tag without focusing it. | | `tagtoleft` | `[synctag]` | Move window to left tag. Optional `synctag` (0/1). | +| `tagtoleftsilent` | `[synctag]` | Move window to left tag without focusing it. Optional `synctag` (0/1). | | `tagtoright` | `[synctag]` | Move window to right tag. Optional `synctag` (0/1). | +| `tagtorightsilent` | `[synctag]` | Move window to right tag without focusing it. Optional `synctag` (0/1). | | `tagcrossmon` | `tag,monitor_spec` | Move window to specified tag on specified monitor. | | `toggletag` | `0-9` | Toggle tag on window (0 means all tags). | | `toggleview` | `1-9` | Toggle tag view. | From 5f88f7f803097ca4b2fc3b41c61d1cae5a73c589 Mon Sep 17 00:00:00 2001 From: lilly-lizard Date: Wed, 22 Apr 2026 19:24:58 +1200 Subject: [PATCH 7/7] added tagtoside_general to reduce code duplication --- src/dispatch/bind_define.h | 49 ++++++++++++++------------------------ 1 file changed, 18 insertions(+), 31 deletions(-) diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 1bd68436..ae4fb4ff 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -1193,7 +1193,7 @@ int32_t tagsilent(const Arg *arg) { return 0; } -int32_t tagtoleft_general(const Arg *arg, bool silent) { +int32_t tagtoside_general(const Arg *arg, bool silent, bool left) { if (!selmon) return 0; @@ -1201,11 +1201,20 @@ int32_t tagtoleft_general(const Arg *arg, bool silent) { __builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1) { uint32_t target = selmon->tagset[selmon->seltags]; - if (target & 1) { - // 1 wraps around to 9 - target |= 1 << LENGTH(tags); + + if (left) { + if (target & 1) { + // 1 wraps around to 9 + target |= 1 << LENGTH(tags); + } + target >>= 1; + } else { + target <<= 1; + if (target & 1 << LENGTH(tags)) { + // 9 wraps around to 1 + target |= 1; + } } - target >>= 1; if (silent) tagsilent(&(Arg){.ui = target, .i = arg->i}); @@ -1216,41 +1225,19 @@ int32_t tagtoleft_general(const Arg *arg, bool silent) { } int32_t tagtoleft(const Arg *arg) { - return tagtoleft_general(arg, false); + return tagtoside_general(arg, false, true); } int32_t tagtoleftsilent(const Arg *arg) { - return tagtoleft_general(arg, true); -} - -int32_t tagtoright_general(const Arg *arg, bool silent) { - if (!selmon) - return 0; - - if (selmon->sel != NULL && - __builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1) { - - uint32_t target = selmon->tagset[selmon->seltags]; - target <<= 1; - if (target & 1 << LENGTH(tags)) { - // 9 wraps around to 1 - target |= 1; - } - - if (silent) - tagsilent(&(Arg){.ui = target, .i = arg->i}); - else - tag(&(Arg){.ui = target, .i = arg->i}); - } - return 0; + return tagtoside_general(arg, true, true); } int32_t tagtoright(const Arg *arg) { - return tagtoright_general(arg, false); + return tagtoside_general(arg, false, false); } int32_t tagtorightsilent(const Arg *arg) { - return tagtoright_general(arg, true); + return tagtoside_general(arg, true, false); } int32_t toggle_named_scratchpad(const Arg *arg) {