JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
make tabs out of extra slave windows
[dwm.git] / dwm.c
diff --git a/dwm.c b/dwm.c
index ffc8864..362e902 100644 (file)
--- a/dwm.c
+++ b/dwm.c
@@ -60,8 +60,8 @@
 enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
 enum { SchemeNorm, SchemeSel, SchemeLast }; /* color schemes */
 enum { NetSupported, NetWMName, NetWMState,
-       NetWMFullscreen, NetActiveWindow, NetWMWindowType,
-       NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
+       NetWMFullscreen, NetWMWindowOpacity, NetActiveWindow, NetWMWindowType,
+       NetWMWindowTypeDialog, NetClientList, NetSupportingWMCheck, NetLast }; /* EWMH atoms */
 enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
 enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
        ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
@@ -90,8 +90,9 @@ struct Client {
        int oldx, oldy, oldw, oldh;
        int basew, baseh, incw, inch, maxw, maxh, minw, minh;
        int bw, oldbw;
+       int opacity;
        unsigned int tags;
-       Bool isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
+       Bool isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, screen_hog;
        Client *next;
        Client *snext;
        Monitor *mon;
@@ -137,6 +138,7 @@ typedef struct {
        const char *title;
        unsigned int tags;
        Bool isfloating;
+       Bool screen_hog;
        int monitor;
 } Rule;
 
@@ -145,6 +147,7 @@ static void applyrules(Client *c);
 static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact);
 static void arrange(Monitor *m);
 static void arrangemon(Monitor *m);
+static void attach_as_master(Client *c);
 static void attach(Client *c);
 static void attachstack(Client *c);
 static void buttonpress(XEvent *e);
@@ -184,12 +187,13 @@ static void monocle(Monitor *m);
 static void motionnotify(XEvent *e);
 static void movemouse(const Arg *arg);
 static Client *nexttiled(Client *c);
+static Client *nextvisible(Client *c);
 static void pop(Client *);
 static void propertynotify(XEvent *e);
 static void quit(const Arg *arg);
 static Monitor *recttomon(int x, int y, int w, int h);
-static void resize(Client *c, int x, int y, int w, int h, Bool interact);
-static void resizeclient(Client *c, int x, int y, int w, int h);
+static void resize(Client *c, int x, int y, int w, int h, Bool interact, Client *base);
+static void resizeclient(Client *c, int x, int y, int w, int h, Client *base);
 static void resizemouse(const Arg *arg);
 static void restack(Monitor *m);
 static void run(void);
@@ -207,6 +211,7 @@ static void sigchld(int unused);
 static void spawn(const Arg *arg);
 static void tag(const Arg *arg);
 static void tagmon(const Arg *arg);
+static void jason_layout(Monitor *);
 static void tile(Monitor *);
 static void togglebar(const Arg *arg);
 static void togglefloating(const Arg *arg);
@@ -267,6 +272,63 @@ static Fnt *fnt;
 static Monitor *mons, *selmon;
 static Window root;
 
+// unfocused windows get transparent (feature)
+static const unsigned long opacities[] = { 0, 0xbfffffff, 0x00000000 }; // first unused
+static void window_set_opaque(Client *c);
+static void window_set_translucent(Client *c);
+static void window_set_invisible(Client *c);
+static void window_set_opacity(Client *c, int opacity_index);
+static void update_window_opacities(Monitor *m);
+void
+window_set_opacity(Client *c, int opacity_index) {
+       if (c->opacity == opacity_index) {
+               return;
+       }
+       c->opacity = opacity_index;
+       if (opacity_index == 0) {
+               XDeleteProperty(dpy, c->win, netatom[NetWMWindowOpacity]);
+       } else {
+               XChangeProperty(dpy, c->win, netatom[NetWMWindowOpacity], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)(&opacities[opacity_index]), 1);
+       }
+}
+void
+window_set_opaque(Client *c) {
+       window_set_opacity(c, 0);
+}
+void
+window_set_translucent(Client *c) {
+       window_set_opacity(c, 1);
+}
+void
+window_set_invisible(Client *c) {
+       window_set_opacity(c, 2);
+}
+void
+update_window_opacities(Monitor *m) {
+       Client *master, *slave, *c;
+       Bool selection_floating = False;
+       slave = master = nexttiled(m->clients);
+       if (master) slave = nexttiled(master->next);
+       if (m->sel && m->sel != master) {
+               if (nexttiled(m->sel) == m->sel) // if selection is tiled
+                       slave = m->sel;
+               else
+                       selection_floating = True;
+       }
+       for (c = m->clients; c; c = c->next) {
+               if (ISVISIBLE(c)) {
+                       if (c->isfloating || c == m->sel || (c == master && selection_floating)) {
+                               window_set_opaque(c);
+                       } else if (c == master || c == slave) {
+                               window_set_translucent(c);
+                       } else {
+                               window_set_opaque(c);
+                       }
+               }
+       }
+}
+
+
 /* configuration, allows nested code to access above variables */
 #include "config.h"
 
