dwm.c
changeset 1244 c8bd07e7d006
parent 1243 7850bc57cbdc
child 1245 2488c46e002c
equal deleted inserted replaced
1243:7850bc57cbdc 1244:c8bd07e7d006
    51 #define LENGTH(x)       (sizeof x / sizeof x[0])
    51 #define LENGTH(x)       (sizeof x / sizeof x[0])
    52 #define MAXTAGLEN       16
    52 #define MAXTAGLEN       16
    53 #define MOUSEMASK       (BUTTONMASK|PointerMotionMask)
    53 #define MOUSEMASK       (BUTTONMASK|PointerMotionMask)
    54 #define TAGMASK         ((int)((1LL << LENGTH(tags)) - 1))
    54 #define TAGMASK         ((int)((1LL << LENGTH(tags)) - 1))
    55 #define TEXTW(x)        (textnw(x, strlen(x)) + dc.font.height)
    55 #define TEXTW(x)        (textnw(x, strlen(x)) + dc.font.height)
    56 #define VISIBLE(x)      ((x)->tags & tagset[seltags])
       
    57 
    56 
    58 /* enums */
    57 /* enums */
    59 enum { CurNormal, CurResize, CurMove, CurLast };        /* cursor */
    58 enum { CurNormal, CurResize, CurMove, CurLast };        /* cursor */
    60 enum { ColBorder, ColFG, ColBG, ColLast };              /* color */
    59 enum { ColBorder, ColFG, ColBG, ColLast };              /* color */
    61 enum { NetSupported, NetWMName, NetLast };              /* EWMH atoms */
    60 enum { NetSupported, NetWMName, NetLast };              /* EWMH atoms */
    70 	int x, y, w, h;
    69 	int x, y, w, h;
    71 	int basew, baseh, incw, inch, maxw, maxh, minw, minh;
    70 	int basew, baseh, incw, inch, maxw, maxh, minw, minh;
    72 	int minax, maxax, minay, maxay;
    71 	int minax, maxax, minay, maxay;
    73 	long flags;
    72 	long flags;
    74 	int bw, oldbw;
    73 	int bw, oldbw;
    75 	Bool isbanned, isfixed, isfloating, ismax, isurgent;
    74 	Bool isbanned, isfixed, isfloating, ismoved, isurgent;
    76 	uint tags;
    75 	uint tags;
    77 	Client *next;
    76 	Client *next;
    78 	Client *prev;
    77 	Client *prev;
    79 	Client *snext;
    78 	Client *snext;
    80 	Window win;
    79 	Window win;
   261 void
   260 void
   262 arrange(void) {
   261 arrange(void) {
   263 	Client *c;
   262 	Client *c;
   264 
   263 
   265 	for(c = clients; c; c = c->next)
   264 	for(c = clients; c; c = c->next)
   266 		if(VISIBLE(c)) {
   265 		if(c->tags & tagset[seltags]) { /* is visible */
   267 			if(!lt->arrange || c->isfloating)
   266 			if(ismax && !c->isfixed) {
       
   267 				XMoveResizeWindow(dpy, c->win, wx, wy, ww - 2 * c->bw, wh - 2 * c->bw);
       
   268 				c->ismoved = True;
       
   269 			}
       
   270 			else if(!lt->arrange || c->isfloating)
   268 				resize(c, c->x, c->y, c->w, c->h, True);
   271 				resize(c, c->x, c->y, c->w, c->h, True);
       
   272 			c->isbanned = False;
   269 		}
   273 		}
   270 		else if(!c->isbanned) {
   274 		else if(!c->isbanned) {
   271 			XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
   275 			XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
   272 			c->isbanned = True;
   276 			c->isbanned = c->ismoved = True;
   273 		}
   277 		}
   274 
   278 
   275 	focus(NULL);
   279 	focus(NULL);
   276 	if(lt->arrange && !ismax)
   280 	if(lt->arrange && !ismax)
   277 		lt->arrange();
   281 		lt->arrange();
   326 				togglemax(NULL);
   330 				togglemax(NULL);
   327 		}
   331 		}
   328 	}
   332 	}
   329 	else if((c = getclient(ev->window))) {
   333 	else if((c = getclient(ev->window))) {
   330 		focus(c);
   334 		focus(c);
   331 		if(CLEANMASK(ev->state) != MODKEY || ismax)
   335 		if(CLEANMASK(ev->state) != MODKEY || (ismax && !c->isfixed))
   332 			return;
   336 			return;
   333 		if(ev->button == Button1)
   337 		if(ev->button == Button1)
   334 			movemouse(c);
   338 			movemouse(c);
   335 		else if(ev->button == Button2)
   339 		else if(ev->button == Button2)
   336 			togglefloating(NULL);
   340 			togglefloating(NULL);
   429 			if((c->y - sy + c->h) > sh && c->isfloating)
   433 			if((c->y - sy + c->h) > sh && c->isfloating)
   430 				c->y = sy + (sh / 2 - c->h / 2); /* center in y direction */
   434 				c->y = sy + (sh / 2 - c->h / 2); /* center in y direction */
   431 			if((ev->value_mask & (CWX|CWY))
   435 			if((ev->value_mask & (CWX|CWY))
   432 			&& !(ev->value_mask & (CWWidth|CWHeight)))
   436 			&& !(ev->value_mask & (CWWidth|CWHeight)))
   433 				configure(c);
   437 				configure(c);
   434 			if(VISIBLE(c))
   438 			if(!c->isbanned)
   435 				XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
   439 				XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
   436 		}
   440 		}
   437 		else
   441 		else
   438 			configure(c);
   442 			configure(c);
   439 	}
   443 	}
   482 drawbar(void) {
   486 drawbar(void) {
   483 	int i, x;
   487 	int i, x;
   484 	Client *c;
   488 	Client *c;
   485 
   489 
   486 	dc.x = 0;
   490 	dc.x = 0;
   487 	for(c = stack; c && !VISIBLE(c); c = c->snext);
   491 	for(c = stack; c && c->isbanned; c = c->snext);
   488 	for(i = 0; i < LENGTH(tags); i++) {
   492 	for(i = 0; i < LENGTH(tags); i++) {
   489 		dc.w = TEXTW(tags[i]);
   493 		dc.w = TEXTW(tags[i]);
   490 		if(tagset[seltags] & 1 << i) {
   494 		if(tagset[seltags] & 1 << i) {
   491 			drawtext(tags[i], dc.sel, isurgent(i));
   495 			drawtext(tags[i], dc.sel, isurgent(i));
   492 			drawsquare(c && c->tags & 1 << i, isoccupied(i), isurgent(i), dc.sel);
   496 			drawsquare(c && c->tags & 1 << i, isoccupied(i), isurgent(i), dc.sel);
   513 	drawtext(stext, dc.norm, False);
   517 	drawtext(stext, dc.norm, False);
   514 	if((dc.w = dc.x - x) > bh) {
   518 	if((dc.w = dc.x - x) > bh) {
   515 		dc.x = x;
   519 		dc.x = x;
   516 		if(c) {
   520 		if(c) {
   517 			drawtext(c->name, dc.sel, False);
   521 			drawtext(c->name, dc.sel, False);
   518 			drawsquare(False, c->isfloating, False, dc.sel);
   522 			drawsquare(c->isfixed, c->isfloating, False, dc.sel);
   519 		}
   523 		}
   520 		else
   524 		else
   521 			drawtext(NULL, dc.norm, False);
   525 			drawtext(NULL, dc.norm, False);
   522 	}
   526 	}
   523 	XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, ww, bh, 0, 0);
   527 	XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, ww, bh, 0, 0);
   613 		drawbar();
   617 		drawbar();
   614 }
   618 }
   615 
   619 
   616 void
   620 void
   617 focus(Client *c) {
   621 focus(Client *c) {
   618 	if(!c || (c && !VISIBLE(c)))
   622 	if(!c || (c && c->isbanned))
   619 		for(c = stack; c && !VISIBLE(c); c = c->snext);
   623 		for(c = stack; c && c->isbanned; c = c->snext);
   620 	if(sel && sel != c) {
   624 	if(sel && sel != c) {
   621 		grabbuttons(sel, False);
   625 		grabbuttons(sel, False);
   622 		XSetWindowBorder(dpy, sel->win, dc.norm[ColBorder]);
   626 		XSetWindowBorder(dpy, sel->win, dc.norm[ColBorder]);
   623 	}
   627 	}
   624 	if(c) {
   628 	if(c) {
   626 		attachstack(c);
   630 		attachstack(c);
   627 		grabbuttons(c, True);
   631 		grabbuttons(c, True);
   628 	}
   632 	}
   629 	sel = c;
   633 	sel = c;
   630 	if(c) {
   634 	if(c) {
   631 		if(ismax) {
       
   632 			XMoveResizeWindow(dpy, c->win, wx, wy, ww - 2 * c->bw, wh - 2 * c->bw);
       
   633 			c->ismax = True;
       
   634 		}
       
   635 		XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]);
   635 		XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]);
   636 		XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
   636 		XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
   637 	}
   637 	}
   638 	else
   638 	else
   639 		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
   639 		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
   652 focusnext(const void *arg) {
   652 focusnext(const void *arg) {
   653 	Client *c;
   653 	Client *c;
   654 
   654 
   655 	if(!sel)
   655 	if(!sel)
   656 		return;
   656 		return;
   657 	for(c = sel->next; c && !VISIBLE(c); c = c->next);
   657 	for(c = sel->next; c && c->isbanned; c = c->next);
   658 	if(!c)
   658 	if(!c)
   659 		for(c = clients; c && !VISIBLE(c); c = c->next);
   659 		for(c = clients; c && c->isbanned; c = c->next);
   660 	if(c) {
   660 	if(c) {
   661 		focus(c);
   661 		focus(c);
   662 		restack();
   662 		restack();
   663 	}
   663 	}
   664 }
   664 }
   667 focusprev(const void *arg) {
   667 focusprev(const void *arg) {
   668 	Client *c;
   668 	Client *c;
   669 
   669 
   670 	if(!sel)
   670 	if(!sel)
   671 		return;
   671 		return;
   672 	for(c = sel->prev; c && !VISIBLE(c); c = c->prev);
   672 	for(c = sel->prev; c && c->isbanned; c = c->prev);
   673 	if(!c) {
   673 	if(!c) {
   674 		for(c = clients; c && c->next; c = c->next);
   674 		for(c = clients; c && c->next; c = c->next);
   675 		for(; c && !VISIBLE(c); c = c->prev);
   675 		for(; c && c->isbanned; c = c->prev);
   676 	}
   676 	}
   677 	if(c) {
   677 	if(c) {
   678 		focus(c);
   678 		focus(c);
   679 		restack();
   679 		restack();
   680 	}
   680 	}
  1025 	}
  1025 	}
  1026 }
  1026 }
  1027 
  1027 
  1028 Client *
  1028 Client *
  1029 nexttiled(Client *c) {
  1029 nexttiled(Client *c) {
  1030 	for(; c && (c->isfloating || !VISIBLE(c)); c = c->next);
  1030 	for(; c && (c->isfloating || c->isbanned); c = c->next);
  1031 	return c;
  1031 	return c;
  1032 }
  1032 }
  1033 
  1033 
  1034 void
  1034 void
  1035 propertynotify(XEvent *e) {
  1035 propertynotify(XEvent *e) {
  1121 		y = sy;
  1121 		y = sy;
  1122 	if(h < bh)
  1122 	if(h < bh)
  1123 		h = bh;
  1123 		h = bh;
  1124 	if(w < bh)
  1124 	if(w < bh)
  1125 		w = bh;
  1125 		w = bh;
  1126 	if(c->x != x || c->y != y || c->w != w || c->h != h || c->isbanned || c->ismax) {
  1126 	if(c->x != x || c->y != y || c->w != w || c->h != h || c->ismoved) {
  1127 		c->isbanned = c->ismax = False;
  1127 		c->isbanned = c->ismoved = False;
  1128 		c->x = wc.x = x;
  1128 		c->x = wc.x = x;
  1129 		c->y = wc.y = y;
  1129 		c->y = wc.y = y;
  1130 		c->w = wc.width = w;
  1130 		c->w = wc.width = w;
  1131 		c->h = wc.height = h;
  1131 		c->h = wc.height = h;
  1132 		wc.border_width = c->bw;
  1132 		wc.border_width = c->bw;
  1195 		XRaiseWindow(dpy, sel->win);
  1195 		XRaiseWindow(dpy, sel->win);
  1196 	if(!ismax && lt->arrange) {
  1196 	if(!ismax && lt->arrange) {
  1197 		wc.stack_mode = Below;
  1197 		wc.stack_mode = Below;
  1198 		wc.sibling = barwin;
  1198 		wc.sibling = barwin;
  1199 		for(c = stack; c; c = c->snext)
  1199 		for(c = stack; c; c = c->snext)
  1200 			if(!c->isfloating && VISIBLE(c)) {
  1200 			if(!c->isfloating && !c->isbanned) {
  1201 				XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc);
  1201 				XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc);
  1202 				wc.sibling = c->win;
  1202 				wc.sibling = c->win;
  1203 			}
  1203 			}
  1204 	}
  1204 	}
  1205 	XSync(dpy, False);
  1205 	XSync(dpy, False);
  1477 
  1477 
  1478 void
  1478 void
  1479 togglefloating(const void *arg) {
  1479 togglefloating(const void *arg) {
  1480 	if(!sel)
  1480 	if(!sel)
  1481 		return;
  1481 		return;
  1482 	sel->isfloating = !sel->isfloating;
  1482 	sel->isfloating = !sel->isfloating || sel->isfixed;
  1483 	if(sel->isfloating)
  1483 	if(sel->isfloating)
  1484 		resize(sel, sel->x, sel->y, sel->w, sel->h, True);
  1484 		resize(sel, sel->x, sel->y, sel->w, sel->h, True);
  1485 	arrange();
  1485 	arrange();
  1486 }
  1486 }
  1487 
  1487