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. | diff --git a/src/config/parse_config.h b/src/config/parse_config.h index e02b5017..bb75c0d7 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -978,9 +978,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) { diff --git a/src/dispatch/bind_declare.h b/src/dispatch/bind_declare.h index dbeebd33..82993861 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); diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index f5992e29..ae4fb4ff 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -1193,28 +1193,51 @@ int32_t tagsilent(const Arg *arg) { return 0; } -int32_t tagtoleft(const Arg *arg) { +int32_t tagtoside_general(const Arg *arg, bool silent, bool left) { 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 (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; + } + } + + 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; +int32_t tagtoleft(const Arg *arg) { + return tagtoside_general(arg, false, true); +} - 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; +int32_t tagtoleftsilent(const Arg *arg) { + return tagtoside_general(arg, true, true); +} + +int32_t tagtoright(const Arg *arg) { + return tagtoside_general(arg, false, false); +} + +int32_t tagtorightsilent(const Arg *arg) { + return tagtoside_general(arg, true, false); } int32_t toggle_named_scratchpad(const Arg *arg) { @@ -1457,12 +1480,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) { @@ -1484,12 +1510,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);