dwm.c
changeset 1401 8cee6e329111
parent 1400 a5312d498a58
child 1402 d0721df4028c
equal deleted inserted replaced
1400:a5312d498a58 1401:8cee6e329111
    42 
    42 
    43 /* macros */
    43 /* macros */
    44 #define BUTTONMASK              (ButtonPressMask|ButtonReleaseMask)
    44 #define BUTTONMASK              (ButtonPressMask|ButtonReleaseMask)
    45 #define CLEANMASK(mask)         (mask & ~(numlockmask|LockMask))
    45 #define CLEANMASK(mask)         (mask & ~(numlockmask|LockMask))
    46 #define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH))
    46 #define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH))
    47 #define ISVISIBLE(M, C)         ((M) == (&mon[C->mon]) && (C->tags & tagset[M->seltags]))
    47 #define ISVISIBLE(M, C)         ((M) == (&mon[C->mon]) && (C->tags & M->tagset[M->seltags]))
    48 #define LENGTH(X)               (sizeof X / sizeof X[0])
    48 #define LENGTH(X)               (sizeof X / sizeof X[0])
    49 #define MAX(a, b)               ((a) > (b) ? (a) : (b))
    49 #define MAX(A, B)               ((A) > (B) ? (A) : (B))
    50 #define MIN(a, b)               ((a) < (b) ? (a) : (b))
    50 #define MIN(A, B)               ((A) < (B) ? (A) : (B))
    51 #define MOUSEMASK               (BUTTONMASK|PointerMotionMask)
    51 #define MOUSEMASK               (BUTTONMASK|PointerMotionMask)
    52 #define WIDTH(x)                ((x)->w + 2 * (x)->bw)
    52 #define WIDTH(X)                ((X)->w + 2 * (X)->bw)
    53 #define HEIGHT(x)               ((x)->h + 2 * (x)->bw)
    53 #define HEIGHT(X)               ((X)->h + 2 * (X)->bw)
    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 
    56 
    57 /* enums */
    57 /* enums */
    58 enum { CurNormal, CurResize, CurMove, CurLast };        /* cursor */
    58 enum { CurNormal, CurResize, CurMove, CurLast };        /* cursor */
    59 enum { ColBorder, ColFG, ColBG, ColLast };              /* color */
    59 enum { ColBorder, ColFG, ColBG, ColLast };              /* color */
    60 enum { NetSupported, NetWMName, NetLast };              /* EWMH atoms */
    60 enum { NetSupported, NetWMName, NetLast };              /* EWMH atoms */
   119 	float mfact;
   119 	float mfact;
   120 	int by, btx;          /* bar geometry */
   120 	int by, btx;          /* bar geometry */
   121 	int wx, wy, ww, wh;   /* window area  */
   121 	int wx, wy, ww, wh;   /* window area  */
   122 	unsigned int seltags;
   122 	unsigned int seltags;
   123 	unsigned int sellt;
   123 	unsigned int sellt;
       
   124 	unsigned int tagset[2];
   124 	Bool showbar;
   125 	Bool showbar;
   125 	Bool topbar;
   126 	Bool topbar;
   126 	Window barwin;
   127 	Window barwin;
   127 } Monitor;
   128 } Monitor;
   128 
   129 
   282 		if(ch.res_class)
   283 		if(ch.res_class)
   283 			XFree(ch.res_class);
   284 			XFree(ch.res_class);
   284 		if(ch.res_name)
   285 		if(ch.res_name)
   285 			XFree(ch.res_name);
   286 			XFree(ch.res_name);
   286 	}
   287 	}
   287 	c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : tagset[mon[c->mon].seltags];
   288 	c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : mon[c->mon].tagset[mon[c->mon].seltags];
   288 }
   289 }
   289 
   290 
   290 Bool
   291 Bool
   291 applysizehints(Client *c, int *x, int *y, int *w, int *h) {
   292 applysizehints(Client *c, int *x, int *y, int *w, int *h) {
   292 	Bool baseismin;
   293 	Bool baseismin;
   603 	}
   604 	}
   604 #endif /* XINERAMA */
   605 #endif /* XINERAMA */
   605 	m->btx = dc.x;
   606 	m->btx = dc.x;
   606 	for(i = 0; i < LENGTH(tags); i++) {
   607 	for(i = 0; i < LENGTH(tags); i++) {
   607 		dc.w = TEXTW(tags[i]);
   608 		dc.w = TEXTW(tags[i]);
   608 		col = tagset[m->seltags] & 1 << i ? dc.sel : dc.norm;
   609 		col = m->tagset[m->seltags] & 1 << i ? dc.sel : dc.norm;
   609 		drawtext(tags[i], col, urg & 1 << i);
   610 		drawtext(tags[i], col, urg & 1 << i);
   610 		drawsquare(m == selmon && sel && sel->tags & 1 << i,
   611 		drawsquare(m == selmon && sel && sel->tags & 1 << i,
   611 		           occ & 1 << i, urg & 1 << i, col);
   612 		           occ & 1 << i, urg & 1 << i, col);
   612 		dc.x += dc.w;
   613 		dc.x += dc.w;
   613 	}
   614 	}
   746 		XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
   747 		XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
   747 	}
   748 	}
   748 	else
   749 	else
   749 		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
   750 		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
   750 	sel = c;
   751 	sel = c;
   751 	if(c)
       
   752 		selmon = &mon[c->mon];
       
   753 	drawbars();
   752 	drawbars();
   754 }
   753 }
   755 
   754 
   756 void
   755 void
   757 focusin(XEvent *e) { /* there are some broken focus acquiring clients */
   756 focusin(XEvent *e) { /* there are some broken focus acquiring clients */
  1411 showhide(Client *c) {
  1410 showhide(Client *c) {
  1412 	if(!c)
  1411 	if(!c)
  1413 		return;
  1412 		return;
  1414 	if(ISVISIBLE((&mon[c->mon]), c)) { /* show clients top down */
  1413 	if(ISVISIBLE((&mon[c->mon]), c)) { /* show clients top down */
  1415 		XMoveWindow(dpy, c->win, c->x, c->y);
  1414 		XMoveWindow(dpy, c->win, c->x, c->y);
  1416 		if(!lt[selmon->sellt]->arrange || c->isfloating)
  1415 		if(!lt[mon[c->mon].sellt]->arrange || c->isfloating)
  1417 			resize(c, c->x, c->y, c->w, c->h);
  1416 			resize(c, c->x, c->y, c->w, c->h);
  1418 		showhide(c->snext);
  1417 		showhide(c->snext);
  1419 	}
  1418 	}
  1420 	else { /* hide clients bottom up */
  1419 	else { /* hide clients bottom up */
  1421 		showhide(c->snext);
  1420 		showhide(c->snext);
  1538 	}
  1537 	}
  1539 }
  1538 }
  1540 
  1539 
  1541 void
  1540 void
  1542 toggleview(const Arg *arg) {
  1541 toggleview(const Arg *arg) {
  1543 	unsigned int mask = tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
  1542 	unsigned int mask = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
  1544 
  1543 
  1545 	if(mask) {
  1544 	if(mask) {
  1546 		tagset[selmon->seltags] = mask;
  1545 		selmon->tagset[selmon->seltags] = mask;
  1547 		arrange();
  1546 		arrange();
  1548 	}
  1547 	}
  1549 }
  1548 }
  1550 
  1549 
  1551 void
  1550 void
  1593 			for(c = clients; c; c = c->next)
  1592 			for(c = clients; c; c = c->next)
  1594 				if(c->mon >= n)
  1593 				if(c->mon >= n)
  1595 					c->mon = n - 1;
  1594 					c->mon = n - 1;
  1596 			if(!(mon = (Monitor *)realloc(mon, sizeof(Monitor) * n)))
  1595 			if(!(mon = (Monitor *)realloc(mon, sizeof(Monitor) * n)))
  1597 				die("fatal: could not realloc() %u bytes\n", sizeof(Monitor) * nmons);
  1596 				die("fatal: could not realloc() %u bytes\n", sizeof(Monitor) * nmons);
       
  1597 			selmon = NULL;
  1598 		}
  1598 		}
  1599 		for(i = 0; i < n ; i++) {
  1599 		for(i = 0; i < n ; i++) {
  1600 			/* TODO: consider re-using XineramaScreenInfo */
  1600 			/* TODO: consider re-using XineramaScreenInfo */
  1601 			mon[i].symbol[0] = '[';
  1601 			mon[i].symbol[0] = '[';
  1602 			mon[i].symbol[1] = '0' + info[i].screen_number;
  1602 			mon[i].symbol[1] = '0' + info[i].screen_number;
  1604 			mon[i].symbol[3] = 0;
  1604 			mon[i].symbol[3] = 0;
  1605 			if(!selmon) { /* not initialised yet */
  1605 			if(!selmon) { /* not initialised yet */
  1606 				mon[i].mfact = mfact;
  1606 				mon[i].mfact = mfact;
  1607 				mon[i].showbar = showbar;
  1607 				mon[i].showbar = showbar;
  1608 				mon[i].topbar = topbar;
  1608 				mon[i].topbar = topbar;
       
  1609 				mon[i].tagset[0] = mon[i].tagset[1] = 1;
  1609 			}
  1610 			}
  1610 			mon[i].wx = info[i].x_org;
  1611 			mon[i].wx = info[i].x_org;
  1611 			mon[i].wy = mon[i].showbar && mon[i].topbar ? info[i].y_org + bh : info[i].y_org;
  1612 			mon[i].wy = mon[i].showbar && mon[i].topbar ? info[i].y_org + bh : info[i].y_org;
  1612 			mon[i].ww = info[i].width;
  1613 			mon[i].ww = info[i].width;
  1613 			mon[i].wh = mon[i].showbar ? info[i].height - bh : info[i].height;
  1614 			mon[i].wh = mon[i].showbar ? info[i].height - bh : info[i].height;
  1647 			mon[0].symbol[2] = ']';
  1648 			mon[0].symbol[2] = ']';
  1648 			mon[0].symbol[3] = 0;
  1649 			mon[0].symbol[3] = 0;
  1649 			mon[0].mfact = mfact;
  1650 			mon[0].mfact = mfact;
  1650 			mon[0].showbar = showbar;
  1651 			mon[0].showbar = showbar;
  1651 			mon[0].topbar = topbar;
  1652 			mon[0].topbar = topbar;
       
  1653 			mon[0].tagset[0] = mon[0].tagset[1] = 1;
  1652 		}
  1654 		}
  1653 		mon[0].wx = sx;
  1655 		mon[0].wx = sx;
  1654 		mon[0].wy = mon[0].showbar && mon[0].topbar ? sy + bh : sy;
  1656 		mon[0].wy = mon[0].showbar && mon[0].topbar ? sy + bh : sy;
  1655 		mon[0].ww = sw;
  1657 		mon[0].ww = sw;
  1656 		mon[0].wh = mon[0].showbar ? sh - bh : sh;
  1658 		mon[0].wh = mon[0].showbar ? sh - bh : sh;
  1758 	}
  1760 	}
  1759 }
  1761 }
  1760 
  1762 
  1761 void
  1763 void
  1762 view(const Arg *arg) {
  1764 view(const Arg *arg) {
  1763 	if((arg->ui & TAGMASK) == tagset[selmon->seltags])
  1765 	if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
  1764 		return;
  1766 		return;
  1765 	selmon->seltags ^= 1; /* toggle sel tagset */
  1767 	selmon->seltags ^= 1; /* toggle sel tagset */
  1766 	if(arg->ui & TAGMASK)
  1768 	if(arg->ui & TAGMASK)
  1767 		tagset[selmon->seltags] = arg->ui & TAGMASK;
  1769 		selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
  1768 	arrange();
  1770 	arrange();
  1769 }
  1771 }
  1770 
  1772 
  1771 /* There's no way to check accesses to destroyed windows, thus those cases are
  1773 /* There's no way to check accesses to destroyed windows, thus those cases are
  1772  * ignored (especially on UnmapNotify's).  Other types of errors call Xlibs
  1774  * ignored (especially on UnmapNotify's).  Other types of errors call Xlibs