X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=dwm.c;h=8ae4c0e8fc7c0573a661140ced2463d751b01aae;hb=f25cc5678fcc405a55df7f49e7b3189241933a97;hp=04ae223b9375edaf231918f3098157f06f1b96c0;hpb=d662f98d89d3e813344e9bdb64e5704caf3b9dc2;p=dwm.git diff --git a/dwm.c b/dwm.c index 04ae223..8ae4c0e 100644 --- a/dwm.c +++ b/dwm.c @@ -59,19 +59,37 @@ 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 = 64, ClkStatusText, ClkWinTitle, + ClkClientWin, ClkRootWin, ClkLast }; /* 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]; + float mina, maxa; int x, y, w, h; int basew, baseh, incw, inch, maxw, maxh, minw, minh; - float mina, maxa; int bw, oldbw; - Bool isbanned, isfixed, isfloating, ismoved, isurgent; uint tags; + Bool isbanned, isfixed, isfloating, ismoved, isurgent; Client *next; Client *snext; Window win; @@ -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); @@ -224,13 +235,11 @@ static Client *stack = NULL; static Cursor cursor[CurLast]; static Display *dpy; static DC dc = {0}; +static Layout *lt = NULL; static Window root, barwin; - /* configuration, allows nested code to access above variables */ #include "config.h" -static Layout *lt = layouts; - /* compile-time check if all tags fit into an uint bit array. */ struct NumTags { char limitexceeded[sizeof(uint) * 8 < LENGTH(tags) ? -1 : 1]; }; @@ -299,50 +308,34 @@ 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++) { + i = x = 0; + do 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); - } + while(ev->x >= x && ++i < LENGTH(tags)); + if(i < LENGTH(tags)) + click = i; + 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); + 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 @@ -664,7 +657,7 @@ focusstack(const Arg *arg) { for(i = clients; i != sel; i = i->next) if (!i->isbanned) c = i; - if(!c) + if(!c) for(; i; i = i->next) if (!i->isbanned) c = i; @@ -920,7 +913,8 @@ manage(Window w, XWindowAttributes *wa) { if(c->y + c->h + 2 * c->bw > sy + sh) c->y = sy + sh - c->h - 2 * c->bw; c->x = MAX(c->x, sx); - c->y = MAX(c->y, by == 0 ? bh : sy); + /* only fix client y-offset, if the client center might cover the bar */ + c->y = MAX(c->y, ((by == 0) && (c->x + (c->w / 2) >= wx) && (c->x + (c->w / 2) < wx + ww)) ? bh : sy); c->bw = borderpx; } @@ -973,12 +967,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; @@ -1097,11 +1094,11 @@ resize(Client *c, int x, int y, int w, int h, Bool sizehints) { w = MAX(w, c->minw); h = MAX(h, c->minh); - - if (c->maxw) + + if(c->maxw) w = MIN(w, c->maxw); - if (c->maxh) + if(c->maxh) h = MIN(h, c->maxh); } if(w <= 0 || h <= 0) @@ -1133,11 +1130,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; @@ -1319,12 +1319,13 @@ setup(void) { /* init screen */ screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); - initfont(FONT); + initfont(font); sx = 0; sy = 0; sw = DisplayWidth(dpy, screen); sh = DisplayHeight(dpy, screen); - bh = dc.font.height + 2; + bh = dc.h = dc.font.height + 2; + lt = layouts; updategeom(); /* init atoms */ @@ -1341,14 +1342,12 @@ setup(void) { cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur); /* init appearance */ - dc.norm[ColBorder] = getcolor(NORMBORDERCOLOR); - dc.norm[ColBG] = getcolor(NORMBGCOLOR); - dc.norm[ColFG] = getcolor(NORMFGCOLOR); - dc.sel[ColBorder] = getcolor(SELBORDERCOLOR); - dc.sel[ColBG] = getcolor(SELBGCOLOR); - dc.sel[ColFG] = getcolor(SELFGCOLOR); - initfont(FONT); - dc.h = bh; + dc.norm[ColBorder] = getcolor(normbordercolor); + dc.norm[ColBG] = getcolor(normbgcolor); + dc.norm[ColFG] = getcolor(normfgcolor); + dc.sel[ColBorder] = getcolor(selbordercolor); + dc.sel[ColBG] = getcolor(selbgcolor); + dc.sel[ColFG] = getcolor(selfgcolor); dc.drawable = XCreatePixmap(dpy, root, DisplayWidth(dpy, screen), bh, DefaultDepth(dpy, screen)); dc.gc = XCreateGC(dpy, root, 0, 0); XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); @@ -1378,7 +1377,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); @@ -1479,7 +1478,7 @@ togglefloating(const Arg *arg) { void togglelayout(const Arg *arg) { - if(arg->v) + if(arg && arg->v) lt = (Layout *)arg->v; else if(++lt == &layouts[LENGTH(layouts)]) lt = &layouts[0]; @@ -1555,10 +1554,10 @@ updategeom(void) { /* window area geometry */ if(XineramaIsActive(dpy)) { info = XineramaQueryScreens(dpy, &i); - wx = info[0].x_org; - wy = showbar && topbar ? info[0].y_org + bh : info[0].y_org; - ww = info[0].width; - wh = showbar ? info[0].height - bh : info[0].height; + wx = info[xidx].x_org; + wy = showbar && topbar ? info[xidx].y_org + bh : info[xidx].y_org; + ww = info[xidx].width; + wh = showbar ? info[xidx].height - bh : info[xidx].height; XFree(info); } else