Ubuntu Forums ubuntu.com - launchpad.net - ubuntu help  

Go Back   Ubuntu Forums > The Ubuntu Forum Community > Other Community Discussions > Tutorials & Tips
Register Reset Password Forum Help Forum Council Search Today's Posts Mark Forums Read

Tutorials & Tips
The place to find Ubuntu related Tips & Tricks.

 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
Old January 29th, 2009   #1
binarymutant
A Carafe of Ubuntu
 
binarymutant's Avatar
 
Join Date: Aug 2007
Location: Knoxville
Beans: 87
Ubuntu 9.04 Jaunty Jackalope
Send a message via AIM to binarymutant Send a message via Yahoo to binarymutant
dwm Primer



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
Code:
wget http://code.suckless.org/dl/dwm/dwm-5.3.1.tar.gz
After the tarball is downloaded, extract it with
Code:
tar -xzf 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 with
Code:
hg clone http://code.suckless.org/hg/dwm
Dependencies
In order to get all the dependencies for building and running dwm simply do
Code:
sudo apt-get install build-essential libx11-dev libxinerama-dev sharutils
Configuration:

To stay simple and lightweight dwm must be compiled in order to work. To compile dwm change to the dwm installation directory and
Code:
make
Code:
sudo make install
Any 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 text
Quote:
[Desktop Entry]
Encoding=UTF-8
Name=dwm
Comment=This session starts dwm
Exec=/usr/local/bin/dwm
Type=Application
Save dwm.desktop to /usr/share/xsessions/ and your ready to login to dwm
Code:
sudo mv dwm.desktop /usr/share/xsessions/
If your not using a login manager, just add this line to .xinitrc
Quote:
exec dwm
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.

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.
Code:
cp config.def.h config.h
The config.h should look like this
Code:
/* 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";
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 like
Quote:
static const char tags[][MAXTAGLEN] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
I personally use these names in my own config.h but use whatever suits your needs
Quote:
static const char tags[][MAXTAGLEN] = { "Main", "Web", "More" };
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.
Quote:
static Rule rules[] = {
/* class instance title tags mask isfloating */
{ "Gimp", NULL, NULL, 0, True },
{ "Firefox", NULL, NULL, 1 << 8, True },
};
Further down,
Quote:
/* key definitions */
#define MODKEY Mod1Mask
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
Quote:
static const char *termcmd[] = { "uxterm", NULL };
Many people create patches for dwm and share them on the developer's [URL
=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
Code:
patch -p1 config.def.h dwm-5.2-fibonacci.diff
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 it
Quote:
while true
do
echo `date`
sleep 1
done | dwm
Save it somewhere and make it executable with this command
Code:
chmod a+x filename
Go back and edit /usr/share/xsessions/dwm.desktop to execute the newly created file
Quote:
[Desktop Entry]
Encoding=UTF-8
Name=dwm
Comment=This session starts dwm
Exec=/home/username/filename
Type=Application
More Links:
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.
__________________
/* Christopher Lunsford
binarymutant.org */

Last edited by binarymutant; May 23rd, 2009 at 04:09 PM.. Reason: Added dependencies
binarymutant is offline   Reply With Quote
 

Bookmarks

Tags
dwm, tutorial

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 05:25 AM.


vBulletin ©2000 - 2010, Jelsoft Enterprises Ltd. Ubuntu Logo, Ubuntu and Canonical © Canonical Ltd. Tango Icons © Tango Desktop Project. lingonberry