The i3 Window Manager

31 Jan

Part three of a series.

i3 is a tiling window manager. That's how it advertises itself, but dynamic and floating both apply, too.

On a minimal system like mine, the windowmanager is most of the working environment. To determine how well it supports my workflow and integrates with my other utilities, I have to use it for a while. Longer than planned, I simply never got around to testing the next windowmanager or even going back to my old favorite openbox. Which is a good sign - i3 is usable.

A fairly recent version of i3 is in most distributions' repositories, a simple

sudo apt install i3 # (metapackage)
or
sudo pacman -S i3-wm i3status i3lock

should be enough.

I3 comes with a session file, so you should be able to choose it at login. If you don't use a login manager, you can use the method described here.

At first login you will be asked a few questions; enough to get you going and be able to at least start a terminal & editor.

Some clickable screenshots:

I3 does not have any "eye candy"; windows have single-coloured, square borders, which change colours depending on context. They do have titlebars though, a feature I've always found useful (and not vain). Despite being outwardly minimalistic, i3 has loads of features; I barely scratched the surface with my single-monitor setup and simple usage habits. I mostly switch workspaces and use tiling in a 50/50-two-windows-side-by-side manner. Sometimes I use the scratchpad and rarely more than two windows per workspace. Windows open side-by-side. The side where the next window will open is highlighted. I can switch that between horizontal and vertical, which enables me to set up 3 window in a sort of master/slave/slave manner, but anything beyond that just baffles me.

Nevertheless, i3 manages simple requirements well. I always have the feeling that beginners are taken into account, and sane, up-to-date defaults are being used. Some effort is being made to integrate it into the already existing linux desktop landscape, instead of taking a gruff take-it-or-leave-it stance. Have a cursory glance at the setup (man page, config file) and just start using it, and it will be a satisfactory experience.

I3 is very well documented. It would go beyond this article to explain it all, but the userguide is well written and up-to-date.

A standard i3 install comes with a few utilities:

$ ls /usr/bin/i3*
/usr/bin/i3
/usr/bin/i3-config-wizard
/usr/bin/i3-dmenu-desktop
/usr/bin/i3-dump-log
/usr/bin/i3-input
/usr/bin/i3-migrate-config-to-v4
/usr/bin/i3-msg
/usr/bin/i3-nagbar
/usr/bin/i3-save-tree
/usr/bin/i3-sensible-editor
/usr/bin/i3-sensible-pager
/usr/bin/i3-sensible-terminal
/usr/bin/i3-with-shmlog
/usr/bin/i3bar
/usr/bin/i3status

They all have their own separate man pages ;-)
Most notable is i3bar which provides the panel, and i3status which comes as a seperate package (at least on archlinux) and provides content for i3bar (but can be used independently, too). That also means that other utilities can provide content for i3bar, most notably conky and py3status (but since i3 has gained a lot of popularity since, lots of replacements exist).

I3 does not cater to users' menu requirements. A common solution is to use dmenu_run (part of dmenu). I've been doing well with that, but I do miss an XDG menu sometimes. I also miss the ability to define root window clicks.

The standard i3bar+i3status is thought-through, as minimalistic as possible, yet offering as much info as necessary. It works really well on my low resolution netbook screen, but on my home desktop I feel a little unsatisfied. After a few failed attempts at adding extra elements (e.g. media player info) I just replaced the whole thing with tint2. It works well enough, but i3 has some non-standard ways of handling workspaces and such, and tint2 glitches around that. But all i3 keybinds still work, and switching workspaces fixes things again for tint2, so for the time being I'm happy with it.

Some applications do not work well with i3 (although this seems to be a common theme with tiling window managers). I guess it has something to do with EWMH and I suspect some defining features of tiling windowmanagers simply go against these rules. With i3 I'm having big problems with virtualbox (client windows scale themselves for no good reason and setting them to floating in ~/.config/i3/config does not seem to be enough to fix that) and smaller, similar problems with other apps.

