dwm.c
changeset 1183 b20561489ffb
parent 1182 9940d125b703
child 1184 bf63402f3b33
equal deleted inserted replaced
1182:9940d125b703 1183:b20561489ffb
    66 /* typedefs */
    66 /* typedefs */
    67 typedef struct Client Client;
    67 typedef struct Client Client;
    68 struct Client {
    68 struct Client {
    69 	char name[256];
    69 	char name[256];
    70 	int x, y, w, h;
    70 	int x, y, w, h;
       
    71 	int fx, fy, fw, fh;
    71 	int basew, baseh, incw, inch, maxw, maxh, minw, minh;
    72 	int basew, baseh, incw, inch, maxw, maxh, minw, minh;
    72 	int minax, maxax, minay, maxay;
    73 	int minax, maxax, minay, maxay;
    73 	long flags;
    74 	long flags;
    74 	unsigned int bw, oldbw;
    75 	unsigned int bw, oldbw;
    75 	Bool isbanned, isfixed, isfloating, isurgent;
    76 	Bool isbanned, isfixed, isfloating, isurgent;
   142 void drawtext(const char *text, unsigned long col[ColLast], Bool invert);
   143 void drawtext(const char *text, unsigned long col[ColLast], Bool invert);
   143 void *emallocz(unsigned int size);
   144 void *emallocz(unsigned int size);
   144 void enternotify(XEvent *e);
   145 void enternotify(XEvent *e);
   145 void eprint(const char *errstr, ...);
   146 void eprint(const char *errstr, ...);
   146 void expose(XEvent *e);
   147 void expose(XEvent *e);
   147 void floating(void); /* default floating layout */
       
   148 void focus(Client *c);
   148 void focus(Client *c);
   149 void focusin(XEvent *e);
   149 void focusin(XEvent *e);
   150 void focusnext(const char *arg);
   150 void focusnext(const char *arg);
   151 void focusprev(const char *arg);
   151 void focusprev(const char *arg);
   152 Client *getclient(Window w);
   152 Client *getclient(Window w);
   284 void
   284 void
   285 arrange(void) {
   285 arrange(void) {
   286 	Client *c;
   286 	Client *c;
   287 
   287 
   288 	for(c = clients; c; c = c->next)
   288 	for(c = clients; c; c = c->next)
   289 		if(isvisible(c))
   289 		if(isvisible(c)) {
   290 			unban(c);
   290 			unban(c);
       
   291 			if(lt->isfloating || c->isfloating)
       
   292 				resize(c, c->fx, c->fy, c->fw, c->fh, True);
       
   293 		}
   291 		else
   294 		else
   292 			ban(c);
   295 			ban(c);
   293 
   296 
   294 	focus(NULL);
   297 	focus(NULL);
   295 	lt->arrange();
   298 	if(lt->arrange)
       
   299 		lt->arrange();
   296 	restack();
   300 	restack();
   297 }
   301 }
   298 
   302 
   299 void
   303 void
   300 attach(Client *c) {
   304 attach(Client *c) {
   358 		if(ev->button == Button1) {
   362 		if(ev->button == Button1) {
   359 			restack();
   363 			restack();
   360 			movemouse(c);
   364 			movemouse(c);
   361 		}
   365 		}
   362 		else if(ev->button == Button2) {
   366 		else if(ev->button == Button2) {
   363 			if((floating != lt->arrange) && c->isfloating)
   367 			if(!lt->isfloating && c->isfloating)
   364 				togglefloating(NULL);
   368 				togglefloating(NULL);
   365 			else
   369 			else
   366 				zoom(NULL);
   370 				zoom(NULL);
   367 		}
   371 		}
   368 		else if(ev->button == Button3 && !c->isfixed) {
   372 		else if(ev->button == Button3 && !c->isfixed) {
   668 	if(ev->count == 0 && (ev->window == barwin))
   672 	if(ev->count == 0 && (ev->window == barwin))
   669 		drawbar();
   673 		drawbar();
   670 }
   674 }
   671 
   675 
   672 void
   676 void
   673 floating(void) { /* default floating layout */
       
   674 	Client *c;
       
   675 
       
   676 	for(c = clients; c; c = c->next)
       
   677 		if(isvisible(c))
       
   678 			resize(c, c->x, c->y, c->w, c->h, True);
       
   679 }
       
   680 
       
   681 void
       
   682 focus(Client *c) {
   677 focus(Client *c) {
   683 	if(!c || (c && !isvisible(c)))
   678 	if(!c || (c && !isvisible(c)))
   684 		for(c = stack; c && !isvisible(c); c = c->snext);
   679 		for(c = stack; c && !isvisible(c); c = c->snext);
   685 	if(sel && sel != c) {
   680 	if(sel && sel != c) {
   686 		grabbuttons(sel, False);
   681 		grabbuttons(sel, False);
   991 	c->win = w;
   986 	c->win = w;
   992 
   987 
   993 	/* geometry */
   988 	/* geometry */
   994 	c->x = wa->x;
   989 	c->x = wa->x;
   995 	c->y = wa->y;
   990 	c->y = wa->y;
   996 	c->w = wa->width;
   991 	c->w = c->fw = wa->width;
   997 	c->h = wa->height;
   992 	c->h = c->fh = wa->height;
   998 	c->oldbw = wa->border_width;
   993 	c->oldbw = wa->border_width;
   999 	if(c->w == sw && c->h == sh) {
   994 	if(c->w == sw && c->h == sh) {
  1000 		c->x = sx;
   995 		c->x = sx;
  1001 		c->y = sy;
   996 		c->y = sy;
  1002 		c->bw = wa->border_width;
   997 		c->bw = wa->border_width;
  1008 			c->y = wy + wh - c->h - 2 * c->bw;
  1003 			c->y = wy + wh - c->h - 2 * c->bw;
  1009 		c->x = MAX(c->x, wx);
  1004 		c->x = MAX(c->x, wx);
  1010 		c->y = MAX(c->y, wy);
  1005 		c->y = MAX(c->y, wy);
  1011 		c->bw = BORDERPX;
  1006 		c->bw = BORDERPX;
  1012 	}
  1007 	}
       
  1008 	c->fx = c->x;
       
  1009 	c->fy = c->y;
  1013 
  1010 
  1014 	wc.border_width = c->bw;
  1011 	wc.border_width = c->bw;
  1015 	XConfigureWindow(dpy, w, CWBorderWidth, &wc);
  1012 	XConfigureWindow(dpy, w, CWBorderWidth, &wc);
  1016 	XSetWindowBorder(dpy, w, dc.norm[ColBorder]);
  1013 	XSetWindowBorder(dpy, w, dc.norm[ColBorder]);
  1017 	configure(c); /* propagates border_width, if size doesn't change */
  1014 	configure(c); /* propagates border_width, if size doesn't change */
  1103 				ny = wy;
  1100 				ny = wy;
  1104 			else if(abs((wy + wh) - (ny + c->h + 2 * c->bw)) < SNAP)
  1101 			else if(abs((wy + wh) - (ny + c->h + 2 * c->bw)) < SNAP)
  1105 				ny = wy + wh - c->h - 2 * c->bw;
  1102 				ny = wy + wh - c->h - 2 * c->bw;
  1106 			if(!c->isfloating && !lt->isfloating && (abs(nx - c->x) > SNAP || abs(ny - c->y) > SNAP))
  1103 			if(!c->isfloating && !lt->isfloating && (abs(nx - c->x) > SNAP || abs(ny - c->y) > SNAP))
  1107 				togglefloating(NULL);
  1104 				togglefloating(NULL);
  1108 			if((lt->isfloating) || c->isfloating)
  1105 			if(lt->isfloating || c->isfloating) {
       
  1106 				c->fx = nx;
       
  1107 				c->fy = ny;
  1109 				resize(c, nx, ny, c->w, c->h, False);
  1108 				resize(c, nx, ny, c->w, c->h, False);
       
  1109 			}
  1110 			break;
  1110 			break;
  1111 		}
  1111 		}
  1112 	}
  1112 	}
  1113 }
  1113 }
  1114 
  1114 
  1259 			break;
  1259 			break;
  1260 		case MotionNotify:
  1260 		case MotionNotify:
  1261 			XSync(dpy, False);
  1261 			XSync(dpy, False);
  1262 			nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1);
  1262 			nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1);
  1263 			nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1);
  1263 			nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1);
  1264 			if(!c->isfloating && !lt->isfloating && (abs(nw - c->w) > SNAP || abs(nh - c->h) > SNAP))
  1264 			if(!c->isfloating && !lt->isfloating && (abs(nw - c->w) > SNAP || abs(nh - c->h) > SNAP)) {
       
  1265 				c->fx = c->x;
       
  1266 				c->fy = c->y;
  1265 				togglefloating(NULL);
  1267 				togglefloating(NULL);
  1266 			if((lt->isfloating) || c->isfloating)
  1268 			}
       
  1269 			if((lt->isfloating) || c->isfloating) {
  1267 				resize(c, c->x, c->y, nw, nh, True);
  1270 				resize(c, c->x, c->y, nw, nh, True);
       
  1271 				c->fw = nw;
       
  1272 				c->fh = nh;
       
  1273 			}
  1268 			break;
  1274 			break;
  1269 		}
  1275 		}
  1270 	}
  1276 	}
  1271 }
  1277 }
  1272 
  1278 
  1282 	if(sel->isfloating || lt->isfloating)
  1288 	if(sel->isfloating || lt->isfloating)
  1283 		XRaiseWindow(dpy, sel->win);
  1289 		XRaiseWindow(dpy, sel->win);
  1284 	if(!lt->isfloating) {
  1290 	if(!lt->isfloating) {
  1285 		wc.stack_mode = Below;
  1291 		wc.stack_mode = Below;
  1286 		wc.sibling = barwin;
  1292 		wc.sibling = barwin;
  1287 		if(!sel->isfloating) {
  1293 		for(c = stack; c; c = c->snext)
  1288 			XConfigureWindow(dpy, sel->win, CWSibling|CWStackMode, &wc);
  1294 			if(!c->isfloating && isvisible(c)) {
  1289 			wc.sibling = sel->win;
  1295 				XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc);
  1290 		}
  1296 				wc.sibling = c->win;
  1291 		for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
  1297 			}
  1292 			if(c == sel)
       
  1293 				continue;
       
  1294 			XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc);
       
  1295 			wc.sibling = c->win;
       
  1296 		}
       
  1297 	}
  1298 	}
  1298 	XSync(dpy, False);
  1299 	XSync(dpy, False);
  1299 	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
  1300 	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
  1300 }
  1301 }
  1301 
  1302 
  1839 	if(memcmp(seltags, tmp, TAGSZ) != 0) {
  1840 	if(memcmp(seltags, tmp, TAGSZ) != 0) {
  1840 		seltags = viewtags[viewtags_set ^= 1];  /* toggle tagset */
  1841 		seltags = viewtags[viewtags_set ^= 1];  /* toggle tagset */
  1841 		memcpy(seltags, tmp, TAGSZ);
  1842 		memcpy(seltags, tmp, TAGSZ);
  1842 		arrange();
  1843 		arrange();
  1843 	}
  1844 	}
       
  1845 	else
       
  1846 		viewprevtag(NULL);
  1844 }
  1847 }
  1845 
  1848 
  1846 void
  1849 void
  1847 viewprevtag(const char *arg) {
  1850 viewprevtag(const char *arg) {
  1848 	seltags = viewtags[viewtags_set ^= 1];  /* toggle tagset */
  1851 	seltags = viewtags[viewtags_set ^= 1];  /* toggle tagset */
  1883 
  1886 
  1884 void
  1887 void
  1885 zoom(const char *arg) {
  1888 zoom(const char *arg) {
  1886 	Client *c = sel;
  1889 	Client *c = sel;
  1887 
  1890 
  1888 	if(!sel || lt->isfloating || sel->isfloating)
       
  1889 		return;
       
  1890 	if(c == nexttiled(clients))
  1891 	if(c == nexttiled(clients))
  1891 		if(!(c = nexttiled(c->next)))
  1892 		if(!c || !(c = nexttiled(c->next)))
  1892 			return;
  1893 			return;
  1893 	detach(c);
  1894 	if(!lt->isfloating && !sel->isfloating) {
  1894 	attach(c);
  1895 		detach(c);
  1895 	focus(c);
  1896 		attach(c);
       
  1897 		focus(c);
       
  1898 	}
  1896 	arrange();
  1899 	arrange();
  1897 }
  1900 }
  1898 
  1901 
  1899 int
  1902 int
  1900 main(int argc, char *argv[]) {
  1903 main(int argc, char *argv[]) {