I noticed recently that when I am working on two screens, the only window manipulation I perform is to move a window from one screen to another. Every once in a while I would tile two windows on one screen, but I’d never have one window overlapping another. I’d chosen Gnome Classic sometime back because it was snappy and did a decent job of getting out of the way (and alt-tab wasn’t completely broken like in Unity), but it seemed like a tiling window manager would work better for me. So I went googling, narrowed the field of contenders down to xmonad, qtile and i3, tried xmonad, failed to make it stick, and finally ended up with i3.
And I am pretty happy with it. The other day I noticed sometime in the afternoon that the monitor on my left was attached to my main screen on the right side. Apparently, I’d spent most of the day without having occasion to move my mouse from one screen to the other. i3 makes it easy to move windows around workspaces and it’s possible to more efficiently get to the window you want compared to alt-tabbing. It also feels even faster than Gnome Classic.
On the other hand, i3 is just a window manager, and it is missing some of the functionality that the gnome shell provides. Here’s a quick run of how to make it work.
no display configuration UI
I learned to use xrandr some time ago because I was sick of the gnome display configuration UI, but if I hadn’t already known it, I definitely would have had to learn it when I started using i3, as there is no UI to change resolutions or position screens in relation to each other. The xrandr commands I use most often are:
This will list all outputs (i.e. monitors) and available modes for them.
xrandr --output VGA1 --mode 1680x1050
Set an output (VGA1) to a resolution (1680×1050, needs to be listed as an available mode for that output).
xrandr --output VGA1 --auto --left-of eDP1
Position one output (VGA1) to the left of another one (eDP1), and enable it with its preferred resolution (–auto flag). I execute this after I connect my monitor to my laptop.
xrandr --output VGA1 --auto --same-as eDP1
Same as above, but this makes one output display the same content as another. I use this after I connect to a projector.
no network manager, power manager and hardware keys
Sounds tough but turned out to be pretty simple, since the gnome tools play pretty well with i3.
exec --no-startup-id nm-applet exec --no-startup-id gnome-settings-daemon
Addings this to the top of .i3/config gives a network manager icon in the status bar (including wireless selector), as well as menu for switching keyboard layouts, and all the hardware keys (mute, volume) and automatic suspend on closing the lid work again.
exec --no-startup-id dropbox start
For extra goodness, this will start the dropbox daemon and add a dropbox icon to the status bar.
The only thing I used the gnome keyring for was to save myself from entering ssh key passphrases. Turns out that the ssh-add command does pretty much the same thing
exec --no-startup-id ssh-add
Adding this to the top of .i3/config will prompt for the passphrase of the default ssh key when logging in. It’s also possible to open other keys by giving a path.
exec --no-startup-id ssh-add /path/to/private/key
Or you can just execute the same command manually from the command line.
no program launch bar
i3 comes with dmenu for launching programs, but since I only ever launch a few programs anyway, I figured I’d go for a simple launch script.
#!/bin/bash exec "$@" &> /dev/null &
This will launch a program, orphan it, and redirect its output to /dev/null. In order to get completion to work with this script,
complete -F _command launch
I added this to my .bash_profile (assumes that the script is called ‘launch’).
no UI for shutdown, suspend, lock
I found this script that will build an UI using python and GTK. I had to modify it slightly, removing the call to i3-lock (which should be i3lock these days anyhow) when suspending, as I had already setup gnome to do the same thing back in the olden days. You can find the modified script here.
no system proxy
I am behind a proxy at work. Switching to i3 didn’t cause any trouble for most programs, since they were using the http_proxy et al. environment variables or had their separate proxy configuration (*grumble, grumble*). Chrome, however, will try to use the system proxy and cry piteously if it’s not available. Fortunately, it’s possible to set a proxy using command line options (–proxy-server, –proxy-auto-detect, or –proxy-pac-url), so I just created a bash alias to launch it with the correct proxy settings.
misc .i3/config settings
One thing I didn’t like about the default configuration was that when you move a window to a workspace that’s on another screen, the focus wouldn’t move with it. I modified the keybindings to make it work the way I wanted:
bindsym $mod+Shift+1 move container to workspace 1; workspace 1 bindsym $mod+Shift+2 move container to workspace 2; workspace 2 bindsym $mod+Shift+3 move container to workspace 3; workspace 3 ...
I also found the workspace back_and_forth to be pretty useful:
bindsym Mod1+Tab workspace back_and_forth
This will toggle between whatever two workspaces you were on last. I use it to switch between monitors quickly. On a related note, I find that usually whatever I have on one screen is related to what I have on the other, and when I want to switch workspaces I want to do it on both screens, so I added some shortcuts to do that quickly (assuming all the even numbered workspaces are on one screen and the odd ones are on another).
bindsym $mod+Control+1 workspace 1; workspace 2 bindsym $mod+Control+2 workspace 3; workspace 4 bindsym $mod+Control+3 workspace 5; workspace 6 bindsym $mod+Control+4 workspace 7; workspace 8 bindsym $mod+Control+5 workspace 9: workspace 10
This will also immediately make back_and_forth work when switching to another set of workspaces.
And I changed all the movement bindings to use the vim movement keys (hjkl, instead of jkl;). You can find the my config here, if you want to save yourself some typing (or vim macroing).
extra credit: fixing dbus issues in tmux
After switching to i3, I would get dbus related warning messages when launching some programs (like gvim) from tmux and gvim would also show me an annoying error box on startup (something about configuration). I didn’t look too deeply into what was going on and why, but I found out that adding
to my .bashrc fixes the problem.
So now I have this bastardized setup with i3 and gnome, which definitely won’t win any prizes for elegance or purity, but I am pretty happy with it so far. No more tabbing through a dozen applications just to tab past the one I wanted and then having to bend my pinky in unnatural ways to shift-alt-tab back. No more laboriously reaching for the mouse and dragging a window over to another screen.
Having said that, I will probably give Arch a spin in the not too distant future.
i3 works fine with keepass autotype if anyone’s wondering.