I don't remember anymore what the out-of-the-box keybinds were, but it didn't take long to adapt either myself or the configuration.
There is only one config file at ~/.config/i3/config; it contains everything: autostart apps (conky, root window background...), keybinds, i3bar, colouring (no separate theme files!).
That might seem a little cumbersome, but:

  • one can use variables (!)
  • the syntax is very intuitive (I heard a developer say that they would test it on friends who aren't too computer-savvy, until they could make sense of it)
  • many things can be achieved with i3 itself and no other utilities, e.g. dmenu-like dialogs requiring user input

Here's my current ~/.config/i3/config:

# Please see http://i3wm.org/docs/userguide.html for a complete reference!

############## AUTOSTART STUFF ##############
exec --no-startup-id tint2 -c "~/.config/tint2/i3/tint2rc"
exec --no-startup-id sleep 10 && setroot --restore

############## VARIABLES ##################
set $mod Mod4
set $font ubuntu
set $dmenu exec --no-startup-id dmenu_run_history -fn monaco:size=10
#~ set $appmenu exec --no-startup-id menu.py
set $appmenu exec --no-startup-id jgmenu_run xdg
set $pacmenu exec --no-startup-id pacmenu
set $bg_act #005577
set $fg_act #dddddd
set $bg #222222
set $fg #bbbbbb
set $weather exec --no-startup-id /home/data/mygit/conky-itl-weather/startconky --toggle config/noto2.cfg
set $musicplayer exec --no-startup-id mocming
set $mixer exec --no-startup-id uam

############ GLOBAL SETTINGS #############################
# Font for window titles. Will also be used by the bar unless a different font
# is used in the bar {} block below.
#~ font -*-ohsnap-medium-r-*-*-14-*-*-*-*-*-*-*
font pango:$font 9

# Click To Focus
focus_follows_mouse no

# Use Mouse+$mod to drag floating windows to their wanted position
floating_modifier $mod

#~ hide_edge_borders smart

force_display_urgency_hint 1000 ms

############### EXEC KEYBINDS ##############
# start a terminal
bindsym $mod+Return exec urxvt

# start dmenu (a program launcher)
bindsym Shift+Return $dmenu
bindsym Shift+Control+Return $pacmenu
# bindsym $mod+d exec --no-startup-id i3-dmenu-desktop

bindsym Control+Mod1+w $weather
bindsym $mod+p $musicplayer
bindsym $mod+x $mixer

############### WINDOW KEYBINDS #################
# kill focused window
bindsym $mod+q kill

# change focus
bindsym $mod+Left focus left
bindsym $mod+Down focus down
bindsym $mod+Up focus up
bindsym $mod+Right focus right

# move focused window
bindsym $mod+Shift+Left move left
bindsym $mod+Shift+Down move down
bindsym $mod+Shift+Up move up
bindsym $mod+Shift+Right move right

# split in horizontal orientation
bindsym $mod+h split h

# split in vertical orientation
bindsym $mod+v split v

# enter fullscreen mode for the focused container
bindsym $mod+f fullscreen toggle

# change container layout (stacked, tabbed, toggle split)
bindsym $mod+s layout stacking
bindsym $mod+w layout tabbed
bindsym $mod+e layout toggle split

# toggle tiling / floating
bindsym $mod+Shift+space floating toggle

# change focus between tiling / floating windows
bindsym $mod+space focus mode_toggle

# focus the parent container
bindsym $mod+Control+p focus parent

# focus the child container
bindsym $mod+Control+c focus child

# switch to workspace
bindsym $mod+1 workspace 1
bindsym $mod+2 workspace 2
bindsym $mod+3 workspace 3
bindsym $mod+4 workspace 4
bindsym $mod+5 workspace 5
bindsym $mod+6 workspace 6
bindsym $mod+7 workspace 7
bindsym $mod+8 workspace 8
bindsym $mod+9 workspace 9

# move focused container to workspace
bindsym $mod+Shift+1 move container to workspace 1
bindsym $mod+Shift+2 move container to workspace 2
bindsym $mod+Shift+3 move container to workspace 3
bindsym $mod+Shift+4 move container to workspace 4
bindsym $mod+Shift+5 move container to workspace 5
bindsym $mod+Shift+6 move container to workspace 6
bindsym $mod+Shift+7 move container to workspace 7
bindsym $mod+Shift+8 move container to workspace 8
bindsym $mod+Shift+9 move container to workspace 9

# reload the configuration file
bindsym $mod+Shift+c reload

# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
bindsym $mod+Shift+r restart

# exit i3 (logs you out of your X session)
set $System System (l) logout, (s) suspend, (h) hibernate, (r) reboot, (Shift+s) shutdown
mode "$System" {
    bindsym l exec --no-startup-id i3-msg exit, mode "default"
    bindsym s exec --no-startup-id $Locker && systemctl suspend, mode "default"
    bindsym h exec --no-startup-id $Locker && systemctl hibernate, mode "default"
    bindsym r exec --no-startup-id systemctl reboot, mode "default"
    bindsym Shift+s exec --no-startup-id systemctl poweroff -i, mode "default"  

    # back to normal: Enter or Escape
    bindsym Return mode "default"
    bindsym Escape mode "default"
}
bindsym $mod+Shift+q mode "$System"

# https://wiki.archlinux.org/index.php/I3
bindsym $mod+PageUp [urgent=latest] focus

bindsym $mod+End move scratchpad
bindsym $mod+Home scratchpad show

# resize window (you can also use the mouse for that)
set $Resize Resize === Left: shrink width 10 === Right: grow width 10 === Up: shrink height 10 === Down: grow height 10
mode "$Resize" {
        # Pressing left will shrink the window’s width.
        # Pressing right will grow the window’s width.
        # Pressing up will shrink the window’s height.
        # Pressing down will grow the window’s height.
        bindsym Left resize shrink width 10 px or 10 ppt
        bindsym Down resize grow height 10 px or 10 ppt
        bindsym Up resize shrink height 10 px or 10 ppt
        bindsym Right resize grow width 10 px or 10 ppt
        # back to normal: Enter or Escape
        bindsym Return mode "default"
        bindsym Escape mode "default"
}
bindsym $mod+r mode "$Resize"

################# MOUSE ######################

bindsym --release button2 kill
bindsym --release button3 $appmenu
bindsym $mod+button3 floating toggle

############## WINDOWS ##################
for_window [class="SuperTuxKart"] floating enable
for_window [class="(?i)xcalc"] floating enable
for_window [title="(?i)alsamixer"] floating enable
for_window [title="FontForge"] floating enable
#~ for_window [class="(?i)keepassx"] floating enable
#~ for_window [class="VirtualBox"] floating enable

# https://wiki.archlinux.org/index.php/I3
for_window [window_role="pop-up"] floating enable
for_window [window_role="task_dialog"] floating enable

# Start i3bar to display a workspace bar (plus the system information i3status
# finds out, if available)
bar {
        # this section reduces the bar to a sort of dmenu-replacement for modifier actions (logout, resize)
        mode hide
        modifier none
        position top
        tray_output none
        workspace_buttons no

        font pango:$font 11
        #~ status_command i3status
        colors {
                # default colors
                background $bg_act
                statusline $fg
                separator #666666

                # colorclass       border  bg      text
                focused_workspace  $bg_act $bg_act $fg
                active_workspace   #333333 #5f676a $fg
                inactive_workspace #444444 $bg #888888
                urgent_workspace   #700000 #700000 #ffffff
                #~ binding_mode       #2f343a #900000 #ffffff
                binding_mode       $bg_act $bg_act $fg_act
            #~ separator #dddddd
            #~ background #222222
            #~ statusline #bbbbbb
            #~ focused_workspace #81a2be #81a2be #1d1f21
            #~ active_workspace #373b41 #373b41 #ffffff
            #~ inactive_workspace #282a2e #282a2e #969896
            #~ urgent_workspace #cc6666 #cc6666 #ffffff
        }
}

############# COLORS #################
# class                 border  backgr. text    indicator child_border
client.focused          $bg_act $bg_act $fg_act #2e9ef4   $bg_act
client.focused_inactive #335766 #335766 $222222 #4d8399   #335766
client.unfocused        #333333 #333333 #888888 #727D80   #333333
client.urgent           #700000 #700000 #ffffff #700000   #700000
client.placeholder      #000000 #0c0c0c #ffffff #000000   #0c0c0c

There's a lot one can do with this windowmanager, and I barely scratched the surface. I could very well go on using and customising it. But maybe because I know I still have many more to test, or maybe because i3 requires a particular usage scenario or mindset that I just don't have, I never got around to that. On the other hand this means it is quite usable with only a small effort of customisation!

I moved on to the next - fluxbox - and already miss the tiling. Placing & resizing windows manually is very time-consuming and annoying.

Next Post Previous Post