@@ -283,19 +345,20 @@ applyrules(Client *c) {
        XClassHint ch = { NULL, NULL };
 
        /* rule matching */
-       c->isfloating = c->tags = 0;
+       c->isfloating = c->tags = c->screen_hog = 0;
        XGetClassHint(dpy, c->win, &ch);
        class    = ch.res_class ? ch.res_class : broken;
        instance = ch.res_name  ? ch.res_name  : broken;
 
        for(i = 0; i < LENGTH(rules); i++) {
                r = &rules[i];
-               if((!r->title || strstr(c->name, r->title))
+               if((!r->title || c->name == strstr(c->name, r->title))
                && (!r->class || strstr(class, r->class))
                && (!r->instance || strstr(instance, r->instance)))
                {
                        c->isfloating = r->isfloating;
                        c->tags |= r->tags;
+                       c->screen_hog = r->screen_hog;
                        for(m = mons; m && m->num != r->monitor; m = m->next);
                        if(m)
                                c->mon = m;
@@ -395,10 +458,19 @@ arrangemon(Monitor *m) {
 }
 
 void
-attach(Client *c) {
+attach_as_master(Client *c) {
        c->next = c->mon->clients;
        c->mon->clients = c;
 }
+void
+attach(Client *c) {
+       if (c->mon->sel) {
+               c->next = c->mon->sel->next;
+               c->mon->sel->next = c;
+       } else {
+               attach_as_master(c);
+       }
+}
 
 void
 attachstack(Client *c) {
@@ -527,6 +599,7 @@ clientmessage(XEvent *e) {
                                      || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen)));
        }
        else if(cme->message_type == netatom[NetActiveWindow]) {
+               return;
                if(!ISVISIBLE(c)) {
                        c->mon->seltags ^= 1;
                        c->mon->tagset[c->mon->seltags] = c->tags;
@@ -662,16 +735,30 @@ detach(Client *c) {
        *tc = c->next;
 }
 
+// NOTE: the stack is for z-order and most-recently-focused
+// only mon->clients determines position in visible layout
 void
 detachstack(Client *c) {
-       Client **tc, *t;
-
-       for(tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext);
-       *tc = c->snext;
-
+       Client *prev = NULL, *next_sel = NULL, *i;
+       for(i = c->mon->stack; i && i != c; i = i->snext) {
+               prev = i;
+       }
        if(c == c->mon->sel) {
-               for(t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext);
-               c->mon->sel = t;
+               // find last visible window before c
+               // WARNING if you detach() before detachstack() this will select last visible window
+               for(i = nextvisible(c->mon->clients); i && i != c; i = nextvisible(i->next))
+                       next_sel = i;
+               // failing that, find first visible window (besides c)
+               if (!next_sel)
+                       for(i = nextvisible(c->mon->clients); i && i == c; i = nextvisible(i->next));
+                       if (i != c)
+                               next_sel = i;
+               c->mon->sel = next_sel;
+       }
+       if (prev) {
+               prev->snext = c->snext;
+       } else {
+               c->mon->stack = c->snext;
        }
 }
 
@@ -800,7 +887,11 @@ focus(Client *c) {
                XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
        }
        selmon->sel = c;
+       jason_layout(selmon);
+       update_window_opacities(selmon);
        drawbars();
+       if(c && (!root || (c->win!=root)) )
+               window_set_opaque(c);
 }
 
 void
@@ -831,7 +922,14 @@ focusstack(const Arg *arg) {
 
        if(!selmon->sel)
                return;
-       if(arg->i > 0) {
+       if(arg->i == 0) {
+               for(i = selmon->clients; i != selmon->sel; i = i->next) {
+                       if(ISVISIBLE(i)) {
+                               c = i;
+                               break;
+                       }
+               }
+       } else if(arg->i > 0) {
                for(c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next);
                if(!c)
                        for(c = selmon->clients; c && !ISVISIBLE(c); c = c->next);
@@ -1011,6 +1109,7 @@ manage(Window w, XWindowAttributes *wa) {
 
        if(!(c = calloc(1, sizeof(Client))))
                die("fatal: could not malloc() %u bytes\n", sizeof(Client));
+       c->opacity = -1; // who knows
        c->win = w;
        updatetitle(c);
        if(XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
@@ -1062,7 +1161,7 @@ manage(Window w, XWindowAttributes *wa) {
        c->mon->sel = c;
        arrange(c->mon);
        XMapWindow(dpy, c->win);
-       focus(NULL);
+       focus(c);
 }
 
 void
@@ -1098,7 +1197,7 @@ monocle(Monitor *m) {
        if(n > 0) /* override layout symbol */
                snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
        for(c = nexttiled(m->clients); c; c = nexttiled(c->next))
-               resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, False);
+               resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, False, 0);
 }
 
 void
@@ -1123,6 +1222,7 @@ movemouse(const Arg *arg) {
        Client *c;
        Monitor *m;
        XEvent ev;
+       Time lasttime = 0;
 
        if(!(c = selmon->sel))
                return;
@@ -1145,6 +1245,10 @@ movemouse(const Arg *arg) {
                        handler[ev.type](&ev);
                        break;
                case MotionNotify:
+                       if ((ev.xmotion.time - lasttime) <= (1000 / 60))
+                               continue;
+                       lasttime = ev.xmotion.time;
+
                        nx = ocx + (ev.xmotion.x - x);
                        ny = ocy + (ev.xmotion.y - y);
                        if(nx >= selmon->wx && nx <= selmon->wx + selmon->ww
@@ -1162,7 +1266,7 @@ movemouse(const Arg *arg) {
                                        togglefloating(NULL);
                        }
                        if(!selmon->lt[selmon->sellt]->arrange || c->isfloating)
-                               resize(c, nx, ny, c->w, c->h, True);
+                               resize(c, nx, ny, c->w, c->h, True, 0);
                        break;
                }
        } while(ev.type != ButtonRelease);
@@ -1180,10 +1284,16 @@ nexttiled(Client *c) {
        return c;
 }
 
+Client *
+nextvisible(Client *c) {
+       for(; c && !ISVISIBLE(c); c = c->next);
+       return c;
+}
+
 void
 pop(Client *c) {
        detach(c);
-       attach(c);
+       attach_as_master(c);
        focus(c);
        arrange(c->mon);
 }
@@ -1243,32 +1353,39 @@ recttomon(int x, int y, int w, int h) {
 }
 
 void
-resize(Client *c, int x, int y, int w, int h, Bool interact) {
+resize(Client *c, int x, int y, int w, int h, Bool interact, Client *base) {
        if(applysizehints(c, &x, &y, &w, &h, interact))
-               resizeclient(c, x, y, w, h);
+               resizeclient(c, x, y, w, h, base);
 }
 
 void
-resizeclient(Client *c, int x, int y, int w, int h) {
+resizeclient(Client *c, int x, int y, int w, int h, Client *base) {
        XWindowChanges wc;
+       unsigned long mask = CWX|CWY|CWWidth|CWHeight|CWBorderWidth;
 
        c->oldx = c->x; c->x = wc.x = x;
        c->oldy = c->y; c->y = wc.y = y;
        c->oldw = c->w; c->w = wc.width = w;
        c->oldh = c->h; c->h = wc.height = h;
+       base = 0;
+       if (base) {
+               wc.stack_mode = Above;
+               wc.sibling = base->win;
+               mask |= CWStackMode|CWSibling;
+       }
        wc.border_width = c->bw;
-       XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
+       XConfigureWindow(dpy, c->win, mask, &wc);
        configure(c);
        XSync(dpy, False);
 }
 
 void
 resizemouse(const Arg *arg) {
-       int ocx, ocy;
-       int nw, nh;
+       int ocx, ocy, nw, nh;
        Client *c;
        Monitor *m;
        XEvent ev;
+       Time lasttime = 0;
 
        if(!(c = selmon->sel))
                return;
@@ -1290,6 +1407,10 @@ resizemouse(const Arg *arg) {
                        handler[ev.type](&ev);
                        break;
                case MotionNotify:
+                       if ((ev.xmotion.time - lasttime) <= (1000 / 60))
+                               continue;
+                       lasttime = ev.xmotion.time;
+
                        nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1);
                        nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1);
                        if(c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww
@@ -1300,7 +1421,7 @@ resizemouse(const Arg *arg) {
                                        togglefloating(NULL);
                        }
                        if(!selmon->lt[selmon->sellt]->arrange || c->isfloating)
-                               resize(c, c->x, c->y, nw, nh, True);
+                               resize(c, c->x, c->y, nw, nh, True, 0);
                        break;
                }
        } while(ev.type != ButtonRelease);
@@ -1328,10 +1449,11 @@ restack(Monitor *m) {
        if(m->lt[m->sellt]->arrange) {
                wc.stack_mode = Below;
                wc.sibling = m->barwin;
-               for(c = m->stack; c; c = c->snext)
+               for(c = m->clients; c; c = c->next)
                        if(!c->isfloating && ISVISIBLE(c)) {
                                XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc);
                                wc.sibling = c->win;
+                               wc.stack_mode = Above;
                        }
        }
        XSync(dpy, False);
@@ -1379,8 +1501,8 @@ sendmon(Client *c, Monitor *m) {
        if(c->mon == m)
                return;
        unfocus(c, True);
-       detach(c);
        detachstack(c);
+       detach(c);
        c->mon = m;
        c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
        attach(c);
@@ -1442,7 +1564,7 @@ setfullscreen(Client *c, Bool fullscreen) {
                c->oldbw = c->bw;
                c->bw = 0;
                c->isfloating = True;
-               resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh);
+               resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh, 0);
                XRaiseWindow(dpy, c->win);
        }
        else {
@@ -1455,7 +1577,7 @@ setfullscreen(Client *c, Bool fullscreen) {
                c->y = c->oldy;
                c->w = c->oldw;
                c->h = c->oldh;
-               resizeclient(c, c->x, c->y, c->w, c->h);
+               resizeclient(c, c->x, c->y, c->w, c->h, 0);
                arrange(c->mon);
        }
 }
@@ -1514,9 +1636,11 @@ setup(void) {
        netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
        netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
        netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
+       netatom[NetWMWindowOpacity] = XInternAtom(dpy, "_NET_WM_WINDOW_OPACITY", False);
        netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
        netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
        netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
+       netatom[NetSupportingWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
        /* init cursors */
        cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
        cursor[CurResize] = drw_cur_create(drw, XC_sizing);
@@ -1552,7 +1676,7 @@ showhide(Client *c) {
        if(ISVISIBLE(c)) { /* show clients top down */
                XMoveWindow(dpy, c->win, c->x, c->y);
                if((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen)
-                       resize(c, c->x, c->y, c->w, c->h, False);
+                       resize(c, c->x, c->y, c->w, c->h, False, 0);
                showhide(c->snext);
        }
        else { /* hide clients bottom up */
@@ -1570,6 +1694,17 @@ sigchld(int unused) {
 
 void
 spawn(const Arg *arg) {
+       int tag = 0, i;
+       if(arg->v == termcmd) {
+               for(i = 0; i < 32; ++i) {
+                       if(selmon->tagset[selmon->seltags] & (1 << i)) {
+                               tag = i;
+                               break;
+                       }
+               }
+               WORKSPACE_NUMBER[17] = workspace_numbers_str[tag][0];
+               WORKSPACE_NUMBER[18] = workspace_numbers_str[tag][1];
+       }
        if(arg->v == dmenucmd)
                dmenumon[0] = '0' + selmon->num;
        if(fork() == 0) {
@@ -1610,21 +1745,90 @@ tile(Monitor *m) {
 
        if(n > m->nmaster)
                mw = m->nmaster ? m->ww * m->mfact : 0;
-       else
-               mw = m->ww;
+       else {
+               c = nexttiled(m->clients);
+               if (c && !c->screen_hog)
+                       mw = m->ww * m->mfact;
+               else
+                       mw = m->ww;
+       }
        for(i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
                if(i < m->nmaster) {
                        h = (m->wh - my) / (MIN(n, m->nmaster) - i);
-                       resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), False);
+                       resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), False, 0);
                        my += HEIGHT(c);
                }
                else {
                        h = (m->wh - ty) / (n - i);
-                       resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), False);
+                       resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), False, 0);
                        ty += HEIGHT(c);
                }
 }
 
+#define TAB_HEIGHT 19
+#define TAB_PAD     7
+
+void
+jason_layout(Monitor *m) {
+       unsigned int i, tiled_count, mw, right_width, tab_counts[2] = {0,0}, cur_tab = 0, *tab_count;
+       int tab_top;
+       Client *c, *vis_slave = 0, *base = 0;
+
+       tab_count = &(tab_counts[0]);
+
+       for(tiled_count = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), tiled_count++) {
+               if (tiled_count == 0) { // master
+                       if (c == m->sel) {
+                               if (c->next) {
+                                       vis_slave = nexttiled(c->next);
+                               }
+                       } else {
+                               vis_slave = m->sel;
+                       }
+               } else {
+                       if (c == vis_slave) {
+                               tab_count = &(tab_counts[1]);
+                       } else {
+                               (*tab_count) += 1;
+                       }
+               }
+       }
+       if(tiled_count == 0) {
+               return;
+       }
+
+       if(tiled_count > 1 || (tiled_count == 1 && !nexttiled(m->clients)->screen_hog)) {
+               mw = m->ww * m->mfact;
+       } else {
+               // one of these:
+               // * zero tiled windows
+               // * one tiled window that's not a screen hog
+               // * miltiple tiled windows
+               mw = m->ww;
+       }
+       right_width = m->ww - mw;
+       tab_count = &(tab_counts[0]);
+       tab_top = m->wy - (m->wh - (2 * (TAB_HEIGHT + TAB_PAD))) + TAB_HEIGHT;
+       for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
+               if (i == 0) {
+                       resize(c, m->wx, m->wy, mw, m->wh, False, 0);
+               } else {
+                       if (c == vis_slave) {
+                               resize(c, m->wx + mw, m->wy + TAB_HEIGHT + TAB_PAD, right_width, m->wh - 2 * (TAB_HEIGHT + TAB_PAD), False, base);
+                               tab_count = &(tab_counts[1]);
+                               tab_top = m->wy + m->wh - TAB_HEIGHT;
+                               cur_tab = 0;
+                       } else {
+                               // this function does not get called when focus changes
+                               // resize(c, m->wx + m->ww, m->wy, m->ww - mw, m->wh, False);
+                               resize(c, m->wx + mw + right_width * cur_tab / (*tab_count), tab_top, right_width, m->wh - 2 * (TAB_HEIGHT + TAB_PAD), False, base);
+                               cur_tab += 1;
+                       }
+               }
+               base = c;
+       }
+}
+
 void
 togglebar(const Arg *arg) {
        selmon->showbar = !selmon->showbar;
@@ -1642,7 +1846,7 @@ togglefloating(const Arg *arg) {
        selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed;
        if(selmon->sel->isfloating)
                resize(selmon->sel, selmon->sel->x, selmon->sel->y,
-                      selmon->sel->w, selmon->sel->h, False);
+                      selmon->sel->w, selmon->sel->h, False, 0);
        arrange(selmon);
 }
 
@@ -1689,8 +1893,8 @@ unmanage(Client *c, Bool destroyed) {
        XWindowChanges wc;
 
        /* The server grab construct avoids race conditions. */
-       detach(c);
        detachstack(c);
+       detach(c);
        if(!destroyed) {
                wc.border_width = c->oldbw;
                XGrabServer(dpy);
@@ -1703,7 +1907,7 @@ unmanage(Client *c, Bool destroyed) {
                XUngrabServer(dpy);
        }
        free(c);
-       focus(NULL);
+       focus(selmon ? selmon->sel : NULL);
        updateclientlist();
        arrange(m);
 }
@@ -1735,6 +1939,12 @@ updatebars(void) {
                m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
                                          CopyFromParent, DefaultVisual(dpy, screen),
                                          CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
+               XChangeProperty(dpy, root, netatom[NetSupportingWMCheck], XA_WINDOW, 32,
+                               PropModeReplace, (unsigned char *) &(m->barwin), 1);
+               XChangeProperty(dpy, m->barwin, netatom[NetSupportingWMCheck], XA_WINDOW, 32,
+                               PropModeReplace, (unsigned char *) &(m->barwin), 1);
+               XChangeProperty(dpy, m->barwin, netatom[NetWMName], XA_STRING, 8,
+                               PropModeReplace, (unsigned char *) "dwm", 3);
                XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
                XMapRaised(dpy, m->barwin);
        }