X-Git-Url: https://git.xinqibao.xyz/dwm.git/blobdiff_plain/2bd46d1ce62e35d2785f43bb9f6f331d3309f66f..bf76cefe47749f784d4ee3b7b71c1c86460e236b:/dwm.c?ds=inline

diff --git a/dwm.c b/dwm.c
index fcdab10..a13f07b 100644
--- a/dwm.c
+++ b/dwm.c
@@ -53,13 +53,14 @@
 #define MOUSEMASK       (BUTTONMASK|PointerMotionMask)
 #define TAGMASK         ((int)((1LL << LENGTH(tags)) - 1))
 #define TEXTW(x)        (textnw(x, strlen(x)) + dc.font.height)
+#define ISVISIBLE(x)    (x->tags & tagset[seltags])
 
 /* enums */
 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,
+enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
        ClkClientWin, ClkRootWin, ClkLast };             /* clicks */
 
 /* typedefs */
@@ -89,10 +90,12 @@ struct Client {
 	int basew, baseh, incw, inch, maxw, maxh, minw, minh;
 	int bw, oldbw;
 	uint tags;
-	Bool isbanned, isfixed, isfloating, isurgent;
+	Bool isfixed, isfloating, isurgent;
 	Client *next;
 	Client *snext;
 	Window win;
+	void *aux;
+	void (*freeaux)(void *);
 };
 
 typedef struct {
@@ -273,14 +276,13 @@ arrange(void) {
 	Client *c;
 
 	for(c = clients; c; c = c->next)
-		if(c->tags & tagset[seltags]) { /* is visible */
-			c->isbanned = False;
+		if(ISVISIBLE(c)) {
+			XMoveWindow(dpy, c->win, c->x, c->y);
 			if(!lt[sellt]->arrange || c->isfloating)
 				resize(c, c->x, c->y, c->w, c->h, True);
 		}
-		else if(!c->isbanned) {
+		else {
 			XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
-			c->isbanned = True;
 		}
 
 	focus(NULL);
@@ -304,17 +306,18 @@ attachstack(Client *c) {
 void
 buttonpress(XEvent *e) {
 	uint i, x, click;
+	Arg arg = {0};
 	Client *c;
 	XButtonPressedEvent *ev = &e->xbutton;
 
 	click = ClkRootWin;
 	if(ev->window == barwin) {
 		i = x = 0;
-		do
-			x += TEXTW(tags[i]);
-		while(ev->x >= x && ++i < LENGTH(tags));
-		if(i < LENGTH(tags))
-			click = i;
+		do x += TEXTW(tags[i]); while(ev->x >= x && ++i < LENGTH(tags));
+		if(i < LENGTH(tags)) {
+			click = ClkTagBar;
+			arg.ui = 1 << i;
+		}
 		else if(ev->x < x + blw)
 			click = ClkLtSymbol;
 		else if(ev->x > wx + ww - TEXTW(stext))
@@ -330,7 +333,7 @@ buttonpress(XEvent *e) {
 	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);
+			buttons[i].func(click == ClkTagBar ? &arg : &buttons[i].arg);
 }
 
 void
@@ -428,7 +431,7 @@ configurerequest(XEvent *e) {
 				c->y = sy + (sh / 2 - c->h / 2); /* center in y direction */
 			if((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight)))
 				configure(c);
-			if(!c->isbanned)
+			if(ISVISIBLE(c))
 				XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
 		}
 		else
@@ -605,8 +608,8 @@ expose(XEvent *e) {
 
 void
 focus(Client *c) {
-	if(!c || c->isbanned)
-		for(c = stack; c && c->isbanned; c = c->snext);
+	if(!c || !ISVISIBLE(c))
+		for(c = stack; c && !ISVISIBLE(c); c = c->snext);
 	if(sel && sel != c) {
 		grabbuttons(sel, False);
 		XSetWindowBorder(dpy, sel->win, dc.norm[ColBorder]);
@@ -639,17 +642,17 @@ focusstack(const Arg *arg) {
 	if(!sel)
 		return;
 	if (arg->i > 0) {
-		for(c = sel->next; c && c->isbanned; c = c->next);
+		for(c = sel->next; c && !ISVISIBLE(c); c = c->next);
 		if(!c)
-			for(c = clients; c && c->isbanned; c = c->next);
+			for(c = clients; c && !ISVISIBLE(c); c = c->next);
 	}
 	else {
 		for(i = clients; i != sel; i = i->next)
-			if (!i->isbanned)
+			if(ISVISIBLE(i))
 				c = i;
 		if(!c)
 			for(; i; i = i->next)
-				if (!i->isbanned)
+				if(ISVISIBLE(i))
 					c = i;
 	}
 	if(c) {
@@ -722,19 +725,18 @@ gettextprop(Window w, Atom atom, char *text, uint size) {
 
 void
 grabbuttons(Client *c, Bool focused) {
-	int i, j;
-	uint buttons[]   = { Button1, Button2, Button3 };
-	uint modifiers[] = { MODKEY, MODKEY|LockMask, MODKEY|numlockmask, MODKEY|numlockmask|LockMask };
+	uint i, j;
+	uint modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
 
 	XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
-	if(focused)
+	if(focused) {
 		for(i = 0; i < LENGTH(buttons); i++)
-			for(j = 0; j < LENGTH(modifiers); j++)
-				XGrabButton(dpy, buttons[i], modifiers[j], c->win, False,
-					BUTTONMASK, GrabModeAsync, GrabModeSync, None, None);
-	else
+			if(buttons[i].click == ClkClientWin)
+				for(j = 0; j < LENGTH(modifiers); j++)
+					XGrabButton(dpy, buttons[i].button, buttons[i].mask | modifiers[j], c->win, False, BUTTONMASK, GrabModeAsync, GrabModeSync, None, None);
+        } else
 		XGrabButton(dpy, AnyButton, AnyModifier, c->win, False,
-			BUTTONMASK, GrabModeAsync, GrabModeSync, None, None);
+		            BUTTONMASK, GrabModeAsync, GrabModeSync, None, None);
 }
 
 void
@@ -928,7 +930,7 @@ manage(Window w, XWindowAttributes *wa) {
 		XRaiseWindow(dpy, c->win);
 	attach(c);
 	attachstack(c);
-	XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); /* some windows require this */
+	XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */
 	XMapWindow(dpy, c->win);
 	setclientstate(c, NormalState);
 	arrange();
@@ -961,7 +963,7 @@ monocle(void) {
 	Client *c;
 
 	for(c = nexttiled(clients); c; c = nexttiled(c->next))
-		resize(c, wx, wy, ww, wh, resizehints);
+		resize(c, wx, wy, ww - 2 * c->bw, wh - 2 * c->bw, resizehints);
 }
 
 void
@@ -1018,7 +1020,7 @@ movemouse(const Arg *arg) {
 
 Client *
 nexttiled(Client *c) {
-	for(; c && (c->isfloating || c->isbanned); c = c->next);
+	for(; c && (c->isfloating || !ISVISIBLE(c)); c = c->next);
 	return c;
 }
 
@@ -1113,7 +1115,7 @@ resize(Client *c, int x, int y, int w, int h, Bool sizehints) {
 		h = bh;
 	if(w < bh)
 		w = bh;
-	if(!c->isbanned || c->x != x || c->y != y || c->w != w || c->h != h) {
+	if(c->x != x || c->y != y || c->w != w || c->h != h) {
 		c->x = wc.x = x;
 		c->y = wc.y = y;
 		c->w = wc.width = w;
@@ -1189,7 +1191,7 @@ restack(void) {
 		wc.stack_mode = Below;
 		wc.sibling = barwin;
 		for(c = stack; c; c = c->snext)
-			if(!c->isfloating && !c->isbanned) {
+			if(!c->isfloating && ISVISIBLE(c)) {
 				XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc);
 				wc.sibling = c->win;
 			}
@@ -1295,8 +1297,9 @@ setclientstate(Client *c, long state) {
 
 void
 setlayout(const Arg *arg) {
-	sellt ^= 1;
-	if(arg && arg->v && arg->v != lt[sellt])
+	if(!arg || !arg->v || arg->v != lt[sellt])
+		sellt ^= 1;
+	if(arg && arg->v)
 		lt[sellt] = (Layout *)arg->v;
 	if(sel)
 		arrange();
@@ -1518,6 +1521,8 @@ unmanage(Client *c) {
 	detachstack(c);
 	if(sel == c)
 		focus(NULL);
+	if(c->aux && c->freeaux)
+		c->freeaux(c->aux);
 	XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
 	setclientstate(c, WithdrawnState);
 	free(c);
@@ -1641,6 +1646,8 @@ updatewmhints(Client *c) {
 
 void
 view(const Arg *arg) {
+	if(arg && (arg->i & TAGMASK) == tagset[seltags])
+		return;
 	seltags ^= 1; /* toggle sel tagset */
 	if(arg && (arg->ui & TAGMASK))
 		tagset[seltags] = arg->i & TAGMASK;
@@ -1702,7 +1709,9 @@ main(int argc, char *argv[]) {
 	else if(argc != 1)
 		eprint("usage: dwm [-v]\n");
 
-	setlocale(LC_CTYPE, "");
+	if(!setlocale(LC_CTYPE, "") || !XSupportsLocale())
+		fprintf(stderr, "warning: no locale support\n");
+
 	if(!(dpy = XOpenDisplay(0)))
 		eprint("dwm: cannot open display\n");