Skip to content

stacker

Bakkeby edited this page Apr 15, 2024 · 2 revisions

The stacker utilities provides comprehensive ways of managing the client stack.

It is based on the popular stacker patch for dwm considered by many to be the ultimate way to control windows using keyboard shortcuts.

The main difference between the dwm patch and the implementation in dusk is that in dwm both floating and tiled clients are selected based on the client stack index, whereas in dusk client selection is restricted to tiled clients only.

Client selection is also restricted to the current workspace.

The keybindings are defined in the STACKKEYS macro as the same keys are used with different modifiers to access different functionality.

#define STACKKEYS(MOD,ACTION) \
	{ KeyPress,   MOD, XK_j, ACTION, {.i = INC(+1) } }, \
	{ KeyPress,   MOD, XK_k, ACTION, {.i = INC(-1) } }, \
	{ KeyPress,   MOD, XK_s, ACTION, {.i = PREVSEL } }, \
	{ KeyPress,   MOD, XK_w, ACTION, {.i = 1 } }, \
	{ KeyPress,   MOD, XK_e, ACTION, {.i = 2 } }, \
	{ KeyPress,   MOD, XK_a, ACTION, {.i = 3 } }, \
	{ KeyPress,   MOD, XK_z, ACTION, {.i = LASTTILED } },

This macro can be expanded to hold shortcuts for more clients as needed.

Here is an explanation for the values passed to functions.

Argument Description
INC(+1) Next client relative to the selected client
INC(-1) Previous client relative to the selected client
PREVSEL The previously selected client
1 The first client in the stack (often the master client)
2 The second client in the stack (often the first stack client)
3 The third client in the stack (often the second stack client)
-1 The last client in the stack
LASTTILED The last client in the stack

1, 2 and 3 above refers to the nth tiled client, starting from 1. Note that the stacker patch for dwm used stack index and started from 0.

The nth client will also reduce if there are less tiled clients than the desired number. E.g. if there are only 2 tiled clients then focusing on 3 will change focus to the last tiled client (2).

-1 refers to the last tiled client in the stack. LASTTILED can be used as well to make things more readable.

PREVSEL refers to the previously selected client on the current workspace.

The STACKKEYS macro is used in the keys array, but is not enabled by default due to the number of keybindings that it consumes. Also it uses AltGr as an example and alternate modifier key to avoid keybinding conflicts.

//	STACKKEYS(AltGr|Ctrl,       stackfocus)
//	STACKKEYS(AltGr|Ctrl|Shift, stackpush)
//	STACKKEYS(AltGr|Shift,      stackswap)

To enable stacker you would uncomment the functions that you need above and take care to revise existing keybindings.

Here is a breakdown of the three functions.

Function Description
stackfocus Focus on the nth client
stackpush Move the current client above the nth position in the stack
stackswap Swap the current client with the nth client (like zoomswap)

More details are to be found on the individual function pages.


Master stacker

The master stacker is building on the ideas of stacker but makes the distinction between the master and stack areas.

This is an alternate way of using stacker.

#define STACKKEYS(MOD,ACTION) \
	{ KeyPress,   MOD, XK_u,                ACTION, {.i = INC(+1) } }, \
	{ KeyPress,   MOD, XK_i,                ACTION, {.i = INC(-1) } }, \
	{ KeyPress,   MOD, XK_semicolon,        ACTION, {.i = PREVSEL } }, \
	{ KeyPress,   MOD, XK_j,                ACTION, {.i = MASTER(1) } }, \
	{ KeyPress,   MOD, XK_m,                ACTION, {.i = MASTER(2) } }, \
	{ KeyPress,   MOD, XK_k,                ACTION, {.i = STACK(1) } }, \
	{ KeyPress,   MOD, XK_l,                ACTION, {.i = STACK(2) } }, \
	{ KeyPress,   MOD, XK_comma,            ACTION, {.i = STACK(3) } }, \
	{ KeyPress,   MOD, XK_period,           ACTION, {.i = STACK(4) } }, \
	{ KeyPress,   MOD, XK_Down,             ACTION, {.i = STACK(5) } }, \
	{ KeyPress,   MOD, XK_bracketleft,      ACTION, {.i = STACK(6) } }, \
	{ KeyPress,   MOD, XK_slash,            ACTION, {.i = LASTTILED } },

Consider the following argument additions.

Argument Description
MASTER(n) The nth client in the master area
STACK(n) The nth client in the stack area

The keybindings in the above example may look off because they are for a keyboard layout like this:

 y  u  i  o  p
 h  j  k  l  ;
 n  m  ,  .  /
    ↑  ↓  [  ]

Translating the keyboard layout with the keybindings we end up with:

 y  ++ -- o  p
 h  m1 s1 s2 prev
 n  m2 s3 s4 last
    ↑  s5 s6 ]

The general idea is that MOD+j and MOD+m focuses on the first and second master client respectively, while MOD+k focuses on the first stack client and so on.

The benefit of this is that the stack clients are always accessible using the same keybindings regardless of how windows are in the master area.

More so doing MOD+m when there is only a single master client will select that master client rather than the first client in the stack area. This is due to how the nth client will reduce within the respective tiled area.


Stacker hints

Optionally keyboard shortcut hints for clients accessible via stacker bindings can be added to the window titles where applicable.

Refer to the StackerIcons functionality for more details.


Back to Functions > Functionality.

Clone this wiki locally