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.

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
		└── sxhkdrc_bspc

3 directories, 4 files

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 at any moment (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 2       # outer border around nodes/windows
bspc config window_gap 4         # 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. Detailed comments are provided therein. Allow me to highlight a very opinionated setting that I have and which might be unsuitable for your use-case:

bspc config ignore_ewmh_focus true

This prevents applications from stealing focus. Set it to false if it is causing you trouble. Personally, I dislike focus stealing. It is very intrusive and can disrupt my rhythm. One common scenario 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.

Another thing to bear in mind concerning this section is the invocation of my bspwm_external_rules script. “External rules” is the set of conditions that the window manager evaluates in order to treat certain windows accordingly. For example, when should a window be spawned in “floating” mode rather than the standard tiling one. My external rules contain some more advanced tweaks that cover manual tiling operations that are discussed in further detail in the chapter about the advanced features of my BSPWM session.

2. Autostart

This section of the bspwmrc is where we instruct the window manager 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 BSPWM.

Some notable points:

  • Each program leverages shell scripting, so as to be run only if it is indeed present on the system.
  • 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 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 (you can set any jpg file as a wallpaper using a command like feh --bg-fill /path/to/jpg).
  • 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 between 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. Else, just remove it.
  • 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 one desktop (because of the “dynamic desktops” functionality discussed in the chapter about the advanced features of my BSPWM session):

bspc monitor -d 1

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 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 SXHKD

There are two config files, sxhkdrc and sxhkdrc_bspc, which are meant to separate custom hotkeys between those that are specific to BSPWM actions and others that are WM-independent.

Each of the SXHKD configs stores custom key bindings, internally known as “key chords”. There are two main types of patterns: the direct and the chained. To illustrate the difference:

# 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 splits between nodes we go with super + s ; <keys>.
  • There are a few more that are documented in the chapter about the advanced features of my BSPWM session. They are super + n ; <keys> for node-related operations (mostly manual tiling and receptacles), and super + c : <keys> (notice the colon sign) for the continuous input mode.

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

# GUI
super + g ; {1-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 (or have poor HTML structure and/or typography), 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 keys 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
	~/.config/sxhkd/sxhkdrc_bspc

The latter is for definitions that control the window manager.  While
the former has WM-independent keys.

Last review 2019-07-01.

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, yet fully-capable terminal (xterm)
Super + q                 |-Close focused window safely (apps might require confirmation)
Super + Shift + q         |-Kill focused window (no confirmation whatsoever)
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 == choose which window 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 window's full screen view
Alt + Tab                 |-Cycle through windows on the current desktop
Alt + Shift + Tab         |-Cycle backwardly through windows on the current desktop

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

Super + {0-9}             |-Switch to the designated desktop (workspace)
Super + Shift + {0-9}     |-Send focused node to the given desktop
                          |---Desktops are created/removed dynamically (my custom setup)
Super + Tab               |-Cycle through desktops on the current monitor
Super + Shift + Tab       |-Cycle backwardly through desktops on the current monitor
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)
                          |---Balance works on the parent node.  Equalise is for all nodes.
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}
Super + comma             |-Switch focus to the next monitor (cycles through monitors)
Super + Shift + comma     |-Switch focus to the previous monitor (cycles through monitors)

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-3}         |-Open graphical apps {firefox,caja,thunderbird}
Super + x ; {3-5}         |-Run a terminal with {mutt,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 window 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 and ~/.config/sxhkd/sxhkdrc_bspc.
They are extensively documented.  You will find key chords for tasks not
included herein, such as multimedia keys, setting node flags, and more.