about summary refs log tree commit diff stats
diff options
context:
space:
mode:
pre { line-height: 125%; } td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } .highlight .hll { background-color: #ffffcc } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
dwm - dynamic window manager
============================
dwm is an extremely fast, small, and dynamic window manager for X.


Requirements
------------
In order to build dwm you need the Xlib header files.


Installation
------------
Edit config.mk to match your local setup (dwm is installed into
the /usr/local namespace by default).

Afterwards enter the following command to build and install dwm (if
necessary as root):

    make clean install


Running dwm
-----------
Add the following line to your .xinitrc to start dwm using startx:

    exec dwm

In order to connect dwm to a specific display, make sure that
the DISPLAY environment variable is set correctly, e.g.:

    DISPLAY=foo.bar:1 exec dwm

(This will start dwm on display :1 of the host foo.bar.)

In order to display status info in the bar, you can do something
like this in your .xinitrc:

    while true
    do
        echo `date` `uptime | sed 's/.*,//'`
        sleep 1
    done | dwm


Configuration
-------------
The configuration of dwm is done by creating a custom config.h
and (re)compiling the source code.
-rw-r--r--client.c235
-rw-r--r--
tsel]) { + if((sel = next(clients))) { + craise(sel); + focus(sel); + } + } discard_events(EnterWindowMask); } @@ -78,31 +123,43 @@ tiling(Arg *arg) float rt, fd; arrange = tiling; - if(!csel) - return; - for(n = 0, c = csel; c; c = next(c), n++); - rt = sqrt(n); - if(modff(rt, &fd) < 0.5) - rows = floor(rt); - else - rows = ceil(rt); - if(rows * rows < n) - cols = rows + 1; + for(n = 0, c = clients; c; c = next(c->next), n++); + if(n) { + rt = sqrt(n); + if(modff(rt, &fd) < 0.5) + rows = floor(rt); + else + rows = ceil(rt); + if(rows * rows < n) + cols = rows + 1; + else + cols = rows; + + gw = (sw - 2) / cols; + gh = (sh - 2) / rows; + } else - cols = rows; - - gw = (sw - 2) / cols; - gh = (sh - 2) / rows; - - for(i = j = 0, c = csel; c; c = next(c)) { - c->x = i * gw; - c->y = j * gh; - c->w = gw; - c->h = gh; - resize(c); - if(++i == cols) { - j++; - i = 0; + cols = rows = gw = gh = 0; + + for(i = j = 0, c = clients; c; c = c->next) { + if(c->tags[tsel]) { + c->x = i * gw; + c->y = j * gh; + c->w = gw; + c->h = gh; + resize(c); + if(++i == cols) { + j++; + i = 0; + } + } + else + ban_client(c); + } + if(sel && !sel->tags[tsel]) { + if((sel = next(clients))) { + craise(sel); + focus(sel); } } discard_events(EnterWindowMask); @@ -113,14 +170,12 @@ prevc(Arg *arg) { Client *c; - if(!csel) + if(!sel) return; - if(!(c = prev(csel))) - c = prev(cend); - if(c) { + if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) { craise(c); - XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); + center(c); focus(c); } } @@ -130,15 +185,15 @@ nextc(Arg *arg) { Client *c; - if(!csel) + if(!sel) return; - if(!(c = next(csel))) - c = next(cstart); - + if(!(c = next(sel->next))) + c = next(clients); if(c) { craise(c); - XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); + center(c); + c->revert = sel; focus(c); } } @@ -146,14 +201,12 @@ nextc(Arg *arg) void ckill(Arg *arg) { - Client *c = csel; - - if(!c) + if(!sel) return; - if(c->proto & WM_PROTOCOL_DELWIN) - send_message(c->win, wm_atom[WMProtocols], wm_atom[WMDelete]); + if(sel->proto & WM_PROTOCOL_DELWIN) + send_message(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]); else - XKillClient(dpy, c->win); + XKillClient(dpy, sel->win); } static void @@ -256,12 +309,12 @@ lower(Client *c) void focus(Client *c) { - if(csel && csel != c) { - XSetWindowBorder(dpy, csel->win, dc.bg); - XMapWindow(dpy, csel->title); - draw_client(csel); + if(sel && sel != c) { + XSetWindowBorder(dpy, sel->win, dc.bg); + XMapWindow(dpy, sel->title); + draw_client(sel); } - csel = c; + sel = c; XUnmapWindow(dpy, c->title); XSetWindowBorder(dpy, c->win, dc.fg); draw_client(c); @@ -273,7 +326,7 @@ focus(Client *c) void manage(Window w, XWindowAttributes *wa) { - Client *c; + Client *c, **l; XSetWindowAttributes twa; c = emallocz(sizeof(Client)); @@ -284,6 +337,7 @@ manage(Window w, XWindowAttributes *wa) c->h = wa->height; c->th = th; c->border = 1; + c->proto = win_proto(c->win); update_size(c); XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | EnterWindowMask); @@ -300,13 +354,9 @@ manage(Window w, XWindowAttributes *wa) update_name(c); - if(!cstart) - cstart = cend = c; - else { - cend->next = c; - c->prev = cend; - cend = c; - } + for(l = &clients; *l; l = &(*l)->next); + c->next = *l; /* *l == nil */ + *l = c; XSetWindowBorderWidth(dpy, c->win, 1); XMapRaised(dpy, c->win); @@ -318,7 +368,7 @@ manage(Window w, XWindowAttributes *wa) XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask, GrabModeAsync, GrabModeSync, None, None); arrange(NULL); - XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); + center(c); focus(c); } @@ -420,26 +470,21 @@ dummy_error_handler(Display *dsply, XErrorEvent *err) void unmanage(Client *c) { + Client **l; + XGrabServer(dpy); XSetErrorHandler(dummy_error_handler); XUngrabButton(dpy, AnyButton, AnyModifier, c->win); XDestroyWindow(dpy, c->title); - if(c->prev) { - c->prev->next = c->next; - if(csel == c) - csel = c->prev; - } - if(c->next) { - c->next->prev = c->prev; - if(csel == c) - csel = c->next; - } - if(cstart == c) - cstart = c->next; - if(cend == c) - cend = c->prev; + for(l = &clients; *l && *l != c; l = &(*l)->next); + *l = c->next; + for(l = &clients; *l; l = &(*l)->next) + if((*l)->revert == c) + (*l)->revert = NULL; + if(sel == c) + sel = sel->revert ? sel->revert : clients; free(c); @@ -447,15 +492,15 @@ unmanage(Client *c) XSetErrorHandler(error_handler); XUngrabServer(dpy); arrange(NULL); - if(csel) - focus(csel); + if(sel) + focus(sel); } Client * gettitle(Window w) { Client *c; - for(c = cstart; c; c = c->next) + for(c = clients; c; c = c->next) if(c->title == w) return c; return NULL; @@ -465,7 +510,7 @@ Client * getclient(Window w) { Client *c; - for(c = cstart; c; c = c->next) + for(c = clients; c; c = c->next) if(c->win == w) return c; return NULL; @@ -475,7 +520,7 @@ void draw_client(Client *c) { int i; - if(c == csel) + if(c == sel) return; dc.x = dc.y = 0; diff --git a/dev.c b/dev.c index aaab99a..d788320 100644 --- a/dev.c +++ b/dev.c @@ -20,19 +20,25 @@ const char *browse[] = { "firefox", NULL }; const char *xlock[] = { "xlock", NULL }; static Key key[] = { - { Mod1Mask, XK_Return, spawn, { .argv = term } }, + { Mod1Mask, XK_Return, zoom, { 0 } }, + { Mod1Mask, XK_t, spawn, { .argv = term } }, { Mod1Mask, XK_w, spawn, { .argv = browse } }, { Mod1Mask, XK_l, spawn, { .argv = xlock } }, { Mod1Mask, XK_k, prevc, { 0 } }, { Mod1Mask, XK_j, nextc, { 0 } }, - { Mod1Mask, XK_t, tiling, { 0 } }, - { Mod1Mask, XK_f, floating, { 0 } }, { Mod1Mask, XK_m, max, { 0 } }, - { Mod1Mask, XK_0, tag, { .i = Tscratch } }, - { Mod1Mask, XK_1, tag, { .i = Tdev } }, - { Mod1Mask, XK_2, tag, { .i = Tirc } }, - { Mod1Mask, XK_3, tag, { .i = Twww } }, - { Mod1Mask, XK_4, tag, { .i = Twork } }, + { Mod1Mask, XK_0, view, { .i = Tscratch } }, + { Mod1Mask, XK_1, view, { .i = Tdev } }, + { Mod1Mask, XK_2, view, { .i = Tirc } }, + { Mod1Mask, XK_3, view, { .i = Twww } }, + { Mod1Mask, XK_4, view, { .i = Twork } }, + { Mod1Mask, XK_space, tiling, { 0 } }, + { Mod1Mask | ShiftMask, XK_space, floating, { 0 } }, + { Mod1Mask | ShiftMask, XK_0, tag, { .i = Tscratch } }, + { Mod1Mask | ShiftMask, XK_1, tag, { .i = Tdev } }, + { Mod1Mask | ShiftMask, XK_2, tag, { .i = Tirc } }, + { Mod1Mask | ShiftMask, XK_3, tag, { .i = Twww } }, + { Mod1Mask | ShiftMask, XK_4, tag, { .i = Twork } }, { Mod1Mask | ShiftMask, XK_c, ckill, { 0 } }, { Mod1Mask | ShiftMask, XK_q, quit, { 0 } }, }; diff --git a/dwm.h b/dwm.h index cf51c36..49aa126 100644 --- a/dwm.h +++ b/dwm.h @@ -68,7 +68,7 @@ struct Client { Window trans; Window title; Client *next; - Client *prev; + Client *revert; }; struct Key { @@ -89,7 +89,7 @@ extern int tsel, screen, sx, sy, sw, sh, th; extern char stext[1024], *tags[TLast]; extern DC dc; -extern Client *cstart, *cend, *csel; +extern Client *clients, *sel; /* client.c */ extern void manage(Window w, XWindowAttributes *wa); @@ -109,7 +109,9 @@ extern void prevc(Arg *arg); extern void max(Arg *arg); extern void floating(Arg *arg); extern void tiling(Arg *arg); -void tag(Arg *arg); +extern void tag(Arg *arg); +extern void view(Arg *arg); +extern void zoom(Arg *arg); extern void gravitate(Client *c, Bool invert); /* draw.c */ diff --git a/main.c b/main.c index 543d156..07e12aa 100644 --- a/main.c +++ b/main.c @@ -38,9 +38,8 @@ int tsel = Tdev; /* default tag */ int screen, sx, sy, sw, sh, th; DC dc = {0}; -Client *cstart = NULL; -Client *cend = NULL; -Client *csel = NULL; +Client *clients = NULL; +Client *sel = NULL; static Bool other_wm_running; static const char version[] = @@ -169,8 +168,10 @@ startup_error_handler(Display *dpy, XErrorEvent *error) static void cleanup() { - while(csel) - unmanage(csel); + while(sel) { + resize(sel); + unmanage(sel); + } XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); }