Single-tasking workflow in Linux with DWM

In a series of Linux-related articles recently, I have provided a number of strategies to eliminate distractions and superfluous features in your workflow. The strategies largely rely on ultra-minimalist command-line tools. Here I wish to expand upon this list with more discoveries.

As I have demonstrated in my action-oriented workflow post, the less easy options you have at your reach, the more likely you maintain attention on your immediate task.

My goal has consisted of maximizing attention on the one screen/application containing your work, eliminating the easy shortcuts of switch to some different tab/window/buffer, or even drifting your visual focus to any source of other information of non-critical value.

I emphasize the elimination of easy distractions. Clearly, if you have total control of your machine (root access), no amount of firewall restrictions, file-system permission manipulations, or window-environment limitations can restrict you from circumventing your own labyrinth. But in my case at least, I’m satisfied having eliminated the easy options.

When composing a document, for example, an extreme variant of an action-oriented workflow would consist of the single text-buffer occupying your entire screen (in my case the VIM buffer), with no other visual stimuli to distract your attention, no possibility of de-maximizing the window or switching to any other document or application. This is commonly known as the kiosk mode, in reference to public terminals.

I don’t necessarily insist on the extreme kiosk variant. In the course of your task, you may need to reference some truly critical material beyond your document, or switch workflows entirely without having to take drastic measures to exit the kiosk mode, such as restarting your machine or even your windowing environment. I will only mention that such a workflow definitely is possible to realize provided you have root control of your system. Meanwhile, however, I will provide you with a viable compromise.

DWM window manager and a single-tasking form of operation

DWM is a product of, a German group that maintains and develops ultra-minimalist tools of lean coding standards, many available in the standard package repositories. The intriguing aspect of their applications is the configuration. All configuration takes place in the C source code, specifically in a config.h header file.

At some point, I considered the practice of storing configuration internally in the code, simply stated, a poor practice, used temporarily in the course of development, perhaps, but unheard of in quality production applications. However, having considered the philosophy, I have been sold on this not only not being a necessarily poor idea, but in certain cases, quiet beneficial. As stated in their philosophy, storing the configuration in the source carries security and speed benefits. I see logic in that. Recompiling their utilities is a question of milliseconds or seconds on modern hardware, eliminating the ancient (90’s era) concerns to the respect of slow compilation. And considering the infrequency with which you would modify your configuration, once configured to your fancy, I see the lack of external configuration files quiet cohesive with my pursuit of action-oriented workflows.

Back to DWM. It is as light of a window manager as it gets. In fact, I have used the awesome window manager for a few years, itself a direct inspiration of DWM but based on the Lua interpreted language. Along with Xfce before that, I have considered the two extremely light, but DWM reached new depths (or heights) in that sense. In the default state, DWM features no menus, no notification bar, and nothing but three layout options, controlled entirely via shortcut combinations. In fact, additional features require software patches.

I type this post in a DWM session, having stripped the configuration of most but the critical options to simulate a semi-kiosk mode. I eliminated all but one tag (for those unfamiliar, windowing environment tags typically refer to the different virtual desktops one may transition between), and eliminated all but one layout - that of all applications automatically occupying the entire screen. I further eliminated options to resize or switch between windows, and left no shortcut to execute any application but via an already-open terminal. How does this work in practice?

As my X-session initiates DWM, I’m greeted with an absolutely blank desktop. Pressing a shortcut combination, a terminal opens, occupying the entire screen. Any further application I open from there, be it another terminal, or an external application via the terminal, it will respectively occupy the entire screen and assume focus. The only way to return to the previous window or terminal is to terminate the active window, via a shortcut (or exit command). If I open a web browser, I must conduct the interaction and close it before control returns. The workflow has taken a single-tasking full-screen appearance.

Here I include the relevant sections of config.h that I’ve severely stripped down to achieve this:

static const char *tags[] = { "1"};

static const Layout layouts[] = {
    /* symbol     arrange function */
    { "[M]",      monocle },

static Key keys[] = {
    /* modifier                     key        function        argument */
    { MODKEY,                       XK_p,      spawn,          {.v = dmenucmd } },
    { MODKEY|ShiftMask,             XK_Return, spawn,          {.v = termcmd } },
    { MODKEY,                       XK_b,      togglebar,      {0} },
    { MODKEY|ShiftMask,             XK_c,      killclient,     {0} },
    { MODKEY|ShiftMask,             XK_q,      quit,           {0} },

static Button buttons[] = {
    /* click                event mask      button          function        argument */
    { ClkLtSymbol,          0,              Button1,        setlayout,      {0} },
    { ClkStatusText,        0,              Button2,        spawn,          {.v = termcmd } },

Everything I’ve achieved with DWM, I could have achieved with the Awesome WM in also stripping it down of most configuration and shortcut options. However, reconfiguring Awesome is a question of simply updating the external configuration and restarting the environment without even compromising state. Reconfiguring DWM, however, is a question of recompiling and restarting the entire X-session - not as easy or compelling, hence I’m far more likely to respect the imposed limitations.

W3M, Surf, Screen, and case against browser tabs (again) and multiplexed terminals

Having restricted this window-environment level of distraction, what about the application-specific distractions such as browser tabs or multiplexed terminals?

As I have previously written, tabs are a bad idea for focus. I have already transitioned to a W3M text-based web browser workflow with less focus on tabs. For those pages you absolutely must view in a graphical browser, I incorporated a W3M shortcut to initiate a Surf browser. Also a product of, Surf is another super-minimalist browser, entirely key-stroke based, having no menus and no possibility of tabs.

With respect to multiplexed terminals, I naturally refer to the Tmux session-based terminal multiplexor, on which I’ve relied for the previous 9 years or so. Lately, I have come to consider stacks of multiplexed and multi-windowed terminals not so beneficial for focus. I’ve spent much of the previous 9 years mindlessly transitioning between different terminals. It resembles a provocative hacker’s playground, but achieves little in terms of single-tasked focused attention. I’ve worked around these distractions by leveraging the zoom feature, causing the current terminal occupy the whole screen, or self-discipline, but am leaning towards abandoning the multiplexing feature altogether, and transitioning to Screen. Screen is an equally powerful session terminal manager, but with what I consider crude multiplexing features, enough for me to abstain from their usage.

Disabling access to external VTM terminals

Linux power users may already be aware of the + accessible virtual terminals to which you can normally escape even in the course of locking your window session. This enables you to not only escape to another terminal outside X, but also start multiple parallel X-sessions (window environments). You can disable this by modifying the /etc/X11/xorg.conf with the following:

Section "ServerFlags"
    Option "DontVTSwitch" "True"
    Option "DontZap"      "True"


This may sound quiet obvious, but the above strategies I mention benefit single-tasking workflows, and may devastate system-admin, research-heavy, or interaction-oriented workflows, requiring at least some easily-attainable degree of multi-tasking.

Fortunately, a DWM session initiates in a matter of milliseconds on modern hardware, and you could even have multiple compiled DWM binaries to choose between more strict or more ‘entertaining’ workflows. Now, as long as you’ve disabled the virtual-terminal switching mentioned above, you cannot invoke parallel DWM (or any X) sessions, which is key for committing to the current workflow until some point of closure.