Protesilaos Stavrou
Philosopher. Polymath.

Basics of my BSPWM

Prot's Dots For Debian - Book index

You used GNU Stow to place all my configurations in the right filesystem path and are now eager to start using the custom desktop session. Just hold on a little longer, while you read through this chapter. The rest of this book is mostly “recommended reading” but not “absolutely essential”.

I have a short video demonstration of BSPWM’s main motions. Here we will inspect the underlying configurations and core files that control the Binary Space Partitioning Window Manager.

~/cpdfd $ tree -aF bspwm/
bspwm/
├── .config/
│   ├── bspwm/
│   │   └── bspwmrc*
│   └── sxhkd/
│       ├── cheatsheet_sxhkdrc.txt
│       └── sxhkdrc
└── .local/
	└── share/
		└── my_bspwm_wallpaper_fallback.png

5 directories, 4 files

What matters right now is the content of the .config directory. We have:

  • BSPWM’s configuration file: bspwmrc
  • The daemon that handles key bindings: sxhkdrc

Both are put in place by running stow bspwm from inside my dotfiles’ directory. I recommend you spend some time reading them. They are heavily commented and should answer whatever questions you may have. For the sake of this manual, let us discuss the headline features.

Overview of bspwmrc

The nice thing about bspwmrc is that it is an executable shell script. It is thus possible to add conditional logic and other aspects of shell scripting in order to exercise a more fine-grained control over the desktop session.

Each setting is a bspc command that can be run in a terminal (bspwmrc is a shell script). This is quite convenient: just execute the command to get an idea of what it does. The options are descriptive enough to offer a clear idea of what they pertain to. Here is a snippet of code:

bspc config border_width 3       # outer border around nodes/windows
bspc config window_gap 6         # empty space between nodes
bspc config split_ratio 0.50     # the ratio of new:existing node

The file is divided in three sections, the description notwithstanding:

  1. Visual options for the window manager.
  2. Autostart programs at BSPWM launch.
  3. Per-host configurations.

1. Visual options

These define such things as the border that is drawn around windows, or the gap between them. They also govern the colours that are applied to the various states of the window border.

The colours are taken from my Tempus themes collection. The theme that is defined as the current default is Tempus Classic, which features warm hues on a dark background (the Tempus themes apply to the entire environment—see the chapter on the Tempus themes).

I will let you read the file for the specifics. Below are some settings that require a little bit of explaining:

bspc config single_monocle true          # smart borders
bspc config borderless_monocle true      # smart borders
bspc config gapless_monocle false        # use "true" for smart gaps

The notion of “smart” options concerns the application of the desired settings only when multiple windows are present. So single_monocle true means that desktops with only one open window will behave as if their layout was set to “monocle”.

The “monocle” layout displays windows in their maximised state, stacked on top of each other. We can control the appearance of windows in monocle view, such as by removing borders around them, with borderless_monocle true while still preserving the outer gaps by applying gapless_monocle false.

Another highly opinionated setting is:

bspc config ignore_ewmh_focus true # prevent focus stealing

Set it to false if you want programs to steal focus. Personally, I dislike that behaviour. One specific case where I do not want focus stealing is while running newsboat: I go through the feed list opening all interesting links in browser tabs (or use mpv in the console for multimedia). Once I am done, I close newsboat: no need to go back and forth between it and whatever program steals its focus each time I try to open a new item in the background.

2. Autostart

This is where we instruct BSPWM to run the programs that are essential to the desktop session. The most important of them is sxhkd, which is the hotkey daemon that stores all our custom key bindings, including those that control the window manager.

