Programming, philosophy, pedaling.

Mini-post: Switching to i3 on Ubuntu

Oct 15, 2016

Tags: programming, workflow

Over the last two days, I’ve begun moving my desktop (which runs Ubuntu 16.04 LTS) from Unity, Canonical’s official graphical shell to i3, a tiling window manager. This post will document a few of the technical hiccups I’ve experienced along the way.


Over the past few years, I’ve made a habit of aggressively scripting menial tasks and binding keys for just about every common activity I do on my computers. I use and switch between tmux and urxvt’s tabbed mode proficiently, wrote my own session manager for Sublime Text, and keep a long list of configurations and aliases for my most common patterns.

Despite all this, I continued to use Unity, best known for its novice-friendly design and accessibility, as my primary graphical environment. I have some good excuses for this: inertia from my rat’s nest of configurations, simplicity of setup, and a coherent environment (i.e., GNOME).

However, as I continued to automate and refine my workflow, it became increasingly obvious that I was working against the limits of Unity (and GNOME) itself: I wanted layout persistence, easy-to-script startup applications, and keybindings for everything. Unity’s performance and quirks had also become sore points - the entire graphical system would slow to a crawl after about a week of uptime (often resulting in a soft lockup), and “disabled” components (the update prompt, launcher, crash logger) had a bad habit of reappearing after system updates or reboots.

Choosing i3

I ended up choosing i3 as my replacement to Unity for two reasons: it came recommended by people (online and off) whose opinions I trust, and because I was curious to try out a tiling window manager.

Installing i3 was extremely easy:

$ sudo apt-get install i3

I then logged out, selected “i3” from LightDM’s list of sessions, and logged into…a black screen.

Problems Experienced

I could fill an entire post with the problems caused by my initial fumbling with hotkeys and confusion of how i3 lays out containers and windows, but I’m going to limit this post to strictly technical problems that I came across during configuration and setup.

Compositing Glitches

Out of the box, i3 lacks a compositor. This wasn’t really noticeable, until I created a floating window and dragged it over Firefox, leaving a smear of artifacts in its wake.

To fix this, I installed compton:

$ sudo apt-get install compton

and ran it:

$ compton -cCGb --backend glx --vsync opengl

(Don’t forget to add that to your ~/.config/i3/config as an exec!)

That immediately fixed all artifacting issues, although workspaces changes sometimes still “stick” to Firefox’s window.

Using the Caps Lock as $mod

By default, i3 uses sets Alt or Super as $mod, which it then uses as the basis for every window manipulation hotkey it creates. Both are fine choices, unless you’re already using Alt for other combinations (like me) and have no super key (also like me).

To get around this, I simply created an ~/.Xmodmap file with the following contents:

clear Lock
keycode 66 = Hyper_L ! 66 is Caps_Lock
add mod4 = Hyper_L

and loaded it with xmodmap ~/.Xmodmap. No modification of i3’s configuration was required, since this assigns mod4 to the newly created “Hyper L”.

This step could also be done with XKB by editing /usr/share/X11/xkb/symbols/pc, deleting the xkb cache (/var/lib/xkb/*), and rebooting, but I personally prefer this approach.

Multiple Monitors

My desktop runs with two monitors, one on DVI (left, secondary) and the other on HDMI (right, primary). When I logged into i3 for the first time, the direction of the two was reversed - HDMI was on the left, and DVI was on the right.

This was fixed with a single xrandr invocation:

xrandr --output DVI-0 --left-of HDMI-0

(Don’t forget to add that to your ~/.config/i3/config as an exec!)

i3 treats each screen as its own workspace, in contrast with the Unity (via Compiz) approach of stitching the two together into one coherent entity. This was a little difficult to get used to at first, but has the advantage of letting me switch only one screen at a time (e.g., to change music while keeping my development screen visible). I replicated my most common use case (changing both screens simultaneously) with a bit of a kludge:

# switch to workspace
bindsym $mod+1 workspace 1L, workspace 1R
bindsym $mod+2 workspace 2L, workspace 2R
bindsym $mod+3 workspace 3L, workspace 3R
bindsym $mod+4 workspace 4L, workspace 4R
bindsym $mod+5 workspace 5L, workspace 5R
# etc...

# move focused container to workspace
bindsym $mod+Shift+1 move container to workspace 1L
bindsym $mod+Shift+2 move container to workspace 2L
bindsym $mod+Shift+3 move container to workspace 3L
bindsym $mod+Shift+4 move container to workspace 4L
bindsym $mod+Shift+5 move container to workspace 5L
# ...
bindsym $mod+Control+1 move container to workspace 1R
bindsym $mod+Control+2 move container to workspace 2R
bindsym $mod+Control+3 move container to workspace 3R
bindsym $mod+Control+4 move container to workspace 4R
bindsym $mod+Control+5 move container to workspace 5R
# etc...

Not very pretty, but it fits my use case well. In the future, I might look into stitching my screens together.

Media Keys

In Unity, I had my media controls bound as Control+<Arrow Key>, where Up and Down were volume, and Left and Right were backwards and forwards. I also had Control+End bound as play/pause.

I was able to get my volume control back immediately with some simple bindsyms in i3’s configuration:

bindsym Control+Up exec amixer -D pulse sset Master 10%+
bindsym Control+Down exec amixer -D pulse sset Master 10%-

Getting my track control bindings back took a little bit more effort. I ended up “importing” my original GNOME bindings by starting gnome-settings-daemon with the rest of my session:

exec --no-startup-id gnome-settings-daemon

Oddly enough, gnome-settings-daemon wasn’t installed by default. I have no idea how Ubuntu was loading my settings previously (Edit: probably through unity-settings-daemon).

Even more oddly, this didn’t work for my Control+End binding - that one still doesn’t work.

Final Thoughts

Since I’ve only been using i3 for a little over 48 hours, it’s far too early to say whether I like it or not.

That being said, I’ve found it surprisingly easy to use so far. The key combinations are slightly different, but the window motions are essentially the same ones that I enabled in Compiz on Unity long ago. I also really like stacking mode, especially for keeping multiple projects open and easily accessible. i3status/i3bar is also pretty neat, although I haven’t configured it much yet.

You can find my i3 configuration file here (it’ll be updated as I continue to experiment).

- William