xmonad Experience + i3-like config

I recently moved from i3 to xmonad. This post is about what I feel and my configuration.

Things I like

  • There are tons of community packages to extend xmonad
  • It’s a AUTO tiller. life becomes easier.
  • Since it’s a auto tiller, it gives you a lot of interesting layouts. I really enjoy the Accordion and Magnify layout.
  • The tabbed sublayout is cool. You can easily sink a window into a tabbed stack. You can do that in i3 too but it’s not easy and confusing.
  • Named workspaces: in i3 if a workspace has no windows in it and is unfocused, then it is gone. Thus it’s kinda pointless to name the workspaces like dev, www, doc etc. They are simply not there until you manually put something into it.
  • I’m learning haskell so configuring xmonad is a good practice
  • The config file is written in haskell and compiled into xmonad, I don’t know if it is necessarily faster and more robost, but if feels quite so.
  • The way xmonad treats “fullscreen”. For example, tell a youtube video to go fullscreen, in i3 the video will then take over the whole monitor. While in xmonad, the video only takes over its panel space, the other panels on the monitor are still visible.(unless you explicitly tell it to take over the monitor (Mod+Space))
  • The Grid select is really cool.



  • it’s harder to set up at the beginning
  • xmonad by default, doesn’t provide much.
  • polybar doesn’t work with xmonad(there is a workaround but tricky). This is not much of an issue tho, xmobar is good enough.

Things I’m not quite used to..

  • xmonad handles multiple monitors not in the way as intuitive as i3 does. In i3, each monitor has a set of workspaces, say Monitor 1 has ws1, ws2 and ws3; Monitor 2 has ws4 and ws5. If you switch from ws4 to ws1 then i3 automatically focus on Monitor 1 & ws1. A workspace always belongs to one monitor unless you explicitly move it to another. That’s not the case in xmonad: each monitor can display any of the workspaces, you focus on one monitor and tell it which ws to display. Say you have 9 ws, Monitor 1 is showing ws1 and Monitor 2 is showing ws2. You are on Monitor 1 and switching to ws2, instead of going to Monitor 2, xmonad will show ws 2 on Monitor 1.

  • Also, the same workspace CAN NOT be displayed on both monitors, since Monitor 1 is now showing ws2, Monitor 2 has to show something else: like ws1.

  • floating windows: in i3 I have a keybindings to “pop” a windows in to floating mode and put it on top of others, in xmonad I have not yet figured out how to do it.

Things I want to do

  • There are many available layouts, like master-slave, tab, spiral … but xmonad only lets you switch layouts one after another. I want a menu to select a layout. rofi, dmenu, xmonad grid select, whatever. (implemented with runSelectedAction)

Why not dwm? Main reason: patching is a pain.

Here is my config file, forked from dt’s dotfiles. I made the keybindings more i3-like. Also removed a lot of funtionalities that I feel bloated.
(I don’t mean they are bad, I just don’t need them.)

Here is my configs:

This is my keybinding list:

-- Xmonad
M-C-r             -- Recompiles xmonad
M-S-r             -- Restarts xmonad
M-S-e             -- Quits xmonad
M-S-q             -- Kill the currently focused client

M-<Return>        -- terminal
M-b               -- Browser
M-p               -- rofi
C-s c             -- calculator (Scratchpads)

M-.               -- Switch focus to next monitor
M-,               -- Switch focus to prev monitor
M-S-Num           -- Move Window to ws n
M-<Tab>           -- Switch to next layout
M-<Space>         -- Toggles noborder/full
M-S-<Space>       -- Restore default layout
M-t               -- Push floating window back to tile
M-S-t             -- Push ALL floating windows to tile
C-g l             -- Select a layout

M-m               -- Move focus to the master window
M-j               -- Move focus to the next window
M-k               -- Move focus to the prev window
M-S-m             -- Swap the focused window and the
                     master window
M-S-j             -- Swap focused window with next window
M-S-k             -- Swap focused window with prev window
M-<Backspace>     -- Moves focused window to master,
                     others maintain order
M-S-<Tab>         -- Rotate all windows except
                     master and keep focus in place
M-C-<Tab>         -- Rotate all the windows in the current stack

C-g g             -- grid select favorite apps
C-g t             -- goto selected window
C-g b             -- bring selected window

C-M1-j            -- Decrease window spacing
C-M1-k            -- Increase window spacing
C-M1-h            -- Decrease screen spacing
C-M1-l            -- Increase screen spacing

-- Increase/decrease windows in the master pane or the stack
M-S-<Up>          -- Increase # of clients master pane
M-S-<Down>        -- Decrease # of clients master pane
M-C-<Up>          -- Increase # of windows
M-C-<Down>        -- Decrease # of windows

-- Window resizing
M-h               -- Shrink horiz window width
M-l               -- Expand horiz window width
M-M1-j            -- Shrink vert window width
M-M1-k            -- Expand vert window width

-- Sublayouts
-- This is used to push windows to tabbed sublayouts,
-- or pull them out of it.
M-C-m             -- MergeAll
M-C-/             -- UnMergeAll
M-C-.             -- Switch focus to next tab
M-C-,             -- Switch focus to prev tab