dwm.c
changeset 1448 d012c6babc13
parent 1447 4fff5050c835
child 1449 8fcc541b5238
equal deleted inserted replaced
1447:4fff5050c835 1448:d012c6babc13
   134 	Client *clients;
   134 	Client *clients;
   135 	Client *sel;
   135 	Client *sel;
   136 	Client *stack;
   136 	Client *stack;
   137 	Monitor *next;
   137 	Monitor *next;
   138 	Window barwin;
   138 	Window barwin;
       
   139 	Layout *lt[2];
   139 };
   140 };
   140 
   141 
   141 typedef struct {
   142 typedef struct {
   142 	const char *class;
   143 	const char *class;
   143 	const char *instance;
   144 	const char *instance;
   259 static Bool otherwm;
   260 static Bool otherwm;
   260 static Bool running = True;
   261 static Bool running = True;
   261 static Cursor cursor[CurLast];
   262 static Cursor cursor[CurLast];
   262 static Display *dpy;
   263 static Display *dpy;
   263 static DC dc;
   264 static DC dc;
   264 static Layout *lt[] = { NULL, NULL };
       
   265 static Monitor *mons = NULL, *selmon = NULL;
   265 static Monitor *mons = NULL, *selmon = NULL;
   266 static Window root;
   266 static Window root;
   267 
   267 
   268 /* configuration, allows nested code to access above variables */
   268 /* configuration, allows nested code to access above variables */
   269 #include "config.h"
   269 #include "config.h"
   374 	/* optimise two loops into one, check focus(NULL) */
   374 	/* optimise two loops into one, check focus(NULL) */
   375 	for(m = mons; m; m = m->next)
   375 	for(m = mons; m; m = m->next)
   376 		showhide(m->stack);
   376 		showhide(m->stack);
   377 	focus(NULL);
   377 	focus(NULL);
   378 	for(m = mons; m; m = m->next) {
   378 	for(m = mons; m; m = m->next) {
   379 		if(lt[m->sellt]->arrange)
   379 		if(m->lt[m->sellt]->arrange)
   380 			lt[m->sellt]->arrange(m);
   380 			m->lt[m->sellt]->arrange(m);
   381 		restack(m);
   381 		restack(m);
   382 	}
   382 	}
   383 }
   383 }
   384 
   384 
   385 void
   385 void
   454 	Arg a = {.ui = ~0};
   454 	Arg a = {.ui = ~0};
   455 	Layout foo = { "", NULL };
   455 	Layout foo = { "", NULL };
   456 	Monitor *m;
   456 	Monitor *m;
   457 
   457 
   458 	view(&a);
   458 	view(&a);
   459 	lt[selmon->sellt] = &foo;
   459 	selmon->lt[selmon->sellt] = &foo;
   460 	for(m = mons; m; m = m->next)
   460 	for(m = mons; m; m = m->next)
   461 		while(m->stack)
   461 		while(m->stack)
   462 			unmanage(m->stack);
   462 			unmanage(m->stack);
   463 	if(dc.font.set)
   463 	if(dc.font.set)
   464 		XFreeFontSet(dpy, dc.font.set);
   464 		XFreeFontSet(dpy, dc.font.set);
   545 	XWindowChanges wc;
   545 	XWindowChanges wc;
   546 
   546 
   547 	if((c = wintoclient(ev->window))) {
   547 	if((c = wintoclient(ev->window))) {
   548 		if(ev->value_mask & CWBorderWidth)
   548 		if(ev->value_mask & CWBorderWidth)
   549 			c->bw = ev->border_width;
   549 			c->bw = ev->border_width;
   550 		else if(c->isfloating || !lt[selmon->sellt]->arrange) {
   550 		else if(c->isfloating || !selmon->lt[selmon->sellt]->arrange) {
   551 			m = c->mon;
   551 			m = c->mon;
   552 			if(ev->value_mask & CWX)
   552 			if(ev->value_mask & CWX)
   553 				c->x = m->mx + ev->x;
   553 				c->x = m->mx + ev->x;
   554 			if(ev->value_mask & CWY)
   554 			if(ev->value_mask & CWY)
   555 				c->y = m->my + ev->y;
   555 				c->y = m->my + ev->y;
   666 		           occ & 1 << i, urg & 1 << i, col);
   666 		           occ & 1 << i, urg & 1 << i, col);
   667 		dc.x += dc.w;
   667 		dc.x += dc.w;
   668 	}
   668 	}
   669 	if(blw > 0) {
   669 	if(blw > 0) {
   670 		dc.w = blw;
   670 		dc.w = blw;
   671 		drawtext(lt[m->sellt]->symbol, dc.norm, False);
   671 		drawtext(m->lt[m->sellt]->symbol, dc.norm, False);
   672 		x = dc.x + dc.w;
   672 		x = dc.x + dc.w;
   673 	}
   673 	}
   674 	else
   674 	else
   675 		x = dc.x;
   675 		x = dc.x;
   676 	if(m == selmon) { /* status is only drawn on selected monitor */
   676 	if(m == selmon) { /* status is only drawn on selected monitor */
  1168 					nx = selmon->wx + selmon->ww - WIDTH(c);
  1168 					nx = selmon->wx + selmon->ww - WIDTH(c);
  1169 				if(abs(selmon->wy - ny) < snap)
  1169 				if(abs(selmon->wy - ny) < snap)
  1170 					ny = selmon->wy;
  1170 					ny = selmon->wy;
  1171 				else if(abs((selmon->wy + selmon->wh) - (ny + HEIGHT(c))) < snap)
  1171 				else if(abs((selmon->wy + selmon->wh) - (ny + HEIGHT(c))) < snap)
  1172 					ny = selmon->wy + selmon->wh - HEIGHT(c);
  1172 					ny = selmon->wy + selmon->wh - HEIGHT(c);
  1173 				if(!c->isfloating && lt[selmon->sellt]->arrange
  1173 				if(!c->isfloating && selmon->lt[selmon->sellt]->arrange
  1174 				                  && (abs(nx - c->x) > snap || abs(ny - c->y) > snap))
  1174 				                  && (abs(nx - c->x) > snap || abs(ny - c->y) > snap))
  1175 					togglefloating(NULL);
  1175 					togglefloating(NULL);
  1176 			}
  1176 			}
  1177 			if(!lt[selmon->sellt]->arrange || c->isfloating)
  1177 			if(!selmon->lt[selmon->sellt]->arrange || c->isfloating)
  1178 				resize(c, nx, ny, c->w, c->h, True);
  1178 				resize(c, nx, ny, c->w, c->h, True);
  1179 			break;
  1179 			break;
  1180 		}
  1180 		}
  1181 	}
  1181 	}
  1182 	while(ev.type != ButtonRelease);
  1182 	while(ev.type != ButtonRelease);
  1287 		case MotionNotify:
  1287 		case MotionNotify:
  1288 			nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1);
  1288 			nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1);
  1289 			nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1);
  1289 			nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1);
  1290 			if(snap && nw >= selmon->wx && nw <= selmon->wx + selmon->ww
  1290 			if(snap && nw >= selmon->wx && nw <= selmon->wx + selmon->ww
  1291 			        && nh >= selmon->wy && nh <= selmon->wy + selmon->wh) {
  1291 			        && nh >= selmon->wy && nh <= selmon->wy + selmon->wh) {
  1292 				if(!c->isfloating && lt[selmon->sellt]->arrange
  1292 				if(!c->isfloating && selmon->lt[selmon->sellt]->arrange
  1293 				   && (abs(nw - c->w) > snap || abs(nh - c->h) > snap))
  1293 				   && (abs(nw - c->w) > snap || abs(nh - c->h) > snap))
  1294 					togglefloating(NULL);
  1294 					togglefloating(NULL);
  1295 			}
  1295 			}
  1296 			if(!lt[selmon->sellt]->arrange || c->isfloating)
  1296 			if(!selmon->lt[selmon->sellt]->arrange || c->isfloating)
  1297 				resize(c, c->x, c->y, nw, nh, True);
  1297 				resize(c, c->x, c->y, nw, nh, True);
  1298 			break;
  1298 			break;
  1299 		}
  1299 		}
  1300 	}
  1300 	}
  1301 	while(ev.type != ButtonRelease);
  1301 	while(ev.type != ButtonRelease);
  1316 	XWindowChanges wc;
  1316 	XWindowChanges wc;
  1317 
  1317 
  1318 	drawbars();
  1318 	drawbars();
  1319 	if(!m->sel)
  1319 	if(!m->sel)
  1320 		return;
  1320 		return;
  1321 	if(m->sel->isfloating || !lt[m->sellt]->arrange)
  1321 	if(m->sel->isfloating || !m->lt[m->sellt]->arrange)
  1322 		XRaiseWindow(dpy, m->sel->win);
  1322 		XRaiseWindow(dpy, m->sel->win);
  1323 	if(lt[m->sellt]->arrange) {
  1323 	if(m->lt[m->sellt]->arrange) {
  1324 		wc.stack_mode = Below;
  1324 		wc.stack_mode = Below;
  1325 		wc.sibling = m->barwin;
  1325 		wc.sibling = m->barwin;
  1326 		for(c = m->stack; c; c = c->snext)
  1326 		for(c = m->stack; c; c = c->snext)
  1327 			if(!c->isfloating && ISVISIBLE(c)) {
  1327 			if(!c->isfloating && ISVISIBLE(c)) {
  1328 				XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc);
  1328 				XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc);
  1394 			PropModeReplace, (unsigned char *)data, 2);
  1394 			PropModeReplace, (unsigned char *)data, 2);
  1395 }
  1395 }
  1396 
  1396 
  1397 void
  1397 void
  1398 setlayout(const Arg *arg) {
  1398 setlayout(const Arg *arg) {
  1399 	if(!arg || !arg->v || arg->v != lt[selmon->sellt])
  1399 	if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
  1400 		selmon->sellt ^= 1;
  1400 		selmon->sellt ^= 1;
  1401 	if(arg && arg->v)
  1401 	if(arg && arg->v)
  1402 		lt[selmon->sellt] = (Layout *)arg->v;
  1402 		selmon->lt[selmon->sellt] = (Layout *)arg->v;
  1403 	if(selmon->sel)
  1403 	if(selmon->sel)
  1404 		arrange();
  1404 		arrange();
  1405 	else
  1405 	else
  1406 		drawbars();
  1406 		drawbars();
  1407 }
  1407 }
  1409 /* arg > 1.0 will set mfact absolutly */
  1409 /* arg > 1.0 will set mfact absolutly */
  1410 void
  1410 void
  1411 setmfact(const Arg *arg) {
  1411 setmfact(const Arg *arg) {
  1412 	float f;
  1412 	float f;
  1413 
  1413 
  1414 	if(!arg || !lt[selmon->sellt]->arrange)
  1414 	if(!arg || !selmon->lt[selmon->sellt]->arrange)
  1415 		return;
  1415 		return;
  1416 	f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
  1416 	f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
  1417 	if(f < 0.1 || f > 0.9)
  1417 	if(f < 0.1 || f > 0.9)
  1418 		return;
  1418 		return;
  1419 	selmon->mfact = f;
  1419 	selmon->mfact = f;
  1431 	root = RootWindow(dpy, screen);
  1431 	root = RootWindow(dpy, screen);
  1432 	initfont(font);
  1432 	initfont(font);
  1433 	sw = DisplayWidth(dpy, screen);
  1433 	sw = DisplayWidth(dpy, screen);
  1434 	sh = DisplayHeight(dpy, screen);
  1434 	sh = DisplayHeight(dpy, screen);
  1435 	bh = dc.h = dc.font.height + 2;
  1435 	bh = dc.h = dc.font.height + 2;
  1436 	lt[0] = &layouts[0];
       
  1437 	lt[1] = &layouts[1 % LENGTH(layouts)];
       
  1438 	updategeom();
  1436 	updategeom();
  1439 	/* init atoms */
  1437 	/* init atoms */
  1440 	wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
  1438 	wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
  1441 	wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
  1439 	wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
  1442 	wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False);
  1440 	wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False);
  1482 showhide(Client *c) {
  1480 showhide(Client *c) {
  1483 	if(!c)
  1481 	if(!c)
  1484 		return;
  1482 		return;
  1485 	if(ISVISIBLE(c)) { /* show clients top down */
  1483 	if(ISVISIBLE(c)) { /* show clients top down */
  1486 		XMoveWindow(dpy, c->win, c->x, c->y);
  1484 		XMoveWindow(dpy, c->win, c->x, c->y);
  1487 		if(!lt[c->mon->sellt]->arrange || c->isfloating)
  1485 		if(!c->mon->lt[c->mon->sellt]->arrange || c->isfloating)
  1488 			resize(c, c->x, c->y, c->w, c->h, False);
  1486 			resize(c, c->x, c->y, c->w, c->h, False);
  1489 		showhide(c->snext);
  1487 		showhide(c->snext);
  1490 	}
  1488 	}
  1491 	else { /* hide clients bottom up */
  1489 	else { /* hide clients bottom up */
  1492 		showhide(c->snext);
  1490 		showhide(c->snext);
  1728 		m->sellt = 0;
  1726 		m->sellt = 0;
  1729 		m->tagset[0] = m->tagset[1] = 1;
  1727 		m->tagset[0] = m->tagset[1] = 1;
  1730 		m->mfact = mfact;
  1728 		m->mfact = mfact;
  1731 		m->showbar = SHOWBAR;
  1729 		m->showbar = SHOWBAR;
  1732 		m->topbar = TOPBAR;
  1730 		m->topbar = TOPBAR;
       
  1731 		m->lt[0] = &layouts[0];
       
  1732 		m->lt[1] = &layouts[1 % LENGTH(layouts)];
  1733 		updatebarpos(m);
  1733 		updatebarpos(m);
  1734 	}
  1734 	}
  1735 	/* reassign left over clients of disappeared monitors */
  1735 	/* reassign left over clients of disappeared monitors */
  1736 	for(tm = mons; tm; tm = tm->next)
  1736 	for(tm = mons; tm; tm = tm->next)
  1737 		while(tm->clients) {
  1737 		while(tm->clients) {
  1914 
  1914 
  1915 void
  1915 void
  1916 zoom(const Arg *arg) {
  1916 zoom(const Arg *arg) {
  1917 	Client *c = selmon->sel;
  1917 	Client *c = selmon->sel;
  1918 
  1918 
  1919 	if(!lt[selmon->sellt]->arrange
  1919 	if(!selmon->lt[selmon->sellt]->arrange
  1920 	|| lt[selmon->sellt]->arrange == monocle
  1920 	|| selmon->lt[selmon->sellt]->arrange == monocle
  1921 	|| (selmon->sel && selmon->sel->isfloating))
  1921 	|| (selmon->sel && selmon->sel->isfloating))
  1922 		return;
  1922 		return;
  1923 	if(c == nexttiled(selmon->clients))
  1923 	if(c == nexttiled(selmon->clients))
  1924 		if(!c || !(c = nexttiled(c->next)))
  1924 		if(!c || !(c = nexttiled(c->next)))
  1925 			return;
  1925 			return;