herbstluftwm juggling

saturday, 21 february 2015

the messenging aspect of herbstluftwm via shell scripts and herbstclient allow extending the window manager behaviour. One added benefit is that it is fairly difficult to bork the actual window manager – at least, I haven’t been able to do so. Illegal herbstclient commands just fail gracefully – no harm done. No recompilation required. And you can test out code snippets in a terminal window before committing the code to the autostart or scripts to be spawned.

swap monitors

is implemented to follow (focus) the current tag or retain focus of the current monitor, dependent on whether the monitor tag is pushed in the direction of monitor (switch focus) – corresponding to left/right bracket – or pulled from the adjacent monitor (retain focus)..

#!/bin/sh function swap_to() { swap_monitors=$(herbstclient get swap_monitors_to_get_tag) herbstclient set swap_monitors_to_get_tag 1 if [[ $@ = 0 ]]; then herbstclient chain . lock . focus_monitor 1 . use $tag0 . focus_monitor 0 . use $tag1 . unlock else herbstclient chain . lock . focus_monitor 0 . use $tag1 . focus_monitor 1 . use $tag0 . unlock fi herbstclient set swap_monitors_to_get_tag $swap_monitors } direction=$@ focus=$(herbstclient list_monitors | grep '\[FOCUS\]' | cut -d: -f1) tag0=$(herbstclient list_monitors | grep '^0:' | cut -d'"' -f2) tag1=$(herbstclient list_monitors | grep '^1:' | cut -d'"' -f2) if [[ $focus = $direction ]]; then [[ $focus = 0 ]] && swap_to 0 || swap_to 1 else [[ $focus = 0 ]] && swap_to 1 || swap_to 0 fi

swap_monitors_to_get_tag is set to 1 to enable the tag swap of existing views.

This ultimately saves me potentially one meager keystroke combination – selecting the monitor in focus – and needing to know the monitor tag I wish to swap! Lazy I know but it’s handy. And it is one less thing – the tags in view – to need to track in the back of your head. The keybinds match the left/right position of the monitor placement to the left/right bracket..

herbstclient keybind Mod1-Control-bracketleft spawn swap_monitors 1 herbstclient keybind Mod1-Control-bracketright spawn swap_monitors 0

swap window

is similar in action to swap_monitors but moves a window to the adjacent monitor, following (focus) or retaining focus of the current monitor depending on the direction (left/right bracket) of the window movement..

#!/bin/sh direction=$@ focus=$(herbstclient list_monitors | grep '\[FOCUS\]' | cut -d: -f1) if [[ $focus = $direction ]]; then if [[ $focus = 0 ]]; then herbstclient and . lock . shift_to_monitor 1 . focus_monitor 0 . unlock else herbstclient and . lock . shift_to_monitor 0 . focus_monitor 1 . unlock fi else if [[ $focus = 0 ]]; then herbstclient and . lock . shift_to_monitor 1 . focus_monitor 1 . unlock else herbstclient and . lock . shift_to_monitor 0 . focus_monitor 0 . unlock fi fi

As above, the keybinds match the left/right position of the monitor placement to the left/right bracket..

herbstclient keybind Mod1-Shift-bracketleft spawn swap_window 1 herbstclient keybind Mod1-Shift-bracketright spawn swap_window 0

hide window

is something transcribed from my bspwm customizations. Most often in herbstluftwm, it is simple enough to set the frame layout to max for the window in focus which, effectively hides the other windows in the frame.

But sometimes, especially in grid layout, it is handy to temporarily minimize (hide) a window or two to quickly resize the remaining windows of the frame, keeping them all in view. Rather than follow common tiling window manager convention to move windows to desktop (tag) “0” or an adjacent monitor, a (tick) ‘tag is added to hold and restore windows from..

#!/bin/sh tag=$(herbstclient list_monitors | grep '\[FOCUS\]' | cut -d'"' -f2) if [[ $@ = +1 ]]; then herbstclient dump “‘$tag” || herbstclient add “‘$tag” herbstclient move “‘$tag” else herbstclient dump “‘$tag” && herbstclient chain . lock . use “‘$tag” . move $tag . use $tag . unlock fi

With simple keybinds, any number of windows per tag can be effectively minimized and restored in order..

hc keybind $Mod-m spawn hide_window +1 hc keybind $Mod-Shift-m spawn hide_window -1

Note: the window(s) are restored to the current frame in focus of the tag.


is a persistent terminal that can be toggled (hide/unhide from the tag in focus) or pulled into view from any desktop (tag). Hence, you can open the scratchpad in any tag, switch to another and pull it into view on the new tag in focus – regardless of whether the scratchpad is visible or not.

It is a lightweight implementation and acts like an ordinary window (versus the virtual monitor overlay example provided in the herbstluftwm contributions)..

#!/bin/sh scratchpad=/tmp/herbstluftwm:scratchpad if xdotool search --onlyvisible --classname 'scratchpad'; then if [[ $(herbstclient list_monitors | grep ‘[FOCUS]’ | cut -d’”’ -f2) = $(herbstclient attr clients.$(cat $scratchpad) | grep ‘s - tag’ | awk ‘{ print $5 }’) ]]; then xdotool search –onlyvisible –classname ‘scratchpad’ windowunmap exit fi fi if [[ -f $scratchpad ]]; then if ! herbstclient bring $(cat $scratchpad); then xdotool search –classname ‘scratchpad’ windowmap && exit fi fi if ! xdotool search --classname 'scratchpad' windowmap; then urxvt -title ‘scratchpad’ -name ‘scratchpad’ -pe tabbed & xdotool search –sync –onlyvisible –classname ‘scratchpad’ herbstclient attr clients.focus.winid > $scratchpad fi

I use the scratchpad a lot – the urxvt tabbed perl extension can reduce the need for extra terminal windows and the persistent content is useful throughout a session – seldom using separate terminal windows, so designate the common terminal keybinds as such..

herbstclient keybind Mod1-Return spawn scratchpad herbstclient keybind Mod1-Shift-Return spawn urxvt

which will open the scratchpad on the desktop, unless it is already in view (in which case, it will be hidden). Extra terminals are always available for times it is handy to work with terminals side-by-side.

»»  herbstluftwm hiding

comment ?