Protesilaos Stavrou
Philosopher. Polymath.

Prot's Dots For Debian

Book contents

  1. Prior notice to using PDFD
  2. Introduction to Prot's Dots for Debian
  3. Installing Debian 10
  4. Installing the core packages
  5. Set up my dotfiles and base configs
  6. Basics of my BSPWM
  7. About the default terminal setup
  8. Why choose the MATE Desktop
  9. Notes about my shell setup
  10. Notes about my Tmux and Vim
  11. About the top panel
  12. Fonts and their configs
  13. Per-user MPD setup
  14. Quick guide to set up Newsboat
  15. The Tempus themes
  16. About my local ~/bin
  17. Advanced features of my BSPWM session
  18. Closing notes and additional resources
The purpose of _Prot's Dots For Debian_ (PDFD) is to guide you through the process of replicating my custom desktop session on Debian 10 'buster'. I have tried every step in this guide on real hardware, my Lenovo ThinkPad X220. The initial installation was done on Saturday 12 January 2019 using the latest netinstall iso for Debian 9 'stretch' and retried on 2019-04-17 using the same method. COPYING ------- All code by Protesilaos Stavrou presented herein is available under the terms of the GNU General Public License Version 3 or later. The non-code parts of this book by Protesilaos Stavrou are distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License. The canonical link to "Prot's Dots for Debian" is an extension of my website: https://protesilaos.com/pdfd DISCLAIMERS ----------- The following disclaimers apply to this work. Excerpt from the GPLv3: >THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY >APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT >HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT >WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT >LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR >A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE >OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU >ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. And this is from the CC BY-SA 4.0 License: >a. Unless otherwise separately undertaken by the Licensor, to the extent >possible, the Licensor offers the Licensed Material as-is and >as-available, and makes no representations or warranties of any kind >concerning the Licensed Material, whether express, implied, statutory, >or other. This includes, without limitation, warranties of title, >merchantability, fitness for a particular purpose, non-infringement, >absence of latent or other defects, accuracy, or the presence or absence >of errors, whether or not known or discoverable. Where disclaimers of >warranties are not allowed in full or in part, this disclaimer may not >apply to You. >b. To the extent possible, in no event will the Licensor be liable to >You on any legal theory (including, without limitation, negligence) or >otherwise for any direct, special, indirect, incidental, consequential, >punitive, exemplary, or other losses, costs, expenses, or damages >arising out of this Public License or use of the Licensed Material, even >if the Licensor has been advised of the possibility of such losses, >costs, expenses, or damages. Where a limitation of liability is not >allowed in full or in part, this limitation may not apply to You. >c. The disclaimer of warranties and limitation of liability provided >above shall be interpreted in a manner that, to the extent possible, >most closely approximates an absolute disclaimer and waiver of all >liability. The purpose of this book is to help you reproduce my custom desktop session on Debian 10 'Buster' (the current Debian "stable"). The set of configurations that make up my system shall hereinafter be referred to as "my dotfiles" or other notions that are described in context. My dotfiles apply to a BSPWM session. That tiling window manager is the core package. Complementing it, are programs that draw a system panel at the top of the viewport, display desktop notifications, set the wallpaper, perform live theme changes to the terminals and graphical applications, and the like. The idea is to have a lightweight yet perfectly functional desktop environment by combining small, specialised tools. A short description of my custom desktop session: * Debian because I prefer longer-term predictability over novelty. * `bspwm` for fine-grained window management, with my custom scripts for added features. * `tmux` to make the terminal power user even more powerful (no plugins). * `vim` because I need an efficient text editor (no plugins). * True minimalism: no complex status lines, no fancy prompts, no decorative elements that add no functionality whatsoever. * Carefully-defined font configurations to complement my hardware and satisfy my aesthetic preferences. * Full integration of my Tempus themes for considerate colour contrast and easy live theme switching for the entire session. * The superb Maté desktop environment as a fallback option and provider of some important programs and system-wide base configurations. ## A book, not an install.sh Some of PDFD's chapters or sections thereof can, at times, be read as a shell script with extensive inline documentation. While I could have provided a script to automate the installation process, along with some basic guidelines on how to use it, I have opted to use this format instead. It is to ensure that no random user attempts to install something they do not fully understand, both in terms of its content and scope. A book makes the installation process fully transparent to the user. You can read what I am doing, inspect the relevant files and, if needed, make changes on the spot. By following the steps in _Prot's Dots For Debian_ (PDFD), you will develop an intimate understanding of my dotfiles, which will help you further customise the environment to your liking. This is important and ultimately good for all parties involved, due to the highly personalised nature of dotfile management. ## Prepare to adapt things to your liking Please understand that my dotfiles have been designed with my use case in mind. There are bits and pieces you might find surplus to your requirements or outright unsuitable to your needs. Hopefully this manual will help you identify them at an early stage and address them accordingly. By sharing my work, I do not purport to be an expert on the matter. I am just a regular user who has spent enough time documenting their practices. If you happen to identify areas in my setup that could be improved or altogether reworked, your contribution shall be taken into consideration. ## Not for hipsters The target audience for this book is the **experienced GNU/Linux user who wants to run Debian 10 'buster' as a desktop OS**. PDFD may also appeal to existing BSPWM users of other distros who would like to test my custom desktop session in a virtual setup or cherry-pick features for use in their setup. Newbies are welcome as well, provided they are willing to learn and understand who this book is for. You do not need to be a programmer to follow the instructions in PDFD—I am not one either. Though it is recommended you have at least some knowledge of shell scripting: it is required to make certain adaptations to programs such as the one that controls the system panel. ## Why Debian and not some rolling-release distro? Exactly because I do not need the latest version of every package ever released. I was an Arch Linux user for a good amount of time. While I did learn a lot and consider that distro my second favourite, I did not find any compelling reason to cling on to the rolling-release model for the entire operating system. Perhaps paradoxically, Debian is exciting because it is predictable. It takes a very conservative stance towards introducing breaking changes. It does not chase new technology trends for innovation's sake. Debian is reliable. Simple and super effective. This is precisely what we need for the custom desktop session: a stable OS that we can expect to remain constant for at least another couple of years. Else we are trapped in a state of flux where we need to track every changelog out there in order to keep our custom desktop environment in good working condition. If I were using a rolling-release distro, I would not be writing this book. Things change all the time and it is impossible to maintain documentation such as this: I do not want this to become some full-time occupation. Here is a rule that is based on my experience: in an ever-changing OS, the broader the scope of customisations, the greater the chance of experiencing breakage or minor annoyances that require manual interventions. For someone like myself, who tends to document the various types of functionality that affect my setup, with this book being a prime example, it simply is too much trouble to constantly update everything for whatever marginal benefit there is to be gained from a fresh package version. Speaking of "fresh", we should avoid thinking of packages in terms of groceries. That is a pernicious metaphor. Programs remain relevant for as long as they work and receive security fixes (where appropriate). The criterion for evaluating a program is not its recency or the hype around it, but its serviceability. _"If it ain't broke, don't fix it"_. Programs that fall in that category do not become "stale" just because their last upstream release was a few months or years ago. Stability means predictability and peace-of-mind. This is the constant against which one may develop habits to meet their computing requirements. Having a stable basis means that you ultimately treat customisations as a means to the end of a more efficient workflow. You do not care about incessant "ricing" per se; constantly tweaking things for the sake of fitting in with the cool kids. You are interested in a custom desktop session that behaves the way you intend. Every customisation, every minute refinement, every careful tweak, serves the purpose of minimising perceived friction, of shortening the distance between your mind and the machine. Nothing more, nothing less. To get Debian 10 'buster' on our machine, we are going to use one of the netinstall iso images. The official way is to follow the standard method, which includes only free/libre software, or to use the unconventional method which comes preconfigured with the `contrib` and `non-free` package repos. The latter is intended for awkward hardware setups that absolutely require certain non-free packages (firmware drivers) to run the installer. Here are the corresponding links: * [Debian 10 netinstall](https://cdimage.debian.org/cdimage/release/current/amd64/iso-cd/) * [Debian 10 netinstall (non-free firmware)](https://cdimage.debian.org/cdimage/unofficial/non-free/images-including-firmware/current/amd64/iso-cd/) ## Short note about free software Debian refers to the second iso as "unofficial". Do not let that mislead you. It is still provided by the team responsible for the installer images. In this context, "unofficial" means that it does not fully conform with Debian's Free Software Guidelines. While understandable, this is a rather unconvincing attempt to maintain the line that Debian only ships with free/libre software. I can, thus, see why the Free Software Foundation or the GNU project[^GNUViewDistros] do not include Debian in their list of approved distributions that do not sacrifice software freedom for convenience.[^FSFDistros] Personally, I use Debian with a single non-free package that is necessary to enable my Wi-Fi card. Otherwise I could not run a free OS _at all_. If you start with the unofficial method, you can still opt to run only free software by retroactively removing any "contrib" and "non-free" entries from the APT sources list. System administration of this sort is outside the scope of PDFD. I have, nonetheless, taken care to only recommend libre software in the pages of this book. ## Writing the latest release iso Politics aside, let us proceed with the installation. You need to verify your iso with information provided by Debian (from the pages you get the iso from). Once the checks are done, write the iso to a flash drive. I usually follow these steps after I insert the medium and open a new terminal: # prints information about devices sudo fdisk -l # the flash drive I insterted is usually at /dev/sdb # unmount the flash drive umount /dev/sdb # write to it sudo dd if=/path/to/iso/file of=/dev/sdb # eject the flash drive sudo eject /dev/sdb **Please be extemely careful with the above commands**, especially when identifying the flash drive. Pay attention to the output of `sudo fdisk -l` and make sure you correctly spot the writeable medium you intend to use. Carelessness might result in data loss or other damages. ## The installation process Now on to get Debian on the machine. Insert the flash drive and power on the computer. You are given the choice of a simple graphical or textual interface, as well as advanced options. If in doubt, go with the graphical option. Once the installer starts, you will have to choose your language and keyboard settings, set your root user's password, create a regular user, and the like. At some point in the installation process, you will be asked to select your major system components. These include a Desktop Environment, an SSH server, a print server, and a web server. I always keep the first option checked, then using the space key to toggle on/off I add MATE, SSH server, remove the print server, and keep the standard system utilities. The selection screen looks like this: [x] Debian desktop environment [ ] ... GNOME [ ] ... Xfce [ ] ... KDE Plasma [ ] ... Cinnamon [x] ... MATE [ ] ... LXDE [ ] ... LXQt [ ] web server [ ] print server [x] SSH server [x] standard system utilities You can omit the SSH server if you have no use for it. Follow the remaining steps and after a while you will have successfully installed Debian on your machine. Congratulations! Later in the book I explain why you should also choose MATE. For the time being, let us proceed to the next chapter of actually installing the core packages and configuring things accordingly. [^GNUViewDistros]: [Explaining Why We Don't Endorse Other Systems](https://www.gnu.org/distros/common-distros.html). By the GNU project. [^FSFDistros]: [Free GNU/Linux distributions](https://www.gnu.org/distros/free-distros.html). By the GNU project. Boot up your newly-installed Debian 10 'buster'. When you reach the display manager screen, enter your user credentials (user name and password). This will put you in a default MATE session (pronounced _MA-te_, from _yerba maté_). From here, we will be installing all the packages we need and doing the rest of the preparatory work. ## Enable sudo First things first: we need to grant superuser privileges to your user account. This is necessary in order to use `sudo` with the various commands, rather than having to switch to the root user. Open a terminal. For this initial step, you need to switch to the root account. su - While being root, make sure you update the package lists. Then install Vim and the package that enables "sudo". apt update && apt install vim sudo Also install these core utilities, which are needed for getting and deploying my dotfiles. apt install git stow Once that is done, add your user account to the "sudo" group, replacing USER with your username. adduser USER sudo Reboot if you want to use the regular user, or continue as root. For the sake of this manual, I assume you rebooted, logged back in to the default MATE session and are now prepared to run all commands from your regular user but with escalated privileges, prepending "sudo" to all relevant commands. ## Getting BSPWM and related core components We start by installing: * the window manager (`bspwm`) as the irreducible factor of my custom desktop session, * the hotkey daemon (`sxhkd`) for handling custom key bindings that control BSPWM and other programs, * the standard terminal emulator `xterm`, * the `suckless-tools`, which provide the simple screen locker (`slock`) and the dynamic menu (`dmenu`), * the program that manages the wallpaper and can display images (`feh`), * the display compositor (`compton`) for smoother transitions and no screen-tearing, * the notification daemon and concomitant library for sending desktop notifications (`dunst` and `libnotify-bin` respectively), * the system bar (`lemonbar`) that is used by one of my scripts to draw a bespoke panel on the top of the viewport as well as its dependencies (`xdo`, `acpi`), * and the secrets' manager (`gnome-keyring`). Run this: sudo apt install bspwm sxhkd xterm suckless-tools feh compton dunst libnotify-bin lemonbar xdo acpi gnome-keyring To make sure `dunst` works unencumbered, we better remove MATE's own notification daemon: sudo apt remove mate-notification-daemon _For more on this set of packages, see the chapter about the basics of my BSPWM as well as the one about the top panel._ ## GTK icon theme Now we get the GTK icon theme. I choose Papirus because it is very well crafted and actively developed. sudo apt install papirus-icon-theme ## Fixed and proportional fonts We need outline/proportional typefaces for the various UI components and graphical applications, plus a fixed-size (bitmap) typeface for use in the system panel. The outline fonts are: sudo apt install fonts-firacode fonts-hack fonts-roboto fonts-dejavu fonts-dejavu-extra fonts-noto-color-emoji fonts-symbola The bitmap font is Terminus. This is optional, though highly recommended: sudo apt install xfonts-terminus _The typographic considerations are discussed in the chapter about the fonts and their configs._ ## Terminal tools My user session makes heavy use of a terminal multiplexer (`tmux`), while I occasionally need to use Vim's external register or graphical application (`vim-gtk3`). sudo apt install tmux vim-gtk3 _The use of these tools is documented in the chapter about my Tmux and Vim combo. Of relevance is the chapter about the default terminal setup._ ## General CLI tools Then we need the RSS/Atom feed reader for the console (`newsboat`) and a simple utility to capture screenshots (`scrot`). sudo apt install newsboat scrot Are you using a laptop or a screen with built-in brightness controls? You need this: sudo apt install xbacklight ## The music setup For my music, I choose to use the Music Player Daemon and connect to it with a client program (`mpc` and/or `ncmpcpp`). I also want MPD to expose itself to applications that implement the MPRIS protocol (`mpdris2` with `python-mutagen` for album covers), in order to be able to control it through other means than its own clients (`playerctl`). To this end, I install the following: sudo apt install mpd mpc ncmpcpp mpdris2 python-mutagen playerctl _Detailed instructions about these are provided in the chapter about the Per-user MPD setup._ ## Extra packages for convenience and added functionality I do not want my BSPWM session to be primitive. I just want it to be configurable and catered to my needs, while being light on system resources. I therefore need a multimedia player that I can launch from the console, which also streams online content (`mpv` with `youtube-dl`), a tool that can edit/transform/convert images from the command line (`imagemagick`), a program to perform file transfers (`rsync`), a graphical frontend to my password manager (`qtpass`, which pulls in `pass`), a frontend for PulseAudio (`pavucontrol`), a very capable image viewer (`sxiv`), and a calculator for the console (`apcalc`—the executable is `calc`). sudo apt install mpv youtube-dl imagemagick rsync qtpass pavucontrol sxiv apcalc ## Thunderbird setup (optional, but recommended) In the same spirit, I use Thunderbird as my primary email client (I also use Mutt, which is not covered in this book due to its configuration being highly dependent on the user). Thunderbird is a robust tool that can easily filter spam, handle my CalDAV and CardDAV accounts, and cope with large volumes of email traffic. The following command will get you the email client, plus extensions for GPG encryption (`enigmail`) and calendaring (`lightning`). sudo apt install thunderbird enigmail lightning While still on the topic of Thunderbird, I also install the following package for handling {Cal,Card}DAV services. I put it here on its own as you might have no need for it, unless your host also uses SOGo. sudo apt install xul-ext-sogo-connector For further language support, I also get these (the latter with extension `-el` is for the Greek language): sudo apt install hunspell {a,hun}spell-el ## Firefox setup (optional, but recommended) The Extended Support Release of Firefox (`firefox-esr`) is my web browser of choice. This is shipped by Debian as the default option. Users normally install whatever web extensions they may need via the browser's own interface. However, I have found that I prefer to let `apt` handle things. The following packages are sufficient for my use case: sudo apt install webext-noscript webext-https-everywhere webext-ublock-origin webext-privacy-badger These extensions are NoScript, HTTPS Everywhere, UBlock Origin, Privacy Badger. To make the browser better suited to my needs, I also disable the Pocket bloatware, from inside Firefox's interface. * First type the address `about:config` and accept the warning message. * Then search for the entry `extensions.pocket.enabled`. * Double click to change it to false. Then we need to address an age-old bug that affects dark GTK themes where Firefox may display dark text on a dark action element, like a search box. * Visit `about:config`. * Do: left click on some empty space > select New > select String. * Add this: `widget.content.gtk-theme-override`. * Its value should be `Adwaita` (the default GTK light theme). ## Optional packages Sometimes I need to edit photographs (`darktable`), record audio (`audacity`), and use a different web browser (`epiphany-browser`). # other packages sudo apt install audacity darktable epiphany-browser And here are some other console tools that might come in handy. `vrms` displays information about non-free software on your system, while `neofetch` prints details about your machine and distro. sudo apt install vrms neofetch I just ran `vrms` and it tells me that I have 1 non-free package on my ThinkPad X220 out of a total of 1727. ABSOLUTELY PROPRIETARY! The offending package is `firmware-iwlwifi` for making Wi-Fi work, else I cannot access the Internet… ## Optional: set up Flatpak with Flathub as its remote repo I think that, when used in moderation and care, Flatpak is a compelling proposition for a stable OS like Debian. Your system will remain rock solid, while the Flatpak'ed applications will use their latest version, while being confined to a sandboxed environment (in the near future a tool like `guix` may be the superior alternative). To get started, install the core package: sudo apt install flatpak Now add [Flathub as a remote package repository](https://flathub.org). Note that you can have multiple remote repos. This is something that, in my opinion, distros should provide themselves (would much rather trust Debian's curated list of `flatpak` packages, but I digress). flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo For the record, Flatpak needs a running settings daemon to known which theme to apply. It is why I use the `mate-settings-daemon` in my BSPWM session (more on that in the chapter about the basics of BSPWM). Note that Flathub does not discriminate against non-free software. If you care about freedom, exercise caution. That granted, the only flatpaks I tend to use are libre: flatpak install org.gnome.Podcasts org.gnome.clocks org.kde.kdenlive ## Next steps We are done installing software. Thanks for your patience! Let us proceed to the next chapter where we actually get the dotfiles and stow them in place. _Stay logged in to the current MATE session for the time being and keep reading_. You have installed all the necessary packages and are now ready to fetch the configurations and code that makes up my custom desktop session. It is assumed you are running the stock MATE session and have an open terminal. ## The latest fixed release of my dots The "Code for Prot's Dots For Debian" (Code for PDFD == CPDFD) is the repository that contains the latest _fixed release_ of my dotfiles. Such tagged releases are versions that I have tested extensively and am confident that others can use. We shall be employing CPDFD, because my dotfiles' `git` repository is an unstable environment, intended for running tests and developing new features that eventually end up in a fixed release. CPDFD is hosted on GitLab's own instance (gitlab.com). If you have an account there and have configured SSH access, you can clone the repo with the following command: git clone git@gitlab.com:protesilaos/cpdfd ~/cpdfd Otherwise, just clone over HTTPS: git clone https://gitlab.com/protesilaos/cpdfd ~/cpdfd Bear in mind that we clone the repo into the user's home directory. The rest of this manual will assume `~/cpdfd` as a constant. _For the record, my dotfiles are available here: https://gitlab.com/protesilaos/dotfiles._ ## Primer to managing dotfiles with GNU Stow You will not be copying anything manually. That is a recipe for disaster! Instead we leverage the power of symbolic links, aka "symlinks", by using GNU Stow. The way Stow works is to read the filesystem paths defined by a target and create equivalent symlinks to them at the parent of the present working directory (or a given destination). In practice, since `cpdfd` is in your home directory, all symlinks will be extensions of `/home/USERNAME/`, else the `~` path. Let us take a closer look at what it means to give `stow` a target. In my dotfiles, I have a directory called "vim". Its structure looks like this: ~/cpdfd $ tree -aF vim vim ├── .vim/ │   ├── colors/ │   │   ├── tempus_autumn.vim │   │   ├── tempus_classic.vim │   │   ├── tempus_dawn.vim │   │   ├── tempus_day.vim │   │   ├── tempus_dusk.vim │   │   ├── tempus_fugit.vim │   │   ├── tempus_future.vim │   │   ├── tempus_night.vim │   │   ├── tempus_past.vim │   │   ├── tempus_rift.vim │   │   ├── tempus_spring.vim │   │   ├── tempus_summer.vim │   │   ├── tempus_tempest.vim │   │   ├── tempus_totus.vim │   │   ├── tempus_warp.vim │   │   └── tempus_winter.vim │   └── spell/ │   ├── el.utf-8.spl │   ├── el.utf-8.sug │   ├── en.utf-8.add │   └── en.utf-8.add.spl └── .vimrc 3 directories, 21 files It includes a `.vimrc` file and a `.vim` directory with more content. So if you run `stow vim` from within `~/cpdfd` all those paths will be added to your home directory as symlinks. Here I also add the `-v` option for a verbose output: ~/cpdfd $ stow -v vim LINK: .vim => cpdfd/vim/.vim LINK: .vimrc => cpdfd/vim/.vimrc This means: * `~/.vim` links to `~/cpdfd/vim/.vim`. * `~/.vimrc` links to `~/cpdfd/vim/.vimrc`. The contents of `.vim` are accordingly expanded into: ~/.vim/colors ~/.vim/colors/tempus_autumn.vim ~/.vim/colors/tempus_classic.vim ~/.vim/colors/tempus_dawn.vim ~/.vim/colors/tempus_day.vim ~/.vim/colors/tempus_dusk.vim ~/.vim/colors/tempus_fugit.vim ~/.vim/colors/tempus_future.vim ~/.vim/colors/tempus_night.vim ~/.vim/colors/tempus_past.vim ~/.vim/colors/tempus_rift.vim ~/.vim/colors/tempus_spring.vim ~/.vim/colors/tempus_summer.vim ~/.vim/colors/tempus_tempest.vim ~/.vim/colors/tempus_totus.vim ~/.vim/colors/tempus_warp.vim ~/.vim/colors/tempus_winter.vim ~/.vim/spell ~/.vim/spell/el.utf-8.spl ~/.vim/spell/el.utf-8.sug ~/.vim/spell/en.utf-8.add ~/.vim/spell/en.utf-8.add.spl From now on, we will be referring to the immediate subdirectories of `~/cpdfd` as "Stow Packages", as per `man stow`. Using GNU Stow is essential because many of my Stow Packages contain somewhat complex structures such as the one shown above. Plus, keeping everything symlinked provides the benefit of controlling things with `git`. If you need to make changes or pull my latest fixed release, you will be able to do so centrally at `~/cpdfd`. ## About my Stow packages Switch to my dotfiles: cd ~/cpdfd Now list only the directories that are relevant for `stow` (they are always written in lower case letters): ~/cpdfd $ ls --ignore='[A-Z]*' bin bspwm colours compton dunst fontconfig gtk keyring music newsboat shell tmux vim xterm Note though, that the directories that are named "NO-STOW-" still contain useful configs. However, they need to be manually adapted to each use case. Target them all at once (we pass the `-v` flag so that you see where everything is linked to—though you can always just browse through my dotfiles' contents): stow -v bin bspwm colours compton dunst fontconfig gtk keyring music newsboat shell tmux vim xterm If Stow throws and error and complains that some files already exist, you must delete them, rename them, or otherwise move them to another location. The common offenders are the default `~/.bashrc` and `~/.profile` which will block the Stow package called "shell". **The rest of this book assumes that you have used GNU Stow on all the appropriate packages, otherwise things will not work as intended.** Now a few words about each Stow package: * `bin` contains my custom scripts. Some of these are an integral part of my custom desktop session. This topic is covered in the chapter about my local ~/bin. * `bspwm` includes the configuration files for the window manager (BSPWM) and the hotkey daemon (SXHKD). The former is where we define settings such as the width of the border that is drawn around windows, the ratio at which windows are split, and the like. The hotkey daemon stores all the custom key bindings we use to control the session. For more, read the chapter about the basics of my BSPWM. * `colours` is where my Tempus themes for the shell and X resources are located. These files are used by various scripts of mine and should never be edited manually. For more, read the chapter about the Tempus themes. * `compton` refers to the display compositor and has the relevant config file. We use this to avoid screen tearing, add some subtle shadows around windows and enable somewhat smoother transitions. * `dunst` includes configurations for the daemon that displays desktop notifications. These control the look and feel of the program. * `fontconfig` includes all of my custom font configurations. For the specifics, refer to the chapter about fonts. * `gtk` defines the settings for the graphical toolkit. It also adds ports of the Tempus Themes for the GTK3 Source View widget (used by text editors such as Gedit, Pluma, Mousepad) as well as the GTK4 equivalent (used by GNOME Builder). * `keyring` contains the files necessary for autostarting the GNOME Keyring, the tool that stores passwords and secrets. You can use this to store access to SSH keys and the like. * `music` refers to the configuration files for the Music Player Daemon and its ncmpcpp client. Please note that you need to read the chapter about the music setup in order to make this work properly. * `newsboat` stores the files needed by the RSS/Atom reader of the same name. In order to use this program, you need to add some URLs that point to valid feeds. Read the chapter about Newsboat. * `shell` defines my Bash-related configurations, including aliases for common commands, the command line prompt, and various useful tweaks. Read the chapter about my shell setup. * `tmux` is about the terminal multiplexer used in my default terminal. Details are included in the chapter about my Tmux and Vim configurations. * `vim` is my editor of choice, which I use without any plugins or whimsical tweaks. As with the above Stow target, refer to the chapter about Tmux and Vim. * `xterm` contains all the necessary files for configuring the terminal emulator according to my preference. ## Ready to go! You are now ready to log in to BSPWM. Just to be sure, reboot your system. When you reach the login screen, look for the drop-down menu on the top-right corner of the screen, where desktop sessions are listed. Select `bspwm` and then proceed to add your username and password. _But before you actually log in, read the following chapter about the basics of my BSPWM, how to control it and move around, and the like_. 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 chord chain Super + ; 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 ; `. * All graphical applications are launched with `super + g ; `. * All the command line programs you would normally run in a terminal are `super + x ; `. * To assign flags to nodes, we have `super + a ; `. * For splits between nodes we go with `super + s ; `. * There are a few more that are documented in the chapter about the advanced features of my BSPWM session. They are `super + n ; ` for node-related operations (mostly manual tiling and receptacles), and `super + c : ` (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 + And this is a key chord chain: Super + ; 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 + |-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. My default terminal emulator is the standard for the X Window System and probably the one with the fewest "gotchas": `xterm`. This has not always been the case. Until fairly recently I was using my custom build of the Simple Terminal, by _suckless_. Prior to that I was a `urxvt` user. I have also worked extensively with `{gnome,mate,xfce4}-terminal` (VTE-based) and others. I only tried Xterm last, due to the baseless belief that it was legacy software, more or less. This was compounded by the misinformation that _suckless_ spreads regarding the maintainability of Xterm. Read what the main Xterm developer, Thomas E. Dickey, has to say about its many [look-alikes](https://invisible-island.net/xterm/xterm.faq.html#known_bugs). Such misconceptions were quickly cast aside once I started reading through the program's manpage and then checked its upstream provider. Xterm is a very capable tool that continues to receive regular updates. To be clear: no terminal is perfect. Choosing one is a matter of weighing the pros and cons. I find that Xterm meets the following criteria better than its alternatives: 1. Is in the Debian repos. True for all other options. However, note that `st` (Debian package `stterm`) only makes sense to use as a custom build, so it technically does not meet this criterion. Overall, Xterm is more suited to Debian than a custom build of the Suckless Terminal, because it does not depend on development packages and therefore is not going to have any issues over the long term (e.g. the upstream has build dependencies that are not available in Debian Stable). 2. Is highly configurable and easy to reproduce. In large part this is true for all options though there are differences in degree and ways of doing things: `xterm` uses the `.Xresources` file, making it the most dotfile-friendly option. 3. Has good performance. My totally-non-scientific tests suggest that only _unpatched_ `st` has a slight edge over Xterm. But the unpatched tool lacks all sorts of features such as scroll-back functionality and cursor blinking, meaning that this is not a one-to-one comparison. At any rate, I think the use of `tmux` renders this point largely irrelevant. 4. Is agnostic to the choice of desktop environment or toolkit. True for `st` and `urxvt` as well, though not for the VTE-based options. 5. Has good font-drawing capabilities. This is particularly important when using `tmux` and other programs that draw borders. The VTE-based programs have no issues whatsoever. Xterm requires some careful font configurations, which I have taken care of. `st` can only cope well if it is extensively patched. `urxvt` has weird issues with letter spacing. If you find that `xterm` does not fit your use case, I also have a script that configures `mate-terminal` to my liking, including colours that match the rest of the session: `own_script_mate_terminal_setup`. If you still want to use something else, and are willing to do things manually, I recommend my custom build of `st` (has no upstream patches and is configured to use my Tempus themes): [https://gitlab.com/protesilaos/st](https://gitlab.com/protesilaos/st). **Be warned that only Xterm is integrated with my dotfiles to keep things maintainable.** ## The practical uses of Xterm The many roles of `xterm` are defined in my `sxhkdrc`. In short: * Serves as a container for `tmux`, the terminal multiplexer (see chapter about my Tmux and Vim setup) * Can be run on its own. Offers everything you expect from a feature-complete, yet fairly lightweight terminal (though I strongly encourage you to learn `tmux`). * Launches CLI tools (`mutt`, `newsboat`, `ncmpcpp`) in a standalone tiled window. * Runs a console calculator in a standalone floating window. * Displays the cheat sheet with the most common key chords in a standalone floating window. With these granted, type `super + F1` or `super + Home` to get started on my `sxhkd` keys (as noted in the chapter about the basics of my BSPWM). You should already be up-and-running with the custom desktop session. But there is still much to learn from the rest of this book. Let us review the choice of MATE (Maté) as the default option for the desktop environment. In the chapter about installing Debian 10 'buster' on your machine, I suggested you select MATE as a core part of your new system. The installer's major component selection should look like this: [x] Debian desktop environment [ ] ... GNOME [ ] ... Xfce [ ] ... KDE Plasma [ ] ... Cinnamon [x] ... MATE [ ] ... LXDE [ ] ... LXQt [ ] web server [ ] print server [x] SSH server [x] standard system utilities You may be wondering why I recommend this step: _is not the purpose of this manual to set up a custom BSPWM session?_ The reasons are basically these: 1. You get all the Xorg and GTK dependencies in place. You need these anyhow for running a graphical session and some of the most common application software, such as Firefox and Thunderbird. 2. You install some MATE programs that my custom desktop session makes use of. These are `caja` (file manager) and `mate-settings-daemon` (touched upon in the chapter about the Tempus themes). 3. You have a robust fallback option in case you need to use the computer without BSPWM (e.g. multiple users on a single computer). 4. Things like networking, the policy kit agent, and the xdg backend (matching programs to MIME types) are configured for you. ## What about minimalism? Minimalism is about striving to achieve a state of minimum viability, the least possible completeness, but not less. We still want something that works without any "gotchas" (edge cases where things do not perform at the desired standard). Installing a fallback DE at the very outset makes things simpler, more predictable and maintainable over the entire life-cycle of the Debian system; a system that can span multiple releases of Debian's "stable" distribution. Do not be a nag about some Internet meme. * Bloat is when you run a modified web browser as your text editor, or whatever the latest trend is with Electron-based applications and web apps. * Bloat is when your favourite web page eats up 50% of my CPU. * Bloat is Vim with a spaghetti code of plugins and concomitant settings that try to reinvent the wheel. * Bloat is a much-vaunted 'minimalist' program like `st` with a hodgepodge of patches pilled on top of it. * Bloat is every addition that actively detracts from the end goal of usability, such as fancy animations for every interaction, wanton use of transparency and blur effects, etc. Free software is about choices. Best we keep our opinions to ourselves and do what we consider appropriate for our particular use case. Enough with the misbegotten elitism and the smugness that certain communities actively cultivate. To my eyes, setting up Xorg is a task that falls outside the scope of dotfile management. Same with configuring the network stack and similar basic utilities. The moment we enter into that domain we start creating our own distro or bespoke sysadmin setup. Let Debian handle that, while we focus on stowing the dotfiles in place, so that we may get our desired workflow going. Personally, I do not keep track of the package count to determine the 'bloat' installed on my machine. This is not a game where the user with the fewer packages wins. If a piece of software is genuinely useful and is known to be fairly stable and maintained, then I keep it. ## Why specifically MATE and not "foo"? MATE is the most complete GTK-based desktop environment after GNOME, _without using the GNOME shell stack_ (in which case we should mention Cinnamon and Budgie). This is to be expected due to its heritage: it is the fork and subsequent continuation of the GNOME 2 code base. MATE's main apps are very competent tools. The file manager, _Caja_, is a good piece of software. The document viewer, _Atril_, gets the job done. Same with the image viewer, _Eye of MATE_. Meanwhile, the archive manager, _Engrampa_, will handle compressing or decompressing data without any problem. Make no mistake: MATE is far from perfect. Otherwise it would be frivolous to set up a _custom_ desktop session. Compared to the other options provided by the Debian installer: * MATE is ideal for a stable distro such as Debian 10 (same with Xfce). It is developed at a rather slow yet steady pace, perfectly complementing the stability and predictability of the underlying OS. Debian is a poor fit for tracking DEs like GNOME and KDE Plasma that are developed at a somewhat fast pace. For instance, the GNOME version in 'buster' (3.30) is already one release behind upstream and will be two by the end of summer 2019. The gap will continue to widen every six months, _ceteris paribus_. Similar story with KDE Plasma. * MATE is fairly modular, much like Xfce. You can use its individual components without having to run the entire session. And unlike Xfce, MATE has already completed the migration to GTK3 (last checked on 2019-07-01). * Unlike GNOME (GNOME 3), MATE is committed to preserving the traditional desktop metaphor instead of turning the desktop into an oversized phone UI. It also is less taxing on system resources. * Compared to Xfce, MATE does not need to pull in packages from another DE in order to function properly. Whereas Xfce lacks its own archive manager, document viewer, calculator, among others. * MATE is more lightweight than GNOME and at least on par with—if not lighter than—KDE Plasma, without losing out on any of the core functionality. For our use case, being light-yet-complete and self-contained is exactly what we are looking for. My point is clear: MATE is the best GTK-based option we could go for. I only use `bash` as my CLI shell. It is ubiquitous. It works. And, because I have no need for fancy extras or technology previews, my shell's setup has no plugins, external add-ons, or other obscure extensions (same as with my Vim and Tmux, by the way). ~/cpdfd $ tree -aF shell shell ├── .bash_profile ├── .bashrc ├── .inputrc ├── .local/ │   └── share/ │   └── my_bash/ │   └── dircolors ├── .profile └── .xsessionrc There are a couple of files that are only read at startup: `.xsessionrc` and `.profile`. The former exists for the sole purpose of sourcing the latter. In `.profile` I have instructions to: * Use my `.bashrc`. * Add `~/bin` to the `PATH`. * Launch the keyring (mostly for storing SSH credentials). `.bash_profile` is also just a placeholder for sourcing the `.bashrc`. Meanwhile, `.inputrc` provides some basic options for slightly modifying the behaviour of the command line interpreter. These concern the (1) reduction of key presses for tab completion, (2) textual and colourised information about files and directories, (3) colours that enhance the visuals of tab-completion's feedback. ## About the .bashrc As is the norm with my dotfiles, the `.bashrc` is heavily documented. This is an overview of its headline options: * `PAGER` and `MANPAGER` is `less` with the option to quit after reaching the end of a file and trying to read further below. * The `EDITOR` is `vim`, while its GUI variant is the `VISUAL`. * The default browser is whatever is defined by the MIME list (should be `firefox-esr`). * The prompt is simple and super effective: ` $ ` by default or, if running via an SSH connection, it becomes slightly more informative with `@: $ `. * Enable tab-completion when starting commands with `sudo`. Then I have a comprehensive list of aliases, that you may or may not like to keep in place. Run `alias` from the command prompt to get the full list and/or filter its output accordingly. Here is a sample: ~ $ alias | grep 'apt' alias aac='sudo apt autoclean' alias aar='sudo apt autoremove -V' alias adl='apt download' alias afu='sudo apt full-upgrade -V' alias ai='sudo apt install' alias air='sudo apt install --reinstall' alias ali='apt list --installed' alias alu='apt list --upgradable' alias ama='sudo apt-mark auto' alias amm='sudo apt-mark manual' alias apc='sudo aptitude purge ~c' alias ar='sudo apt remove -V' alias ard='apt rdepends' alias as='apt search' alias ash='apt show' alias au='sudo apt update' alias aug='sudo apt upgrade -V' alias aulu='sudo apt update && apt list --upgradable' alias auu='sudo apt update && sudo apt upgrade -V' alias auufu='sudo apt update && sudo apt upgrade -V && sudo apt full-upgrade -V' The most opinionated aliases are those that change the default behaviour of core utilities like `cp`, `mv`, `rm`. They make their output verbose and introduce a prompt for confirming user input where appropriate. I believe these are sound defaults, as they protect you from accidents. That granted, you can always run an unmodified command by prepending a backslash `\`. For example: # This uses the alias for `cp` ~/cpdfd $ cp README test 'README' -> 'test' ~/cpdfd $ # This uses the original `cp` ~/cpdfd $ \cp README test ~/cpdfd $ Finally, there are a few functions: * `man()` configures `man` to show some colours and formatting for the various parts of its syntax. * `cd()` tells `cd` to list in a clean way the directory's contents when entering it, including the hidden items, though not the implicit ones. * `backupthis()` can be run as `backupthis ` to create a copy of the target, with a time stamp as its extension and identifier. That just about covers it. I wish you luck on your PATH; make sure to get HOME safe. Both Tmux and Vim are essential to my workflow. It is thus pertinent to inform you about their respective configuration files so that you know what to expect. This is with the proviso that you already are familiar with these tools. ## About my tmux setup Let's start with the terminal multiplexer. It is the first thing you will interact with when you log into the session and type the key chord `super + return`: ~/cpdfd $ tree -aF tmux tmux └── .tmux.conf 0 directories, 1 file Only its config is distributed with my dotfiles, which is another way of saying that _I do not use any plugins whatsoever_. What is provided by the program itself is more than enough. To send commands to `tmux` you must typically start by first pressing its prefix key, which I have kept to the default of `Ctrl + b` as it is the one that causes no issues with other programs' main functionality, _in the way I use them_. To be clear, `Ctrl + b` does interfere with a couple of commands: (a) the command line motion for moving one character backwards and (b) Vim's full page back scroll. So you press the prefix key, then release it and you can then either access the command prompt by inputting the colon `:` sign or typing one of the many key sequences that are assigned to direct actions (see table below). In the configuration file, modifier keys are shortened. So `Ctrl + b` is written as `C-b`, `Alt` is `A`. Note that `Shift` is not used directly, but is instead implied by the use of a capital letter (just to be sure: Shift inserts the majuscule of the given letter). Here are the main key bindings to get you started: # Those that involve C-b (prefix) # ------------------------------- s # split current pane horizontally v # split current pane vertically ### these are similar to Vim's C-w {s,v} S # split the whole window horizontally V # split the whole window vertically x # kill current pane C-x # kill all panes except the current one r # reload the tmux conf m # mark active pane C-m # toggle maximise active pane ### the default is z (too close to x) A-{1-5} # switch to one of the five layout presets E # evenly spread out active and adjacent panes c # create a new window (windows contain panes) b # break pane from current window ### default is ! J # the opposite of break-pane Tab # swap active pane with the previous one C-Tab # swap active pane with the marked one a # sync input across panes in the current window # Keys without the prefix # ----------------------- A-{h,j,k,l} # navigate panes in the given direction A-S-{h,l} # move to left/right window C-Space # enter copy-mode ### use Vim keys to scroll, select/copy text Read `.tmux.conf` for the entirety of my settings and custom key bindings. That file is heavily documented, as is the norm with practically every item in my dotfiles. Now if you are thinking that you do not need a terminal multiplexer and have no time to learn how to use one, I urge you to think again. This is a great skill to master. It greatly improves the overall use of the terminal. It is a skill that is highly portable. It will come in handy in a variety of situations whereas, to be blunt, learning `bspwm` may not be particularly useful outside the narrow confines of a custom desktop session. Tmux is superior to a standard terminal because it offers unique capabilities: * Persistent local/remote sessions (even if you close the terminal or log out). Once you use this, there is no going back. * Advanced management of a large number of pseudo-terminals by leveraging window splitting (panes) like a tiling window manager, pane grouping per window (the equivalent of tabs/workspaces), and sessions (sessions hold windows, windows hold panes). * Scriptability including the possibility to send key sequences to running applications (I use this to source my .vimrc when I perform a live theme change, as noted in the chapter about my Tempus themes). ## About my Vim setup That last piece of advice holds true for `vim` as well. Spend some time learning its basics. Over time you will become proficient at editing text. And here is another piece of advice, before we delve into the specifics of my Vim setup: set a very high bar for the use of plugins or, as in my case, do not use plugins _at all_. Also avoid copy-pasting stuff without carefully considering the ramifications. The more comfortable you are with the generic program, the higher the portability of your knowledge. Vim is meant to be used as the standard UNIX editor that is available in virtually every such machine out there. Straying too much from the defaults might impede your ability to work effectively under circumstances that are not under your immediate control. Now on to my customisations. ~/cpdfd $ tree -aF vim vim ├── .vim/ │   ├── colors/ │   │   ├── tempus_autumn.vim │   │   ├── tempus_classic.vim │   │   ├── tempus_dawn.vim │   │   ├── tempus_day.vim │   │   ├── tempus_dusk.vim │   │   ├── tempus_fugit.vim │   │   ├── tempus_future.vim │   │   ├── tempus_night.vim │   │   ├── tempus_past.vim │   │   ├── tempus_rift.vim │   │   ├── tempus_spring.vim │   │   ├── tempus_summer.vim │   │   ├── tempus_tempest.vim │   │   ├── tempus_totus.vim │   │   ├── tempus_warp.vim │   │   └── tempus_winter.vim │   └── spell/ │   ├── el.utf-8.spl │   ├── el.utf-8.sug │   ├── en.utf-8.add │   └── en.utf-8.add.spl └── .vimrc 3 directories, 19 files A quick rundown of my very short and simple `.vimrc`: * I stick to the default key bindings. * I expect Vim to ask for confirmation when closing a modified buffer. * I use tabs instead of spaces for indentation, setting the width of the tab character to be equal to four spaces. I used to use spaces when I first started using a text editor, because that was the default. However, experience suggests that tabs are semantically more appropriate for indentation. The tab key inserts its own character, which can have an arbitrary width defined by the program that reads it. In short, tabs are better for indentation, while spaces are better for tabular layouts such as the `tmux` key table I presented above. * The text width is 72 blocks long. This is particularly important for writing good `git` commit messages. And, because `git` is designed with email in mind, this line length is ideal for sending plain text email, such as with `mutt`. In general, this line length also makes sense for comment blocks in your code, because it makes them easier to read without having to rely on non-standard things like text-wrapping (so, for example, hitting `gqip` will format inside the given paragraph, while `gq` does the same over the given selection). * Sentences in a paragraph start with two spaces after a period or full stop. This is better visually when typing in a monospaced font. The various parsers, e.g. Markdown to HTML, know how to convert that to a single space, just as they know how to turn hard line wraps between consecutive lines of text into uniform paragraphs (a blank line marks a new paragraph). * Syntax highlighting is on and uses my Tempus themes. Do not edit this part manually, as it will be changed when running `tempus` or its `tempusmenu` interface (see chapter on Tempus themes). Read the `.vimrc` for an in-depth understanding of my customisations (it is a straightforward, well-commented config). ## Neither Tmux nor Vim is an OS Now you may be wondering how it is possible to use Tmux and Vim without plugins and all the accoutrements of a modern workflow. The answer is rather simple: let Tmux+Vim be specialised tools and leave the rest to other programs. Do you really need Vim's sub-par approach to multiplexing (its own approach to splits, buffers, tabs) when you can just be a `tmux` ninja? What, you need more than that? Let me tell you about this nice program called BSPWM… Why do you require a plugin to check `git` information inside Vim when you can just use the command line? Open a new `tmux` split and type `git status`, `git log`, `git diff`… You need to commit only parts of a changed file? Know that `git add --patch` is your friend. In the same spirit, use the core utilities like `cd`, `ls`, `find`, `grep`, `cp`, `mv`, `rm`. Keep things simple and avoid feature creep. Let the text editor _edit text_. Keep the multiplexer true to its spirit of managing terminal sessions. If you truly need an extensible, fully-customisable integrated development environment, then you should seriously consider GNU Emacs (which is a Lisp interpreter that implements a text editor among _many_ others). Of course, there are scenaria where a plugin makes a program better for the task at hand. My point is that you should be very picky about your choice of external functionality. GNU/Linux is a powerful OS (Emacs too!). You do not need to incorporate every kind of feature in the core tool. Perhaps there are other operating systems that make things difficult for the power user: if you are using one of those, then a pile of plugins is the least of your troubles. As a closing remark, let me leave you with a joke I once heard about Emacs (a tool that I genuinely like and will eventually incorporate in my computing life): its name is an allusion to its design that involves active use of modifier keys… Escape, Meta, Alt, Control, Shift. The panel that appears at the uppermost area of the viewport is drawn by `lemonbar`. This is a beautifully simple tool. On the face of it, all it does is place an empty bar at either the top (default) or bottom of the screen, while offering a syntax for formatting any output it may display. It is up to the user to add content to it. This is where my `melonpanel` comes into play. It is a shell script that fetches and parses some useful information about the system and the running session, and lays it on the bar. Each snippet of info is internally referred to as a "module" and has its own dedicated logic inside the script. The modules are the following: * BSPWM report about the workspaces, nodes, their flags and state (see next section about it). * Battery status and current capacity. * Core temperature. * Speaker volume strength and status. * Keyboard indicators for alternate layout and caps lock. * Date and time. This is what a module looks like: # Core temperature. _temperature() { command -v acpi > /dev/null || return 1 local therm_label therm_status therm_label='T:' therm_status="$(acpi -t | awk -F '[[:space:]]+|,' '{ print $5 }')" therm_status="${therm_status:0:2}" # Up to 59 degrees celcius keep text colour same as default. 60-79 # turn the colour red on normal background. Else turn the whole # indicator red. case "$therm_status" in [12345][0-9]) echo "$therm_label ${therm_status}°C" ;; [67][0-9]) echo "$therm_label %{F$color1}${therm_status}°C%{F-}" ;; *) echo "%{F$background}%{B$color1} $therm_label ${therm_status}°C %{B-}%{F-}" ;; esac } ## How the modules are placed on the panel All modules will grab some piece of text and clean it up so that it looks nice on the panel. However, each individual module _does not output directly_ to the named pipe where the data is read from. Instead, all modules are called from `_modules()`, which I need to explain a bit: _modules() { while true; do echo "B" "$(_battery)" echo "T" "$(_temperature)" echo "D" "$(_datetime)" echo "K" "$(_keyboard)" echo "V" "$(_volume)" sleep 1s done } You will notice that each individual item echoes a majuscule and then the output of the module it references. These capital letters are important because they demarcate each set of data in the named pipe, making it possible to put the right thing in the right place. We see this in practice at `_melonpanel()`, specifically this part: while read -r line ; do case $line in B*) # battery status bat="${line#?}" ;; T*) # temperature therm="${line#?}" ;; D*) # current date and time date="${line#?}" ;; K*) # keyboard layout (en or gr) key="${line#?}" ;; V*) # volume level vol="${line#?}" ;; What this does is identify the part that contains the data of each module and assign a variable to it. The variables are then placed on the panel with the following: _panel_layout() { echo "%{l}$wm%{r}$key $bat $therm $vol $date " } Focus on the content of the `echo`. The syntax `%{l}` places things on the left, while `%{r}` aligns them to the right (this notation is provided by `lemonbar`—see its manpage). I believe this pretty much covers the essentials of how `melonpanel` is designed. As with all my scripts, this too is heavily documented. So do read it. That granted, I admit that `lemonbar` is not the most user-friendly, point-and-click program out there. But hey, neither is BSPWM, Xterm, Tmux, Vim, etc. ## The BSPWM module On the left side of the panel lies the set of indicators that report on the status of the window manager (based on the output of the command `bspc subscribe report`). This is what you see when starting the session (note that I have taken care to use the appropriate spacing, so that all typographic elements are evenly spread out): [1] * The numbers correspond to the names of the available desktops. Because I have implemented _dynamic desktops_ (see chapter about the advanced features of my BSPWM), there is only one desktop on the panel. If you navigate to desktop number two, the module will be like this, _if desktop 1 is empty_: [2] * If desktop 1 is occupied, the module will be: 1^ [2] * The desktop inside square brackets (and also drawn with a bold font) is the current one, while the caret sign denotes an occupied desktop. Next to the desktop numbers there is at least one asterisk. If the desktop contains windows, then the asterisks are two: * The first asterisk always indicates the layout of the desktop. If the view is set to monocle, then the letter `M` will take the place of the asterisk. The layout cycles between tiled and monocle, but because the former is what we normally use, I have opted to hide the `T` behind the asterisk and only display the `M`. * The second asterisk contains information about the active window's flags. The flags I define in my `sxhkdrc_bspc` are: Sticky, Private, Locked, Marked (see `man bspc` for their meaning). When a flag for the current node is active, its initial letter is displayed on the panel. More than one flags can be activated at once. If all indicators are toggled on at once, you will see something like this: [1] 2^ * SPLM Urgent and unfocused desktops are denoted by the column sign and are coloured red: [1] 2# * * On multi-head setups (e.g. dual monitor), the BSPWM report will divide desktops and their corresponding indicators per monitor. Combined with the above, we get the following: [1] 2^ * L 4- 5# 6^ M SP Notice how the indicators that display the `*` (asterisk) are visible for each set of desktops. Also look at the use of another typographic marker next to desktop 4: the hyphen is for showing the _focused desktop on the unfocused monitor_. The letter `M` in this case concerns desktop 4. Same with the node flags `S` and `P`. While `L` applies to the focused node in desktop 1 and the asterisk next to it informs us that the layout is the default, i.e. tiled. I believe all this will become easier to grasp once you start using the system. For the record, this design bears close resemblance to the status line of my `tmux` setup. ## Panel transparency By default, the panel is opaque, though I have made it fairly trivial to add a transparency effect to its background. The following is an excerpt from the relevant `melonpanel` section: _melonpanel < "$melonpanel_fifo" | lemonbar -u 1 -p -g "x${melonpanel_height}" \ -F "$foreground" -B "#ff${background:1}" -f "$fontmain" -f "$fontbold" -n "Melonpanel" & Take a closer look at the segment of the command that controls the background colour: `-B "#ff${background:1}"`. I have designed it so that you can tweak its alpha value, which is governed by the `ff` part. This is hexadecimal notation and means that the alpha channel is set to full, which translates to complete opacity. `00` is the opposite. Try replacing `ff` with `aa` to get some subtle transparency, or with `55` for a more pronounced effect. Possible values for each digit are: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f. A running compositor is required to enable transparency effects (I use `compton` as already mentioned in previous chapters). As a rule of thumb, light themes will require a greater adjustment than dark themes to create a noticeable see-through style. The choice of wallpaper will also affect your perception of it. For changes to be applied, reload the panel with the key chord chain `super + e ; p` (as explained in the chapter about the basics of my BSPWM). Otherwise, you can always just use `tempusmenu` to switch to another Tempus theme (as discussed in the chapter about my themes), thus forcing a panel reload. ## Known issues Sometimes, seemingly at random, the panel will not be hidden when entering a window's full screen view. The less-than-ideal workaround is to reload `melonpanel` with the key chord chain `super + e ; p`. This seems to be an upstream bug. Another thing to bear in mind is that upstream `lemonbar` does not support proportional or outline fonts (e.g. the "DejaVu" family). It can only display fixed-size, else bitmap, typefaces such as "Terminus". If you have followed the instructions in the chapter about installing the core packages, you will have `xfonts-terminus` available on your system. This is an optional dependency, as the panel will fall back to the `fixed` typeface which comes pre-installed with Debian. I just think that Terminus is more consistent and is better suited for such a UI task (see ANNEX below for Lemonbar with proportional fonts). Finally, you may notice that `pgrep melonpanel` always lists two running processes. This is because it is running `_modules()` (mentioned above) as well as `bspc subscribe report` that displays desktop information and the like. The report needs to be its own process because it has its own synchronicity, controlled by the window manager itself (please let me know if there is a way of merging every modules functionality into a single process). ## ANNEX for lemonbar-xft I maintain a personal fork of `lemonbar` with support for Xft (the fontconfig library). This basically means running the panel using proportional/outline fonts. * I have a [video where I talk about my fork](https://protesilaos.com/codelog/2019-06-24-demo-lemonbar-xft/). * I also provide information on [how I forked lemonbar-xft](https://protesilaos.com/codelog/2019-06-24-lemonbar-xft-howto/). * And here is how to [compile Lemonbar Xft on Debian 10 Buster](https://protesilaos.com/codelog/2019-06-23-lemonbar-xft-new/). I will not provide any further information herein. **I do not encourage you to compile stuff from random sources or to create what is known as a "FrankenDebian".** I use this fork as part of my own system and am prepared to deal with any possible breakage. If you are not or do not trust my fork (you should not trust any random source), then stick with the package provided by Debian: it includes the upstream code that only uses bitmap fonts. Typography is essential to a good computing experience. I would even argue that type is the irreducible factor of a computer's user interface. But let's keep things in focus: good fonts are essential to a setup that strongly emphasises the use of a text terminal. My _opinionated_ font-related settings are stored in my dotfiles' "fontconfig" directory (stow package). These take precedence over system-wide defaults that are defined in `/etc/fonts/`. ~/cpdfd $ tree -aF fontconfig/ fontconfig/ └── .config/ └── fontconfig/ ├── conf.d/ │   ├── 10-hinting-full.conf │   ├── 10-sub-pixel-rgb.conf │   ├── 11-lcdfilter-default.conf │   ├── 20-unhint-small-hack.conf │   ├── 45-generic.conf │   ├── 45-latin.conf │   ├── 50-enable-terminus.conf │   ├── 60-generic.conf │   ├── 60-latin.conf │   ├── 80-condensed-large-dejavu.conf │   └── README └── fonts.conf 3 directories, 12 files The `fonts.conf` includes basic rules for adding emoji character support to all generic font family definitions: serif, sans-serif, monospace. Inside `conf.d` we find the important rules (sorry, I do not really care about emoji). Some file names will suggest what each rule is about. For example, `50-enable-terminus.conf` overrides the default settings that _disable_ fixed-size typefaces (bitmap fonts). The file `20-unhint-small-hack.conf` applies to the "Hack" typeface. It concerns small point sizes. This rule serves mostly as an example, but also because that family is my preferred choice of monospaced font. You can copy and then edit the rule to match whatever typeface fails to display properly at certain point sizes. On the other end, `80-condensed-large-dejavu.conf` will substitute the default DejaVu fonts for Serif and Sans with their condensed equivalents. This makes either DejaVu variant better as a fallback font for UI elements and long form texts, because it removes the rivers of white space that run through its widely-spaced letter forms. The file names that start with "45" attribute a generic family to each typeface. For example, I assign "Hack" to the "monospace" group. While the "60-\*" rules concern the priority of font selection. Here is a snippet of XML that I will explain: sans-serif Roboto Noto Sans Liberation Sans DejaVu Sans When selecting the fontconfig alias "sans-serif" (or just "Sans"), the actual typeface is, in order of priority from top to bottom: Roboto, Noto Sans, Liberation Sans. If none of these are installed or available, then DejaVu Sans shall be used instead. As already discussed in the chapter about installing core packages, these are the fonts I use and consider solid defaults: sudo apt install fonts-firacode fonts-hack fonts-roboto fonts-dejavu fonts-dejavu-extra fonts-noto-color-emoji fonts-symbola xfonts-terminus Note that `fonts-symbola` is mostly required to display symbols in terminals that have trouble with ambiguous characters. ## Modifying the font configurations My settings are tailored to my hardware and aesthetic preferences. I strongly encourage you to spend some time inside my `conf.d` to get a sense of how things work. For more, run `man fonts-conf`. Settings provided by Debian, are stored at `/usr/share/fontconfig/conf.d/`, while the _applicable rules_ are defined in `/etc/fonts/conf.d/`. Graphical applications read the configuration files that are specific to their toolkit. I only have GTK apps, so we get these files: ~/cpdfd $ tree -aF gtk gtk ├── .config/ │   ├── gtk-3.0/ │   │   └── settings.ini # Irrelevant files ├── .gtkrc-2.0 # More files that do not concern fonts You only need to check `.gtkrc-2.0` and the GTK3 `settings.ini`. The default typeface is the fontconfig alias "sans" at 10 point size. If you have followed the instructions in the chapter about installing core packages, "Sans" or "Sans-serif" should stand for "Roboto" (package is `fonts-roboto`). The panel (top bar) only supports bitmap fonts, as explained in the chapter about the top panel. It is configured to use Terminus (`xfonts-terminus`) else fall back to whatever the "fixed" typeface is. The notification daemon—`dunst`—uses "Sans-10", in large part because its configuration file is static and cannot run shell logic. A sans-serif font is the safest default. Besides, notifications can display a big chunk of text, where a monospaced font will make the notification's box expand out of proportion. We want them to be discreet. All the above notwithstanding, you should know that not all applications out there will faithfully follow your rules. For example, Flatpak apps will use their own settings because they do not read from the user's font configurations. Graphical tools that are launched with escalated privileges will read from the root user's configs. And so on. ## What makes a good choice of font Some closing notes on the criteria that determine the choice of my default typefaces: Hack and Roboto. * Good unicode coverage. Support extended latin and greek glyphs _at minimum_. * Have at least two weights: regular and bold. Ideally, also support true italics, or at least oblique forms with some effort put into them, rather than some procedurally generated slanted variant of the regular letters. * Be legible at small point sizes. Do not create rivers of white space that flow through the text at larger sizes. * Have good typographic colour. In other words, do not have too thin letter forms. Typefaces that are too thin are harder to read, make colours less distinct from each other, while they tend to create a certain "halo effect" around letter forms when using them against a light backdrop. * Do not have a very high x-height. I need to easily tell apart miniscules from majuscules. * Do not rely too much on serifs and fine details. Such letters can become the standard when our displays have a pixel density that is at least as good as printed text. Until then, they can be hard to read in certain conditions. * For monospaced fonts: all vaguely similar glyphs should be easy to tell apart, such as `0`, `o`, `O`, `i`, `I`, `l`, `L` `1`, `s`, `5`… * Be available in Debian's `main` archives. Comply with Debian's Free Software Guidelines. All this can be summarised as "do not be frivolous; be frugal, be accessible, and get the job done". ## ANNEX on Xterm fonts You will notice that I recommend installing `fonts-firacode`. This is the typeface I use inside my terminal emulator (Xterm), because it has excellent support for box-drawing capabilities, which is particularly important for `tmux`. Xterm has a _very rare_ bug that you will only encounter if you use Greek letters and only with certain font and point size combinations. I have submitted a detailed report on the [Greek pi (π) and box-drawing bug](https://protesilaos.com/codelog/2019-07-01-xterm-greek-pi-bug/). The bug notwithstanding, I have made sure that my `.Xresources` includes the necessary settings that work around this problem. As such, "Hack" and "DejaVu Sans Mono" will cope just fine with all typography-related requirements inside of Xterm. The Music Player Daemon is a program that stores information about your music collection. It manages metadata and playlists of currently queued songs or ones that are saved. MPD uses a server/client model. To interface with it we need to use one of the many available client programs. The simplest one is `mpc`, a console utility with basic functionality for querying the daemon's status, handling media controls, and the like. A more feature-rich client is `ncmpcpp`, which also runs in the console. ## Basic configuration MPD may be run as a system-wide server and can be controlled remotely as well. For my use case, all I need is a local, user-specific setup. This is what we will be doing. Assuming you have followed the instructions in the chapter about installing the core packages, you should have these in place: sudo apt install mpd mpc ncmpcpp mpdris2 python-mutagen playerctl Then switch to the base of my dotfiles' directory and proceed to create symlinks for the music-related programs: ~/cpdfd $ stow music Now you need to run a series of commands to configure `mpd` in accordance with our per-user requirements. Start by disabling the `systemd` service, since we autostart `mpd` from within the `bspwm` session: sudo systemctl disable mpd Now switch to the local config directory: cd ~/.config/mpd Create the directory where saved playlist data is stored: mkdir playlists Generate the files `mpd` needs in order to run: touch database log pid state sticker.sql Configuration is done! You might need to reboot for changes to take effect. ## Update the database To update the `mpd` database (assuming the presence of audio files at `~/Music`) either run `mpc update` in a terminal or type `ncmpcpp` and then press `u`. If your music is in a different directory, edit the relevant path in `~/.config/mpd/mpd.conf`. ## Basics of ncmpcpp The "Ncurses Console Media Player C++". To start interfacing with this excellent tool, simply type `ncmpcpp` in a terminal, or use the key chord chain `super + x ; 5` (see the chapter about the basics of my BSPWM). To play music, learn how to use `ncmpcpp` by studying the corresponding manpage. I typically switch to screen 4, by hitting `4`, then `A` and hit enter. This inserts an empty prompt which adds all available music to the playlist. Then I toggle on repeat mode with `r`, random playback order with `z`, and a 5 second cross-fade with `x`. If you do not like `ncmpcpp`, I highly recommend `cantata`, a graphical MPD front end using the Qt toolkit which, however, does not integrate well with my mostly GTK- and text- based environment (as such, Cantata is not part of my custom desktop session). ## Why we also need mpc The comparatively simpler `mpc` tool performs the role of a remote control. We use it to assign key chords with which to control `mpd` even when no client is running. In a similar fashion, `mpc` provides a simple way of querying the status of the server for the sake of, say, displaying information about the current song on the panel (see the chapter about the top panel). ## The MPRIS bridge By default, `mpd` does not behave like most up-to-date music players in the GNU/Linux world. Put differently, it cannot be controlled by dedicated media keys, nor interact with specialised tools that might be offered by the desktop environment. This kind of functionality is part of the MPRIS protocol. To make `mpd` a good citizen, we have fetched the `mpdris2` package as well as a dedicated, console-based program for controlling MPRIS-aware applications: `playerctl`. With these in place, the Music Player Daemon (and all other MPRIS-aware media players, like the ever-popular `vlc`) can be controlled using the keyboard's dedicated media keys. See `man playerctl` for more demanding types of interaction. The key chords are defined in my `sxhkdrc` as explained in the chapter about the basics of my BSPWM. ## Peace of mind MPD is great because while it is powerful and can cater to the needs of the most avid audiophile, it also works seamlessly once you set it up. I prefer it over its alternatives because it is very much _laissez faire_, to the point you almost forget it is even there. When you log back in to the custom BSPWM session, `mpd` will be up and running, waiting for your input in a paused state (or stopped, in case that was the last interaction with it). You do not need to keep any window open, nor run some resource-hungry web app just for the sake of playing audio from your local collection. Hit the keyboard's dedicated key for `play` or type `super + down arrow`: music will start playing, while you get on with your work (do not forget to see my `sxhkdrc` for the relevant key chords). Part of my customisations concerns `newsboat`, a decent RSS/Atom reader for the console. If you have never heard what an RSS or Atom feed is, it is a data stream that is meant to be read by client programs, known as "readers" or "feed readers". Whenever the source that publishes the feed makes a new entry (publishes something), the stream is populated with the new content, which the reader can then fetch. This makes it possible to keep track of multiple websites from a single interface. Having all that in the terminal makes things even better. ~/cpdfd $ tree -aF newsboat/ newsboat/ └── .config/ └── newsboat/ ├── config ├── queue ├── themes/ │   ├── tempus_theme_dark.theme │   └── tempus_theme_light.theme └── urls -> /path/to/my/symlink # not part of the dotfiles 3 directories, 5 files All you need to get started is to first put things in place: ~/cpdfd $ stow -v newsboat LINK: .config/newsboat => ../dotfiles/newsboat/.config/newsboat Then to actually read some feeds, you must _manually create_ a `urls` file at `~/.config/newsboat/` with a single feed source per line, like this: https://www.debian.org/News/news https://bits.debian.org/feeds/atom.xml https://www.gnu.org/software/guix/news/feed.xml I personally **exclude this file from the dotfiles because it might contain sensitive information**. If you want to filter feeds, you can add one or more tags to them, with a space demarcating each entry: https://www.debian.org/News/news "Distro" https://bits.debian.org/feeds/atom.xml "Distro Community" https://www.gnu.org/software/guix/news/feed.xml "GNU Linux Distro" Tags are used to aggregate content from multiple sources: # A catch-all filter for unread items "query:Unread Articles:unread = \"yes\"" # Some tag-specific filters "query:GNU plus Linux:tags # \"Distro\"" "query:ARBITRARY NAME OF FILTER:tags # \"Tag\"" Once you launch the program, either from the command line or with the key chord chain `super + x ; 4` (see chapter on the basics of BSPWM) you will start seeing news items pop up, grouped by source URL. From there you can use Vi motions or the arrow keys to select the desired item and either read it in place by hitting the `Return` key (`Enter`) or open it in the browser by hitting `o` (`firefox-esr` is the default and what I use). The config file is fairly simple, with each setting usually describing what it does: # General # ------- show-read-articles no show-read-feeds no prepopulate-query-feeds no feed-sort-order unreadarticlecount show-keymap-hint yes swap-title-and-hints no text-width 72 save-path "~/Documents/archived-articles/rss" browser /usr/bin/xdg-open %u confirm-exit yes display-article-progress yes For more, see the source for the actual configurations as well as `man newsboat`. PRIOR NOTICE: all the scripts referenced herein are discussed in greater detail in the chapter about my local `~/bin`. * * * All the colours you see are part of a project of mine called [Tempus themes](https://protesilaos.com//tempus-themes/). These are colour schemes for Vim, terminal emulators and relevant tools. They consist of sixteen hues that correspond to the standard escape sequences for terminal colour definitions, in order from 0 to 15: 0-7: black, red, green, yellow, blue, magenta, cyan, white 8-15: bright {black, red, green, yellow, blue, magenta, cyan, white} I have designed Tempus with the purpose of filling a perceived void in the theming space: that of accessible, functional, yet still presentable colour schemes. Tempus is designed to work well for as many users as possible, myself included. In more technical terms, the Tempus themes are compliant **at minimum** with the _Web Content Accessibility Guidelines_ (WCAG) level AA for colour contrast between foreground and background values. This stands for a relative luminance ratio of 4.5:1. That ratio is but a threshold as some members of the collection conform with the even higher standard of 7:1 (WCAG AAA). ## Accessibility is about good design To dispel any misconceptions, "accessibility" is not only useful for a subset of users. Accessibility is another way of describing thoughtful design. It benefits everyone. Being forced to read light grey on a white background or green text on a red backdrop is a major failure, indicating a lack of forethought and empathy with the user. For us who spend considerable amounts of time interfacing with a computer, a good contrast ratio is essential to a subconsciously pleasant session (just as with good typography, as discussed in the chapter about fonts). Whether you read, write, code, your eyes will appreciate the improved legibility of text on the screen. Try this: miscalibrate your monitor and/or your font configurations to make text look blurry and irritating to the eye. Work in that environment for a while to realise how much more painful it is. Eye strain is real, so do yourself a service by prioritising legibility over whimsy. If you are used to inaccessible colour combinations, you may find Tempus themes a bit too sharp at first. Give it some time: your eyes will adapt to the improved presentation. I know from experience, as I used to work with inaccessible themes. In fact, I had developed an entire collection of them: [Prot16](https://protesilaos.com/schemes/). Those were not designed with accessibility and functionality in mind. Some might even "look better" than the Tempus themes, but none _works better_. ## The Tempus themes collection As of this writing (2019-07-02) the Tempus themes collection consists of the following items (WCAG rating in parentheses): # Light themes dawn (AA) day (AA) fugit (AA) past (AA) totus (AAA) # Dark themes autumn (AA) classic (AA) dusk (AA) future (AAA) night (AAA) rift (AA) spring (AA) summer (AA) tempest (AAA) warp (AA) winter (AA) The one you get by default is Tempus Classic, which is a dark theme with warm hues. ## Tempus and my dotfiles With the exception of GTK widget and icon themes, Tempus is applied everywhere colours can be defined. Some notable examples are `bspwm`, `vim`, `tmux`, `newsboat`, `neomutt`, `dunst`, and my `lemonbar` script called `melonpanel`. Even GTK-based text editors are covered, such as `gedit` (GNOME default), `pluma` (MATE default), and `gnome-builder`. A shell script is responsible for changing themes across all those applications: it is aptly named `tempus`, which is a _backronym_ standing for "Themes Every Meticulous Person Ultimately Seeks" (in case you do not know, "tempus" is a real word in Latin). You can run `tempus` directly from the terminal by adding a scheme's unique name as its argument. For example, to switch to the light theme `day`, you would do: tempus day A slightly more convenient way is to use `tempusmenu`. This is a `dmenu` script that interfaces with the aforementioned command. It is bound to a hotkey sequence for your convenience. To invoke `tempusmenu`, type `super + e ; t` (hold `super` and press `e`, then release `super` and just press `t`—this is a key chord chain, as discussed in the chapter about the basics of my BSPWM). A menu with all available items will appear. Either type your choice and press enter or use the arrow keys (or CLI/Emacs motions) and press enter. My dotfiles are designed in such a way that the following changes will occur when performing a theme switch across the entire environment: * All running terminals will "live reload" their colours using escape sequences. Thanks to my `own_script_update_running_terminals`. Similarly, all running CLI programs like `vim`, `newsboat`, `neomutt`, `less` will gracefully adjust to the theme change. * My default terminal emulator, `xterm`, will also write the new colour definitions to its configuration file (also see the chapter about the default terminal). * The terminal multiplexer (`tmux`) will be instructed to reload its configurations in order to parse the new colours. * The top panel (`melonpanel`) will be re-run and display the new colours. Same with the notification daemon (`dunst`). * All running GTK applications, including Flatpaks, will convert to a light or dark variant of their current theme, depending on whether the selected Tempus theme is light or dark (assuming you followed the instructions in the chapter about installing core packages). So if you choose `totus`, for example, which is dark text on a light background, the GTK themes will also be light, and vice versa. This is courtesy of a running settings daemon. If you have followed the instructions in the chapters about installing Debian 10 'buster' and adding the core packages, this is the `mate-settings-daemon`. * The wallpaper will change accordingly, if you have defined images at `~/Pictures/theme/{dark,light}.jpg`. All this happens in the blink of an eye. If you care about the specifics (or wish to contribute) you need to examine the script that does the heavy lifting: `tempus`. In my opinion, this is a very neat feature. Having it bound to a key chord makes it even better. Now if you need any convincing of why you should ever be able to switch themes on the fly, try coding using a dark theme under direct sunlight… ## Additional resources The Tempus themes is a standalone project that happens to be integrated with my dotfiles. There are a number of `git` repos. The specialised ones are specific to the program they reference: * [Tempus themes](https://gitlab.com/protesilaos/tempus-themes). The main content hub, which provides information about the project, screen shots, and offers all available ports in a central place. * [Tempus themes GTK3 Source View](https://gitlab.com/protesilaos/tempus-themes-gtksourceview3). For GTK-based text editors like Gedit, Pluma, Mousepad. * [Tempus themes GTK4 Source View](https://gitlab.com/protesilaos/tempus-themes-gtksourceview4). Only known implementation is for GNOME builder though other apps will follow once the migration to GTK4 gains momentum. * [Tempus themes Kitty](https://gitlab.com/protesilaos/tempus-themes-kitty). * [Tempus themes Konsole](https://gitlab.com/protesilaos/tempus-themes-konsole). * [Tempus themes ST](https://gitlab.com/protesilaos/tempus-themes-st). * [Tempus themes Tilix](https://gitlab.com/protesilaos/tempus-themes-tilix). * [Tempus themes URxvt](https://gitlab.com/protesilaos/tempus-themes-urxvt). * [Tempus themes Vim](https://gitlab.com/protesilaos/tempus-themes-vim). * [Tempus themes Xfce4-terminal](https://gitlab.com/protesilaos/tempus-themes-xfce4-terminal). * [Tempus themes Xterm](https://gitlab.com/protesilaos/tempus-themes-xterm). Also see the [Tempus themes Generator](https://gitlab.com/protesilaos/tempus-themes-generator): the tool that produces all these ports and the place where you could contribute new templates, code, ideas. ## Known issues The "live reloading" of all running instances of `vim` is contingent on `tmux` (see chapter on my Tmux+Vim combo). If you are running the text editor outside of the multiplexer's control (e.g. a GUI), then the theme switch requires manual intervention. Either exit Vim and enter again or run `:source ~/.vimrc`. To fix this, I would need a program that can send key chords to running applications: this is possible within `tmux`, as can be seen in `tmux_update_vim`. There is `xdotool`, but my tests did not yield promising results… If you are using the `mate-terminal` (recall that `xterm` is my default and recommended option) and try to open a new instance of it while the theme switch is underway, it will likely retain its older colour scheme in the database, even if it might catch the step where terminals are live reloaded via escape sequences. In such a case the theme switch needs to be performed anew or you must manually run `own_script_mate_terminal_setup`. An integral part my dotfiles is the `bin` directory. It includes various scripts that I have written for use in my custom desktop session. Some of these are essential to various functions and workflows. Others are convenient extras. ~/cpdfd $ tree -aF bin bin ├── bin/ │   ├── bspwm_dynamic_desktops* │   ├── bspwm_external_rules* │   ├── bspwm_focus_mode* │   ├── bspwm_multifaceted_operation* │   ├── bspwm_reorder_desktops* │   ├── bspwm_smart_move* │   ├── bspwm_smart_presel* │   ├── clr* │   ├── dotsmenu* │   ├── flatpakmenu* │   ├── gev* │   ├── melonpanel* │   ├── nbm* │   ├── own_script_bspwm_node_resize* │   ├── own_script_bspwm_per_host_configs* │   ├── own_script_current_keyboard_layout* │   ├── own_script_laptop_dual_monitor* │   ├── own_script_local_build_tempus_themes* │   ├── own_script_mate_setup* │   ├── own_script_mate_terminal_setup* │   ├── own_script_notify_send_mpc_status* │   ├── own_script_print_colour_table* │   ├── own_script_run_dmenu_xcolors* │   ├── own_script_run_passmenu_xcolors* │   ├── own_script_update_environment_theme* │   ├── own_script_update_running_terminals* │   ├── own_script_update_tmux_running_vim* │   ├── passmenu* │   ├── poweroptionsmenu* │   ├── ptp* │   ├── sbg* │   ├── sbgmenu* │   ├── stm* │   ├── stmmenu* │   ├── tempus* │   ├── tempusmenu* │   ├── tmr* │   ├── tmux_update_vim* │   ├── toggle_compton* │   └── toggle_screenkey* └── .local/ └── share/ └── my_custom_ui_font.sh* 3 directories, 41 files Let's first get out of the way the `my_custom_ui_font.sh`. This file contains the font definition that is used in my various `dmenu` implementations. The code part: if [ -n "$(fc-list 'dejavu sans condensed')" ]; then my_font_family='DejaVu Sans Condensed' my_font_size=12.5 fi my_custom_ui_font="${my_font_family:-sans}-${my_font_size-12}:${my_font_weight:-regular}" Now a few words about the scripts, with the proviso that you can always learn more about each time by studying the source code: * Scripts that start with "own_script" are labelled as such for a variety of reasons: (1) their function is ancillary to something else, (2) I might develop a better replacement, (3) avoid naming conflicts, (4) be descriptive about what each item is about. * Scripts whose name begins with "bspwm\_" implement various advanced functions for the window manager. These are documented in the chapter about the advanced features of my BSPWM. * In principle, all items have inline documentation, except `passmenu` which is provided by another source referenced therein. * While on the topic of `passmenu`, this is a `dmenu` interface for copying to the clipboard a password stored with `pass`. Such an awesome feature! To put it succinctly, this is what sold me on both the power of `dmenu` and the idea of a dedicated password manager that works seamlessly with core UNIX utilities. * Many of these scripts are assigned to custom key bindings. Better check my `sxhkdrc` and/or `sxhkdrc_bspc` to find out the relevant key chords (as explained in the chapter about the basics of my BSPWM). * The items `nbm`, `sbg`, and `sbgmenu` cover various ways of setting the desktop backdrop. I guess it is better explained in this short video: [My UNIX-y ways to wallpapers](https://protesilaos.com/codelog/2019-02-09-unix-ways-wallpapers/). * The `stm` and `stmmenu` are tools for handling my task list, in accordance with my own methodology. They are complementary to each other. This short video of mine should be enough to get you started: [UNIX way to task management](https://protesilaos.com/codelog/2019-02-17-unix-ways-todo/). * `gev` must be run in the terminal to print a table with the status of all `git` repositories inside the user's home directory. Better see this video: [Demo of my Git's Eye View](https://protesilaos.com/codelog/2019-03-25-gev-demo/). * The `own_script_run_*` commands are wrappers around `dmenu_run` and `passmenu` respectively. They are meant to customise the looks to my liking, in order to keep things consistent. * If you have Flatpak applications on your system, `flatpakmenu` will provide a nice interface to launching them. * `melonpanel` is the script that draws the session's panel. It is what provides content/information to `lemonbar` for display on the screen. This is discussed at length in the chapter about the top panel. * Then there are a few items that are meant to integrate my themes into the various parts of the running session (as explained in the chapter about the Tempus themes): `tempusmenu` is a front end to selecting the theme you want; `tempus` does the actual work of applying the new theme across all supported programs; running terminals are re-coloured with `own_script_update_running_terminals`; while the running Vim sessions inside of Tmux are re-styled with the use of `tmux_update_vim`. * `poweroptionsmenu` provides an interface for logging out of the session, switching users, locking the screen (using `slock`), rebooting, and shutting down the system. * `toggle_compton` will enable or disable the display compositor. A very useful feature under certain circumstances where running `compton` is detrimental to the task at hand. For instance, I use this to shut down the compositor when I am screen casting. * `toggle_screenkey` is another on/off switch for the program it references. * `ptp` is a script that prints a table with the colour palette of the active Tempus theme. The table is "context-aware", so that it displays information depending on the width of the running terminal. * `clr` calculates the contrast ratio between two colours. You run it by passing two arguments to it, each representing a colour that is written in valid hexadecimal RGB notation. * `tmr` is a very simple timer. Run it with a single argument that represents a valid unit of time in seconds, minutes, hours, such as `tmr 10m`. Once the time has elapsed, it will print a message informing you of the time it started and end. It will also ring an alarm for a few seconds. Finally, it is worth pointing out that the quality of these scripts may vary considerably. The newer the script, the better it is. This is all part of a learning process as I am not a programmer by trade. Despite that, I hope my efforts on this front are enough to set you up and running on a custom desktop session centred around the Binary Space Partitioning Window Manager. My dotfiles' stow package called "bin" includes the following set of scripts that alter the behaviour of the window manager: ~/cpdfd $ tree -aF bin bin ├── bin/ │   ├── bspwm_dynamic_desktops* │   ├── bspwm_external_rules* │   ├── bspwm_focus_mode* │   ├── bspwm_multifaceted_operation* │   ├── bspwm_reorder_desktops* │   ├── bspwm_smart_move* │   ├── bspwm_smart_presel* # Trimmed output Here I explain what each item does and how it is implemented in my system. All hotkeys mentioned herein are defined in my `sxhkdrc_bspc`. ## Dynamic desktops By default, BSPWM uses a fixed number of desktops. A set is assigned to a monitor at startup. This is a perfectly usable design, especially for single-monitor setups. It can, however, be inefficient: * You seldom need, say, ten desktops at all times. Your normal work requires only three or four of them. So why keep the rest? And why try to work around this by retroactively concealing them from the `bspc` report, the panel, etc.? * On multi-head setups, you might find it preferable to decouple desktops from monitors. You might, for instance, require five desktops on the larger monitor and only one on the smallest one. Again, why commit to a specific number at startup and try to adapt your workflow to it. Dynamic desktops solve these _potential_ issues. You start with a single desktop per monitor and go from there in accordance with your evolving requirements. The script is designed to insert/remove desktops on a per monitor basis. This means that its operations are always confined to the focused monitor. As such, if you are on desktop 1 on monitor one, and switch to desktop 2 (using `super + {0-9}`), then desktop 2 will be placed on monitor one as well. If you wanted to have it on monitor two, you would need to bring focus to it first (cycle through monitors with the key chord `super + comma`). Alternatively, you can spawn a desktop on the next monitor without switching focus to it, by pressing `super + ctrl + {0-9}`. Such a desktop will hold a receptacle (discussed below). Sending the focused window to a dynamically-created desktop is straightforward: `super + shift + {0-9}`. Again, this is limited to the given monitor, while I have decided not to implement a direct action for sending the focused window to a new desktop on the next monitor. There is a trade-off between feature completeness and complexity. In short, dynamic desktops should have a natural feel to them. You just move around and they adapt accordingly. As a bonus, I have added a "back-and-forth" behaviour, so if you input the same number of the desktop twice while using `super + {0-9}`, focus will move to the last desktop and back again. Dynamic desktops and the concomitant back-and-forth behaviour were inspired by `i3wm`. ## Reorder desktops This is a simple script that will reorder the desktops in numerical order. You will probably have no use for this, because it is already part of `bspwm_dynamic_desktops` from where it was extracted. Still, it is provided as a standalone utility in case you ever find yourself manually performing the necessary `bspc` actions that add/remove desktops. ## Manual tiling (smart presel and external rules) BSPWM automatically tiles windows in a spiral layout. Older windows move inwardly, while the newest one occupies the outermost part of the spiral (at the given level). However, the window manager also offers a couple of features for manually placing windows on the screen. Those are referred to as preselections and receptacles respectively. A preselection is, by default, an area that is a fraction of the focused node. The preselection provides feedback on where the _next_ window will be placed. When that event takes place, the focused window is split at the given ratio and focus switches to the new window. In contradistinction, receptacles are empty frames that occupy an area of the screen, as per the tiling scheme, until they are expressly told to host a window, at which point they cease to exist. Think of them as placeholders for windows yet-to-be. To send an item to the position of the receptacle, we need to pass a specific command: the unscripted tiling method will not affect receptacles. I have decided to carve a niche for each of these features and design distinct courses of action around them. The two scripts involved in the process are `bspwm_smart_presel` and `bspwm_external_rules`. "Smart presel" contains logic to evaluate the following and lead to the relevant consequences: * Is there a marked window (using the node flag "marked", which is assigned with `super + a ; m`)? If yes, then use the first that matches this criterion. Otherwise operate on the focused window. * Does a receptacle exist? If yes, use it to place the window in its stead. Else put the window in the position of the first matching preselection. A preselection is given with `super + alt + {h,j,k,l}`. It is cancelled by inputting the same direction twice. To insert a receptacle, press `super + n ; r`. Remove it at any time with `super + n ; super + r` (you can then resize nodes, adjust the split ratios etc. as mentioned in the chapter basics of my BSPWM). If a preselection is available, then a new receptacle will be placed there. To place the marked or focused window in the position of the available receptacle or preselection type `super + n ; i`. The difference between the two is revealed when performing such actions across desktops. A receptacle will not call focus to itself, whereas a preselection will. The assumption that underpins this design is that a receptacle can be placed in a desktop, then a program that has a rather slow startup time is launched (e.g. the web browser). The user is free to switch to another desktop in the meantime. This way you can continue your work and get back to that slow application at a later point. Multi-head setups render this apparent. For example, you "pre-load" the smaller monitor, switch to the larger one, work there and the application will appear on the small monitor, taking the place of the receptacle. No interruptions, no things moving around. This is precise and deliberate. Note that for such a scenario you do not need to press `super + n ; i`, because the external rules come into play, automatically placing the next window in the position of the first available receptacle (or preselection if no receptacle exists). You can, nonetheless, still use `super + n ; i`. Place a receptacle in a new desktop, switch to another and then type that key sequence to insert the marked or focused window there. At any rate, all this is a means of fleshing out BSPWM's notions of manual tiling actions. You are free to tweak things to your liking. ## Multifaceted operations (multi-node actions) This is, dare I say, a beautifully simple script that facilitates window management over multiple selection paths. Its various actions are assigned to key chords and concern the following: * `super + n ; super + shift + r`: kill all receptacles (as opposed to only remove the last one, with `super + n ; super + r`). * `super + n ; super + q`: close all non-focused, non-marked windows on the focused desktop. This is an extension of the standard key for closing the focused window: `super + q` with the added bonus of respecting the "marked" flag (it is assumed you are marking windows for a reason). * `super + n ; super + shift + q`: same as above, but kills them instead. For context, the key for killing just the focused window is `super + shift + q`. * `super + n ; l`: assign the "locked" flag to all windows in the present desktop. A locked window cannot be closed with any of the commands mentioned earlier (though it _can be killed_). Recall from the chapter on the basics of my BSPWM that to assign such a flag to the focused window, you press `super + a ; l` (inputting twice toggles the behaviour). * `super + n ; shift + l`: remove the "locked" flag from all windows on the present desktop. * `super + n ; m`: summon all "marked" windows, regardless of where they are, to the present desktop. You can mark a window by passing to it that flag: `super + a ; m`. * `super + n ; super + {0-9}`: bring all the windows of the given desktop (the given number) to the focused one. This is an extension of the basic key for focusing desktops: `super + {0-9}`. * `super + n ; super + shift + {0-9}`: send the windows of the present desktop to the given one. This incorporates the dynamic desktops mentioned above, so inputting a number will just create that desktop on the focused monitor. With those granted, I recommend you try learning things one command at a time. Otherwise you will most certainly mix up all the key chords and key chord chains. Start with the basics. You will then realise that the more advanced ones build on that foundation. ## Smart move You move focus around windows with `super + {h,j,k,l}`. Additionally, you swap the position between the focused window and the one in the given direction with `super + shift + {h,j,k,l}`. These are standard actions that are provided out-of-the-box. Their two limitations are: 1. They do not work with receptacles. 2. You cannot remove a window from the automatic tiling scheme. You must instead switch places with an existing one. So what I have decided to do is provide a wrapper around the standard commands for focusing and switching windows, but also account for receptacles. If you input the keys that switch windows in a direction where no window exists, a receptacle will be spawned to occupy that place. Inputting the same direction again will move the focused window that is adjacent to the receptacle to the space occupied by the latter. At that point the receptacle will disappear. This provides an intuitive way of moving a window to the position of an adjacent receptacle, rather than having to memorise a key chord chain (though that still has its use case for instances where you do not want to move a window adjacent to a receptacle). Furthermore, this offers the upside of creating three column/row layouts by just moving things around. Consider this standard layout for three windows: _____ _____ | | | B | | A | |___| | | | C | |___| |___| You can focus B or C and input `super + shift + l` to insert a receptacle to their right. Do so again to move the adjacent focused window there, to get a three column layout. You can then even out the proportions of the splits between the windows with `super + s ; b`. Try working with `bspwm_smart_move` for a while. If you find that it poses an impediment to your workflow you can find easy-to-follow instructions inside `sxhkdrc_bspc`. ## Focus mode This is a "distraction-free" environment that removes the top panel, window gaps, and any padding from the desktop. All you see is windows with _overlapping borders_ between them. The idea is to remove all complementary elements and focus on the content of your work. For example, I often use this when I am doing long-form writing. Toggle the focus mode with `super + e ; f`. ## Is BSPWM the best tiling window manager? Short answer: it depends. Long answer: You cannot possibly address such questions in abstract. Much hinges on the desired workflow and the needs each user has. One's disposition must be accounted for: whether they want to experiment and script certain patterns of behaviour, and the like. The purpose of this chapter, and this book at-large, is to make a point about the degree to which we can approximate a desktop environment by utilising disparate programs in a synergistic way. BSPWM works perfectly fine without scripting anything. It does, nonetheless, offer that option, which opens up a range of possibilities for advanced window management. That is all from my side. Thank you for reading through the pages of _Prot's Dots for Debian_ (PDFD). You should now have a solid basis to build upon. Remember: we customise our session to improve our workflow. Efficiency is all that matters. What gets upvoted in various fora for \*NIX enthusiasts does not always work as well (e.g. low-contrast colour schemes, excessive transparency and wanton use of blur effects). I leave you with some links, just for the sake of completeness: * The canonical link to [PDFD](https://protesilaos.com/pdfd) (part of my website). * [My website](https://protesilaos.com/), where I publish all sorts of things apart from libre software stuff. * Source files for _Prot's Dots For Debian_: 1. [PDFD repo](https://gitlab.com/protesilaos/pdfd). 2. [Site repo](https://gitlab.com/protesilaos/protesilaos.gitlab.io). * The [Code for PDFD](https://gitlab.com/protesilaos/cpdfd) contains the latest fixed release of my dotfiles. It was our reference point throughout this book. * [My dotfiles](https://gitlab.com/protesilaos/dotfiles) is where I push regular changes to my custom desktop session. I include them in a "fixed release" when I feel they are ready for broader adoption. * [Tempus themes](https://gitlab.com/protesilaos/tempus-themes). This is just the main repo, which includes information about the entirety of the project, as noted in the chapter about the Tempus themes. </div>