Some notable points:

  • Each program leverages shell scripting, so as to be run only if it is indeed present.
  • melonpanel is the script that draws the panel at the top of the screen. This is my implementation of lemonbar (read the chapter about the top panel).
  • compton is a display compositor, which is configured to provide a slight blur behing transparent regions, and add subtle shadows around windows, and the like. Its real necessity is to eliminate or at least minimise screen tearing.
  • feh is the tool that sets the wallpaper. I manually define a “{light,dark}.jpg” at ~/Pictures/theme. The last used file path is stored in ~/.fehbg, while I also set a ~/.wallpaper.jpg. In case you have not assigned any wallpaper, you will get ~/.local/share/my_bspwm_wallpaper_fallback.png. That is a pure black (#000000) background with this inscription in pure green (#00ff00): where there is a shell, there are dotfiles_.
  • setxkbmap sets the keyboard layout to US QWERTY and assigns the Compose key to the “Menu” button. Note though that own_script_current_keyboard_layout is designed to switch layouts betwen the default and Greek. To change this behaviour, you need to either edit sxhkdrc (find that script’s invocation) or adapt the script to your needs.
  • A settings daemon is also launched. If you have followed the instructions in this manual, it should be mate-settings-daemon. We need such a tool for a couple of reasons: (1) to be able to change the theme of GTK applications, (2) to apply the same theme to Flatpak apps. As a bonus, the settings daemon allows for live theme switching (as discussed in the chapter about the Tempus themes).
  • The last two programs that are launched are mpd and mpDris2. These are for our music player, as documented in the chapter about the music setup.

3. Per-host configurations

Here I execute a single command: own_script_bspwm_per_host_configs. This contains some additional bspc commands for defining the number of desktops (workspaces) and their mapping to one or two monitors. The default is to set six desktops:

# all workspaces on the primary monitor
bspc monitor -d 1 2 3 4 5 6

While these settings can be stored in bspwmrc directly, I have decided to keep them in their own file. It is a prime example of an external script that configures BSPWM in a context-aware manner (and why having bspwmrc as an executable is a powerful feature).

Bear in mind that, as with all of my dots, own_script_bspwm_per_host_configs is documented extensively. If, however, you have no use for such functionality, just define the workspaces directly inside BSPWM’s config file (see the bspc monitor command shown above).

Also note that own_script_laptop_dual_monitor contains an xrandr command that slightly adjusts the brightness and gamma channels of the LVDS1 display. I have sanitised this behaviour by running a check against the HOSTNAME, to make sure this only runs on my laptop. Still, it is important for you to know, as you might need to adapt things to your liking.

Outlines of sxhkdrc

This is the file where we store all our custom key bindings, internally known as “key chords”. There are two types of patterns: the direct and the chained.

# key chord
Super + <key>

# key chord chain
Super + <key> ; <key>

Sample of an actual direct key chord is:

# Session management (log out, lock, switch users, reboot, shutdown).
ctrl + alt + {Home,End,Delete}
	poweroptionsmenu

This means that while holding down the Ctrl and Alt modifiers, you can press either of Home, End, Delete to invoke the command poweroptionsmenu (a script of mine for running common session management operations, such as logging out, locking the screen, rebooting…).

Now this is a simplified version of an actual key chord chain:

super + e ; {p,t}
	{ \
	pkill -x melonpanel && melonpanel, \
	tempusmenu, \
	}

This pattern means that you first hold down Super, then press e, then release Super and press any of the keys defined to the right of the semicolon ; to invoke the corresponding command. To that end, super + e ; t will execute tempusmenu.

All key chord chains are designed with mnemonics in mind:

  • Everything that concerns the entire session, else “the environment”, starts with super + e ; <keys>.
  • All graphical applications are launched with super + g ; <keys>.
  • All the command line programs you would normally run in a terminal are super + x ; <keys>.
  • To assign flags to nodes, we have super + a ; <keys>.
  • For node splits we go with super + s ; <keys>.

A note on the selection of keys for launching common programs:

# GUI
super + g ; {1,2,3}
	{ \
	notify-send -i firefox "Run GUI program" "Launching Web Browser" && firefox-esr, \
	notify-send -i system-file-manager "Run GUI program" "Launching File Manager" && caja, \
	notify-send -i thunderbird "Run GUI program" "Launching Email Client" && thunderbird \
	}
# CLI
super + x ; {3-5}
	mate-terminal --disable-factory -x {neomutt,newsboat,ncmpcpp}

You might wonder why I have not started numbering the CLIs from 1: because I want to remember that while launching programs I have the following mappings, regardless of whether they are graphical or textual:

  • 1 == web browser
  • 2 == file manager
  • 3 == email client
  • 4 == RSS/Atom reader
  • 5 == music player

I have not found any CLI tools that I consider good enough for web browsing and file management. Given that most websites are not designed to work without javascript and CSS, I believe there will be no truly decent console-based web browser. As for a file manager, I used to use ranger but have realised that I have no real need for it: I mostly manipulate files the UNIX way.

The point is that you might find this indexing useful in case you choose to add your own programs.

Cheat sheet with common key bindings

To help you get started, I provide the cheatsheet_sxhkdrc.txt. It includes the most common key chords, accompanied by short descriptions or explanations. Type super + F1 or super + Home. This will launch a floating terminal window that runs less on the cheat sheet.

The first section of the cheat sheet covers the basics about key chords and key chord chains. It also notes that the main motions that correspond to the four cardinal directions are the same as with Vim: h, j, k, l for left, down, up, right respectively.

So go ahead and run super + F1 once you log in to the BSPWM session for the first time. Below I present the entirety of the cheat sheet, with a reminder that you must always look at the source code that I strive to keep clean, readable, and well-documented:

List of common key bindings.  All definitions are stored at:

	~/.config/sxhkd/sxhkdrc

Last review 2019-05-16.

Explanation of the basics
=========================

The Super key, aka "mod4", is the one that most keyboards mark with the
Windows logo.  While the key "Return" is also known as "Enter".

Motions are the same as Vim: h,j,k,l (left,down,up,right).

This is the general format of a key chord (aka key binding):

	Super + <key>

And this is a key chord chain:

	Super + <key> ; <key>

The keys "Super", "Alt", "Shift", "Ctrl" are known as "modifiers".

To run a key chord, hold down the modifier and press the key.  Key chord
chains build on that principle: you type the key binding to the left of
the semicolon (;), release the modifier and then type the key (or key
chord) to the right of the semicolon.

In this document, the notation {h,j,k,l} means "any one among" the
comma-separated items.  Whereas {1-4} denotes a range: 1,2,3,4.

Getting started
===============

Super + Return            |-Open a terminal running the "Default" tmux session
Super + Shift + Return    |-Open a generic terminal (mate-terminal)
Super + q                 |-Close focused node
Super + Shift + q         |-Kill focused node
Ctrl + Alt + Delete       |-Launch poweroptionsmenu, where you can choose to log out, reboot, etc.

Window motions
==============

Super + {h,j,k,l}         |-Move focus in the given direction == determine which node has attention
Super + Shift + {h,j,k,l} |-Swap focused node with the one in the given direction
Super + Ctrl + {h,j,k,l}  |-Expand/contract tiled node in that direction, provided there is a split
Super + Alt + {h,j,k,l}   |-Set preselection (manual tiling) for next window
                          |---Cancel presel by inputting same command again
Super + Alt + {1-9}       |-Set the presel ratio, relative to the focused node
Super + Shift + <arrows>  |-Move floating window
Alt + right click         |-Drag floating window
Alt + left click          |-Resize floating window from the nearest edge

Window and desktop actions
==========================

Super + Space             |-Toggle between tiled and floating states
Super + m                 |-Toggle between tiled and monocle layout (monocle == maximised nodes)
Super + f                 |-Toggle focused node's full screen view

Desktop operations
==================

Super + {1-6}             |-Switch to the designated desktop (workspace)
Super + shift + {1-6}     |-Send focused node to the given desktop
Super + Tab               |-Switch to last active desktop
Super + r                 |-Rotate the node tree 90 degrees clockwise
Super + Shift + r         |-Rotate the node tree 90 degrees counter-clockwise
Super + Alt + r           |-Mirror/flip the node tree (top left becomes bottom right)
Super + s ; {b,e}         |-Balance or equalise node splits (better try it to get an idea)
Super + Shift + {[,]}     |-Incrementally decrease or increase the gaps between the tiled nodes
Super + Shift + {y,u,i,o} |-Change to gap presents {0,5,10,20}

Launching programs
==================

Super + d                 |-Run dmenu with access to all binaries in PATH
Super + Shift + d         |-Run flatpakmenu with access to all flatpak apps
Super + g ; {1,2,3}       |-Open graphical apps {firefox,caja,thunderbird}
Super + x ; {3,4,5}       |-Run a terminal with {neomutt,newsboat,ncmcpp}
Super + x ; 0             |-Launch a floating terminal running calc

Useful extras
=============

Super + {F1,Home}         |-Launch a floating window with this cheat sheet
Print                     |-Get a screenshot of the focused node saved to the ~/Desktop
Super + Print             |-Get a screenshot of the entire viewport saved to the ~/Desktop
Super + p                 |-Run passmenu to copy a password stored with the UNIX tool "pass"
Super + x ; w             |-Run a floating image browser, from where you can also set the wallpaper
Super + e ; c             |-Toggle the display compotisor (do this if you have performance issues)
Super + e ; f             |-Toggle BSPWM "focus mode", to remove gaps, the padding, the panel
Super + e ; t             |-Run tempusmenu to select a Tempus theme for a live theme switch
                          |---The Tempus themes: https://gitlab.com/protesilaos/tempus-themes
                          |---Some ports of the Tempus themes are distributed with my dotfiles

Further reading
===============

Study the ~/.config/sxhkd/sxhkdrc.  It is extensively documented.  You
will find key chords for tasks not included herein, such as multimedia
keys, setting node flags, cycling through the node history, and more.