After an epic search for the ultimate window manager I stumbled upon dwm (Dynamic Window Manager). At only 2000 lines of pure C code I was instantly hooked. But, because of the lack of community documentation and the self proclaimed elitist userbase, dwm is rarely talked about around the Ubuntu world. Here is a primer for dwm in hopes that it will create a discussion around this great tool and maybe some more tips about customizing it.
Concepts:
The core idea behind all tiling window managers is the idea of productivity. Tiling window managers increase productivity by almost never having the user remove their hands from the keyboard. Since all tasks are visible on the screen, another method of increasing computing efficiency is automatic window placement. The more popular window managers stack windows on top of each other and block access to tasks in the background. This causes the user to waste valuable time having to physically move the mouse in order to see the blocked task or risks having the user becoming distracted with the new window and possibly forgetting about the original task all together. With automatic window placement the screen is divided up into a "master" area on one side and a "stack" area on the other. When a new window is created it spawns in the "master" area and all the other windows move to the stack area.
Installation:
There are a couple of ways to get dwm. The easiest being to go to http://www.suckless.org/dwm/ and download the tarball or simply
After the tarball is downloaded, extract it withCode:wget http://code.suckless.org/dl/dwm/dwm-5.3.1.tar.gz
A way to stay current with dwm's development is to use Mercurial, a verson control system similar to git. All development of dwm is done through Mercurial. So, if Mercurial is installed, get a working copy of the dwm repository withCode:tar -xzf dwm-5.3.1.tar.gz
DependenciesCode:hg clone http://code.suckless.org/hg/dwm
In order to get all the dependencies for building and running dwm simply do
Configuration:Code:sudo apt-get install build-essential libx11-dev libxinerama-dev sharutils
To stay simple and lightweight dwm must be compiled in order to work. To compile dwm change to the dwm installation directory and
Code:makeAny changes made to dwm requires recompiling. Once dwm is compiled the last remaining obstacle to using it is the login manager. Create a new file called dwm.desktop and add this to the textCode:sudo make install
Save dwm.desktop to /usr/share/xsessions/ and your ready to login to dwm[Desktop Entry]
Encoding=UTF-8
Name=dwm
Comment=This session starts dwm
Exec=/usr/local/bin/dwm
Type=Application
If your not using a login manager, just add this line to .xinitrcCode:sudo mv dwm.desktop /usr/share/xsessions/
and then you will be able to use dwm with the startx command. The default dwm is a little ugly, and the keybinds are a little strange at first. Alt+Shift+Enter will bring up a new terminal. Bring up more than 2 terminals and the default tiling layout will begin to show. Alt+F changes the layout to floating and Alt+M will change the layout to monocle or fullscreen. The strange icon on the top left side of the status bar will cycle through layouts when clicked. The default dwm is pretty ugly to my eyes, but with a little customization the glossy shine of it can come out.exec dwm
Customization:
Customizing dwm is the best part of the tiling window manager experience! Those default keybinds are awkward to me and frankly the colors aren't too appealing. All the customizable parts of dwm are located in a file called config.def.h. Copying config.def.h to a new file called config.h will safely let you edit the customizations while still having a way to revert back to the defaults.
The config.h should look like thisCode:cp config.def.h config.h
The variable name comes first, example: normbordercolor[] = "#cccccc"; is the color for the normal border color. It is set to grey in this example. Change the "#cccccc" to the color you want. You can use any hexidecimal color, more commonly called html color codes. On the left side of the default status bar the numbers one through nine are displayed. If clicked these numbers switch virtual desktops. Moving windows to the other virtual desktops is as easy as hitting Alt+Shift+1-9. To change the virtual desktops names from numbers to something more familiar, edit the line under the /* Tagging */ section that looks likeCode:/* See LICENSE file for copyright and license details. */ /* appearance */ static const char font[] = "-*-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*"; static const char normbordercolor[] = "#cccccc"; static const char normbgcolor[] = "#cccccc"; static const char normfgcolor[] = "#000000"; static const char selbordercolor[] = "#0066ff"; static const char selbgcolor[] = "#0066ff"; static const char selfgcolor[] = "#ffffff"; static unsigned int borderpx = 1; /* border pixel of windows */ static unsigned int snap = 32; /* snap pixel */ static Bool showbar = True; /* False means no bar */ static Bool topbar = True; /* False means bottom bar */ static Bool readin = True; /* False means do not read stdin */ static Bool usegrab = False; /* True means grabbing the X server during mouse-based resizals */ /* tagging */ static const char tags[][MAXTAGLEN] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; static unsigned int tagset[] = {1, 1}; /* after start, first tag is selected */ static Rule rules[] = { /* class instance title tags mask isfloating */ { "Gimp", NULL, NULL, 0, True }, { "Firefox", NULL, NULL, 1 << 8, True }, }; /* layout(s) */ static float mfact = 0.55; /* factor of master area size [0.05..0.95] */ static Bool resizehints = True; /* False means respect size hints in tiled resizals */ static Layout layouts[] = { /* symbol arrange function */ { "[]=", tile }, /* first entry is default */ { "><>", NULL }, /* no layout function means floating behavior */ { "[M]", monocle }, }; /* key definitions */ #define MODKEY Mod1Mask #define TAGKEYS(KEY,TAG) \ { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, /* helper for spawning shell commands in the pre dwm-5.0 fashion */ #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } /* commands */ static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; static const char *termcmd[] = { "uxterm", NULL }; 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, XK_j, focusstack, {.i = +1 } }, { MODKEY, XK_k, focusstack, {.i = -1 } }, { MODKEY, XK_h, setmfact, {.f = -0.05} }, { MODKEY, XK_l, setmfact, {.f = +0.05} }, { MODKEY, XK_Return, zoom, {0} }, { MODKEY, XK_Tab, view, {0} }, { MODKEY|ShiftMask, XK_c, killclient, {0} }, { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, { MODKEY, XK_space, setlayout, {0} }, { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, { MODKEY, XK_0, view, {.ui = ~0 } }, { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, TAGKEYS( XK_1, 0) TAGKEYS( XK_2, 1) TAGKEYS( XK_3, 2) TAGKEYS( XK_4, 3) TAGKEYS( XK_5, 4) TAGKEYS( XK_6, 5) TAGKEYS( XK_7, 6) TAGKEYS( XK_8, 7) TAGKEYS( XK_9, 8) { MODKEY|ShiftMask, XK_q, quit, {0} }, }; /* button definitions */ /* click can be a tag number (starting at 0), * ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ static Button buttons[] = { /* click event mask button function argument */ { ClkLtSymbol, 0, Button1, setlayout, {0} }, { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, { ClkWinTitle, 0, Button2, zoom, {0} }, { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, { ClkClientWin, MODKEY, Button1, movemouse, {0} }, { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, { ClkTagBar, 0, Button1, view, {0} }, { ClkTagBar, 0, Button3, toggleview, {0} }, { ClkTagBar, MODKEY, Button1, tag, {0} }, { ClkTagBar, MODKEY, Button3, toggletag, {0} }, }; [/QUOTE] It might look daunting to edit but it's really very simple. It may be written in C but knowing how to program is not required. The /* Appearance */ section defines the look and feel of dwm. The /* Tagging */ section defines windows rules, The /* Layout(s) */ section defines the layouts and everything under the /* Key definitions */ section defines your mouse and key bindings. To change the colors used by dwm edit these variables [QUOTE] static const char normbordercolor[] = "#cccccc"; static const char normbgcolor[] = "#cccccc"; static const char normfgcolor[] = "#000000"; static const char selbordercolor[] = "#0066ff"; static const char selbgcolor[] = "#0066ff"; static const char selfgcolor[] = "#ffffff";
I personally use these names in my own config.h but use whatever suits your needsstatic const char tags[][MAXTAGLEN] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
My example shows the second virtual desktop called Web because I tag my browser windows to it. The /* Tagging */ section in config.h also provides a way to control and move new windows. For instance both Firefox and Gimp are floating, Firefox will spawn on virtual desktop 9 and Gimp will spawn wherever it's started from.static const char tags[][MAXTAGLEN] = { "Main", "Web", "More" };
Further down,static Rule rules[] = {
/* class instance title tags mask isfloating */
{ "Gimp", NULL, NULL, 0, True },
{ "Firefox", NULL, NULL, 1 << 8, True },
};
The MODKEY is set to Alt by default and every key binding for dwm starts with the MODKEY. In order to change the MODKEY from Alt to the Windows Key replace the Mod1Mask to Mod4Mask. If urxvt is the terminal of choice instead of xterm edit the line/* key definitions */
#define MODKEY Mod1Mask
Many people create patches for dwm and share them on the developer's [URLstatic const char *termcmd[] = { "uxterm", NULL };
=http://lists.suckless.org/dwm/]mailing list[/URL]. The patch I like a lot is the fibonacci patch http://www.aplusbi.com/dwm/dwm-5.2-fibonacci.diff because it makes the "Stack" area spiral
To apply the fibonacci patch download the diff into the dwm installation directory, be aware that this patch changes config.def.h and not config.h
If you notice the right side of the status bar has an "EOF" it's because GDM and other login managers close standard output to dwm before executing it. To replace the "EOF" with a clock create a new file and add this text to itCode:patch -p1 config.def.h dwm-5.2-fibonacci.diff
Save it somewhere and make it executable with this commandwhile true
do
echo `date`
sleep 1
done | dwm
Go back and edit /usr/share/xsessions/dwm.desktop to execute the newly created fileCode:chmod a+x filename
More Links:[Desktop Entry]
Encoding=UTF-8
Name=dwm
Comment=This session starts dwm
Exec=/home/username/filename
Type=Application
http://wiki.archlinux.org/index.php/Dwm
http://ubuntuforums.org/showthread.php?t=642808
Hopefully this primer will get anyone ready to start using dwm and share any other knowledge they pick up elsewhere.
Bookmarks