diff options
-rw-r--r-- | config.def.h | 84 | ||||
-rw-r--r-- | dwm.c | 101 |
2 files changed, 111 insertions, 74 deletions
diff --git a/config.def.h b/config.def.h index 1733681..fe97061 100644 --- a/config.def.h +++ b/config.def.h @@ -39,10 +39,10 @@ static Layout layouts[] = { /* key definitions */ #define MODKEY Mod1Mask #define TAGKEYS(KEY,TAG) \ - { MODKEY, KEY, view, TAG }, \ - { MODKEY|ControlMask, KEY, toggleview, TAG }, \ - { MODKEY|ShiftMask, KEY, tag, TAG }, \ - { MODKEY|ControlMask|ShiftMask, KEY, toggletag, 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 */ #define SHCMD(cmd) { .v = (char*[]){ "/bin/sh", "-c", cmd, NULL } } @@ -51,27 +51,61 @@ static Key keys[] = { /* modifier key function argument */ { MODKEY, XK_p, spawn, {.v = (char *[]){"dmenu_run", "-fn", FONT, "-nb", NORMBGCOLOR, "-nf", NORMFGCOLOR, "-sb", SELBGCOLOR, "-sf", SELFGCOLOR, NULL}} }, { MODKEY|ShiftMask, XK_Return, spawn, {.v = (char *[]){"uxterm", NULL}} }, - { 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_m, togglemax, {0}}, - { MODKEY, XK_Return, zoom, {0}}, - { MODKEY, XK_Tab, view, {0}}, - { MODKEY|ShiftMask, XK_c, killclient, {0}}, - { MODKEY, XK_space, togglelayout, {0}}, - { MODKEY|ShiftMask, XK_space, togglefloating, {0}}, + { 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_m, togglemax, {0} }, + { MODKEY, XK_Return, zoom, {0} }, + { MODKEY, XK_Tab, view, {0} }, + { MODKEY|ShiftMask, XK_c, killclient, {0} }, + { MODKEY, XK_space, togglelayout, {0} }, + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, { MODKEY, XK_0, view, {.ui = ~0 } }, { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, - TAGKEYS( XK_1, {.ui = 1 << 0} ) - TAGKEYS( XK_2, {.ui = 1 << 1} ) - TAGKEYS( XK_3, {.ui = 1 << 2} ) - TAGKEYS( XK_4, {.ui = 1 << 3} ) - TAGKEYS( XK_5, {.ui = 1 << 4} ) - TAGKEYS( XK_6, {.ui = 1 << 5} ) - TAGKEYS( XK_7, {.ui = 1 << 6} ) - TAGKEYS( XK_8, {.ui = 1 << 7} ) - TAGKEYS( XK_9, {.ui = 1 << 8} ) - { MODKEY|ShiftMask, XK_q, quit, {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 */ +#define TAGBUTTONS(TAG) \ + { TAG, 0, Button1, view, {.ui = 1 << TAG} }, \ + { TAG, 0, Button3, toggleview, {.ui = 1 << TAG} }, \ + { TAG, MODKEY, Button1, tag, {.ui = 1 << TAG} }, \ + { TAG, MODKEY, Button3, toggletag, {.ui = 1 << TAG} }, + +/* 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, togglelayout, {0} }, + { ClkLtSymbol, 0, Button3, togglemax, {0} }, + { ClkWinTitle, 0, Button1, movemouse, {0} }, + { ClkWinTitle, 0, Button2, zoom, {0} }, + { ClkWinTitle, 0, Button3, resizemouse, {0} }, + { ClkWinTitle, 0, Button4, focusstack, {.i = +1 } }, + { ClkWinTitle, 0, Button5, focusstack, {.i = -1 } }, + { ClkClientWin, MODKEY, Button1, movemouse, {0} }, + { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, + { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, + { ClkRootWin, Button1Mask, Button3, spawn, {.v = (char *[]){"uxterm", NULL}} }, + TAGBUTTONS(0) + TAGBUTTONS(1) + TAGBUTTONS(2) + TAGBUTTONS(3) + TAGBUTTONS(4) + TAGBUTTONS(5) + TAGBUTTONS(6) + TAGBUTTONS(7) + TAGBUTTONS(8) +}; + diff --git a/dwm.c b/dwm.c index dfc452a..4153f41 100644 --- a/dwm.c +++ b/dwm.c @@ -59,10 +59,28 @@ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ enum { ColBorder, ColFG, ColBG, ColLast }; /* color */ enum { NetSupported, NetWMName, NetLast }; /* EWMH atoms */ enum { WMProtocols, WMDelete, WMName, WMState, WMLast };/* default atoms */ +enum { ClkLtSymbol = -1, ClkStatusText = -2, ClkWinTitle = -3, + ClkClientWin = -4, ClkRootWin = -5, ClkLast = -6};/* clicks */ /* typedefs */ typedef unsigned int uint; typedef unsigned long ulong; + +typedef union { + int i; + uint ui; + float f; + void *v; +} Arg; + +typedef struct { + uint click; + uint mask; + uint button; + void (*func)(const Arg *arg); + const Arg arg; +} Button; + typedef struct Client Client; struct Client { char name[256]; @@ -92,13 +110,6 @@ typedef struct { } font; } DC; /* draw context */ -typedef union { - int i; - uint ui; - float f; - void *v; -} Arg; - typedef struct { uint mod; KeySym keysym; @@ -157,12 +168,12 @@ static void killclient(const Arg *arg); static void manage(Window w, XWindowAttributes *wa); static void mappingnotify(XEvent *e); static void maprequest(XEvent *e); -static void movemouse(Client *c); +static void movemouse(const Arg *arg); static Client *nexttiled(Client *c); static void propertynotify(XEvent *e); static void quit(const Arg *arg); static void resize(Client *c, int x, int y, int w, int h, Bool sizehints); -static void resizemouse(Client *c); +static void resizemouse(const Arg *arg); static void restack(void); static void run(void); static void scan(void); @@ -297,50 +308,31 @@ attachstack(Client *c) { void buttonpress(XEvent *e) { - uint i, mask; - int x; + uint i, x, click; Client *c; XButtonPressedEvent *ev = &e->xbutton; + click = ClkRootWin; if(ev->window == barwin) { x = 0; - for(i = 0; i < LENGTH(tags); i++) { + for(i = 0; i < LENGTH(tags) && ev->x >= x; i++) { x += TEXTW(tags[i]); - if(ev->x < x) { - mask = 1 << i; - if(ev->button == Button1) { - if(ev->state & MODKEY) - tag((Arg*)&mask); - else - view((Arg*)&mask); - } - else if(ev->button == Button3) { - if(ev->state & MODKEY) - toggletag((Arg*)&mask); - else - toggleview((Arg*)&mask); - } - return; - } - } - if(ev->x < x + blw) { - if(ev->button == Button1) - togglelayout(NULL); - else if(ev->button == Button3) - togglemax(NULL); + if(i < LENGTH(tags) || ev->x <= x) + click = i - 1; + else if(ev->x < x + blw) + click = ClkLtSymbol; + else if(ev->x > wx + ww - TEXTW(stext)) + click = ClkStatusText; + else + click = ClkWinTitle; } } - else if((c = getclient(ev->window))) { - focus(c); - if(CLEANMASK(ev->state) != MODKEY || (ismax && !c->isfixed)) - return; - if(ev->button == Button1) - movemouse(c); - else if(ev->button == Button2) - togglefloating(NULL); - else if(ev->button == Button3 && !c->isfixed) - resizemouse(c); - } + else if((c = getclient(ev->window))) + click = ClkClientWin; + + for(i = 0; i < LENGTH(buttons); i++) + if(click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) + buttons[i].func(&buttons[i].arg); } void @@ -971,12 +963,15 @@ maprequest(XEvent *e) { } void -movemouse(Client *c) { +movemouse(const Arg *arg) { int x1, y1, ocx, ocy, di, nx, ny; uint dui; + Client *c; Window dummy; XEvent ev; + if(!(c = sel)) + return; restack(); ocx = nx = c->x; ocy = ny = c->y; @@ -984,6 +979,11 @@ movemouse(Client *c) { None, cursor[CurMove], CurrentTime) != GrabSuccess) return; XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui); + if(x1 < c->x || x1 > c->x + c->w || y1 < c->y || y1 > c->y + c->h) { + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, 0, 0); + x1 = c->x + 1; + y1 = c->y + 1; + } for(;;) { XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); switch (ev.type) { @@ -1131,11 +1131,14 @@ resize(Client *c, int x, int y, int w, int h, Bool sizehints) { } void -resizemouse(Client *c) { +resizemouse(const Arg *arg) { int ocx, ocy; int nw, nh; + Client *c; XEvent ev; + if(!(c = sel)) + return; restack(); ocx = c->x; ocy = c->y; @@ -1377,7 +1380,7 @@ setup(void) { PropModeReplace, (unsigned char *) netatom, NetLast); /* select for events */ - wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask + wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask|ButtonPressMask |EnterWindowMask|LeaveWindowMask|StructureNotifyMask; XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa); XSelectInput(dpy, root, wa.event_mask); @@ -1643,7 +1646,7 @@ updatewmhints(Client *c) { void view(const Arg *arg) { seltags ^= 1; /* toggle sel tagset */ - if(arg && (arg->ui & TAGMASK)) + if(arg && (arg->ui & TAGMASK) && (arg->ui & TAGMASK) != tagset[seltags ^ 1]) tagset[seltags] = arg->i & TAGMASK; arrange(); } |