dwm.c
changeset 1235 13f86ee1a8e6
parent 1234 ec42705c5fac
child 1236 523ba822927f
equal deleted inserted replaced
1234:ec42705c5fac 1235:13f86ee1a8e6
    69 	int x, y, w, h;
    69 	int x, y, w, h;
    70 	int basew, baseh, incw, inch, maxw, maxh, minw, minh;
    70 	int basew, baseh, incw, inch, maxw, maxh, minw, minh;
    71 	int minax, maxax, minay, maxay;
    71 	int minax, maxax, minay, maxay;
    72 	long flags;
    72 	long flags;
    73 	int bw, oldbw;
    73 	int bw, oldbw;
    74 	Bool isbanned, isfixed, isfloating, isurgent;
    74 	Bool isbanned, isfixed, isfloating, ismax, isurgent;
    75 	uint tags;
    75 	uint tags;
    76 	Client *next;
    76 	Client *next;
    77 	Client *prev;
    77 	Client *prev;
    78 	Client *snext;
    78 	Client *snext;
    79 	Window win;
    79 	Window win;
   118 /* function declarations */
   118 /* function declarations */
   119 void applyrules(Client *c);
   119 void applyrules(Client *c);
   120 void arrange(void);
   120 void arrange(void);
   121 void attach(Client *c);
   121 void attach(Client *c);
   122 void attachstack(Client *c);
   122 void attachstack(Client *c);
   123 void ban(Client *c);
       
   124 void buttonpress(XEvent *e);
   123 void buttonpress(XEvent *e);
   125 void checkotherwm(void);
   124 void checkotherwm(void);
   126 void cleanup(void);
   125 void cleanup(void);
   127 void configure(Client *c);
   126 void configure(Client *c);
   128 void configurenotify(XEvent *e);
   127 void configurenotify(XEvent *e);
   174 void tile(void);
   173 void tile(void);
   175 void tileresize(Client *c, int x, int y, int w, int h);
   174 void tileresize(Client *c, int x, int y, int w, int h);
   176 void togglebar(const void *arg);
   175 void togglebar(const void *arg);
   177 void togglefloating(const void *arg);
   176 void togglefloating(const void *arg);
   178 void togglelayout(const void *arg);
   177 void togglelayout(const void *arg);
       
   178 void togglemax(const void *arg);
   179 void toggletag(const void *arg);
   179 void toggletag(const void *arg);
   180 void toggleview(const void *arg);
   180 void toggleview(const void *arg);
   181 void unban(Client *c);
       
   182 void unmanage(Client *c);
   181 void unmanage(Client *c);
   183 void unmapnotify(XEvent *e);
   182 void unmapnotify(XEvent *e);
   184 void updatebar(void);
   183 void updatebar(void);
   185 void updategeom(void);
   184 void updategeom(void);
   186 void updatesizehints(Client *c);
   185 void updatesizehints(Client *c);
   215 	[MapRequest] = maprequest,
   214 	[MapRequest] = maprequest,
   216 	[PropertyNotify] = propertynotify,
   215 	[PropertyNotify] = propertynotify,
   217 	[UnmapNotify] = unmapnotify
   216 	[UnmapNotify] = unmapnotify
   218 };
   217 };
   219 Atom wmatom[WMLast], netatom[NetLast];
   218 Atom wmatom[WMLast], netatom[NetLast];
       
   219 Bool domax = False;
   220 Bool otherwm, readin;
   220 Bool otherwm, readin;
   221 Bool running = True;
   221 Bool running = True;
   222 uint tagset[] = {1, 1}; /* after start, first tag is selected */
   222 uint tagset[] = {1, 1}; /* after start, first tag is selected */
   223 Client *clients = NULL;
   223 Client *clients = NULL;
   224 Client *sel = NULL;
   224 Client *sel = NULL;
   266 arrange(void) {
   266 arrange(void) {
   267 	Client *c;
   267 	Client *c;
   268 
   268 
   269 	for(c = clients; c; c = c->next)
   269 	for(c = clients; c; c = c->next)
   270 		if(VISIBLE(c)) {
   270 		if(VISIBLE(c)) {
   271 			unban(c);
       
   272 			if(!lt->arrange || c->isfloating)
   271 			if(!lt->arrange || c->isfloating)
   273 				resize(c, c->x, c->y, c->w, c->h, True);
   272 				resize(c, c->x, c->y, c->w, c->h, True);
   274 		}
   273 		}
   275 		else
   274 		else if(!c->isbanned) {
   276 			ban(c);
   275 			XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
       
   276 			c->isbanned = True;
       
   277 		}
   277 
   278 
   278 	focus(NULL);
   279 	focus(NULL);
   279 	if(lt->arrange)
   280 	if(lt->arrange && !domax)
   280 		lt->arrange();
   281 		lt->arrange();
   281 	restack();
   282 	restack();
   282 }
   283 }
   283 
   284 
   284 void
   285 void
   291 
   292 
   292 void
   293 void
   293 attachstack(Client *c) {
   294 attachstack(Client *c) {
   294 	c->snext = stack;
   295 	c->snext = stack;
   295 	stack = c;
   296 	stack = c;
   296 }
       
   297 
       
   298 void
       
   299 ban(Client *c) {
       
   300 	if(c->isbanned)
       
   301 		return;
       
   302 	XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
       
   303 	c->isbanned = True;
       
   304 }
   297 }
   305 
   298 
   306 void
   299 void
   307 buttonpress(XEvent *e) {
   300 buttonpress(XEvent *e) {
   308 	uint i, x, mask;
   301 	uint i, x, mask;
   328 						toggleview(&mask);
   321 						toggleview(&mask);
   329 				}
   322 				}
   330 				return;
   323 				return;
   331 			}
   324 			}
   332 		}
   325 		}
   333 		if((ev->x < x + blw) && ev->button == Button1) 
   326 		if(ev->x < x + blw) {
   334 			togglelayout(NULL);
   327 			if(ev->button == Button1) 
       
   328 				togglelayout(NULL);
       
   329 			else if(ev->button == Button3) 
       
   330 				togglemax(NULL);
       
   331 		}
   335 	}
   332 	}
   336 	else if((c = getclient(ev->window))) {
   333 	else if((c = getclient(ev->window))) {
   337 		focus(c);
   334 		focus(c);
   338 		if(CLEANMASK(ev->state) != MODKEY)
   335 		if(CLEANMASK(ev->state) != MODKEY || domax)
   339 			return;
   336 			return;
   340 		if(ev->button == Button1) {
   337 		if(ev->button == Button1)
   341 			restack();
       
   342 			movemouse(c);
   338 			movemouse(c);
   343 		}
       
   344 		else if(ev->button == Button2)
   339 		else if(ev->button == Button2)
   345 			togglefloating(NULL);
   340 			togglefloating(NULL);
   346 		else if(ev->button == Button3 && !c->isfixed) {
   341 		else if(ev->button == Button3 && !c->isfixed)
   347 			restack();
       
   348 			resizemouse(c);
   342 			resizemouse(c);
   349 		}
       
   350 	}
   343 	}
   351 }
   344 }
   352 
   345 
   353 void
   346 void
   354 checkotherwm(void) {
   347 checkotherwm(void) {
   367 }
   360 }
   368 
   361 
   369 void
   362 void
   370 cleanup(void) {
   363 cleanup(void) {
   371 	close(STDIN_FILENO);
   364 	close(STDIN_FILENO);
   372 	while(stack) {
   365 	view(NULL);
   373 		unban(stack);
   366 	while(stack)
   374 		unmanage(stack);
   367 		unmanage(stack);
   375 	}
       
   376 	if(dc.font.set)
   368 	if(dc.font.set)
   377 		XFreeFontSet(dpy, dc.font.set);
   369 		XFreeFontSet(dpy, dc.font.set);
   378 	else
   370 	else
   379 		XFreeFont(dpy, dc.font.xfont);
   371 		XFreeFont(dpy, dc.font.xfont);
   380 	XUngrabKey(dpy, AnyKey, AnyModifier, root);
   372 	XUngrabKey(dpy, AnyKey, AnyModifier, root);
   510 		}
   502 		}
   511 		dc.x += dc.w;
   503 		dc.x += dc.w;
   512 	}
   504 	}
   513 	if(blw > 0) {
   505 	if(blw > 0) {
   514 		dc.w = blw;
   506 		dc.w = blw;
   515 		drawtext(lt->symbol, dc.norm, False);
   507 		drawtext(lt->symbol, dc.norm, domax);
   516 		x = dc.x + dc.w;
   508 		x = dc.x + dc.w;
   517 	}
   509 	}
   518 	else
   510 	else
   519 		x = dc.x;
   511 		x = dc.x;
   520 	dc.w = textw(stext);
   512 	dc.w = textw(stext);
   639 		attachstack(c);
   631 		attachstack(c);
   640 		grabbuttons(c, True);
   632 		grabbuttons(c, True);
   641 	}
   633 	}
   642 	sel = c;
   634 	sel = c;
   643 	if(c) {
   635 	if(c) {
       
   636 		if(domax) {
       
   637 			XMoveResizeWindow(dpy, c->win, wx, wy, ww - 2 * c->bw, wh - 2 * c->bw);
       
   638 			c->ismax = True;
       
   639 		}
   644 		XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]);
   640 		XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]);
   645 		XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
   641 		XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
   646 	}
   642 	}
   647 	else
   643 	else
   648 		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
   644 		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
   958 	if(!c->isfloating)
   954 	if(!c->isfloating)
   959 		c->isfloating = (rettrans == Success) || c->isfixed;
   955 		c->isfloating = (rettrans == Success) || c->isfixed;
   960 	attach(c);
   956 	attach(c);
   961 	attachstack(c);
   957 	attachstack(c);
   962 	XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); /* some windows require this */
   958 	XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); /* some windows require this */
   963 	ban(c);
       
   964 	XMapWindow(dpy, c->win);
   959 	XMapWindow(dpy, c->win);
   965 	setclientstate(c, NormalState);
   960 	setclientstate(c, NormalState);
   966 	arrange();
   961 	arrange();
   967 }
   962 }
   968 
   963 
   993 	int x1, y1, ocx, ocy, di, nx, ny;
   988 	int x1, y1, ocx, ocy, di, nx, ny;
   994 	uint dui;
   989 	uint dui;
   995 	Window dummy;
   990 	Window dummy;
   996 	XEvent ev;
   991 	XEvent ev;
   997 
   992 
       
   993 	restack();
   998 	ocx = nx = c->x;
   994 	ocx = nx = c->x;
   999 	ocy = ny = c->y;
   995 	ocy = ny = c->y;
  1000 	if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
   996 	if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
  1001 	None, cursor[CurMove], CurrentTime) != GrabSuccess)
   997 	None, cursor[CurMove], CurrentTime) != GrabSuccess)
  1002 		return;
   998 		return;
  1128 		y = sh - h - 2 * c->bw;
  1124 		y = sh - h - 2 * c->bw;
  1129 	if(x + w + 2 * c->bw < sx)
  1125 	if(x + w + 2 * c->bw < sx)
  1130 		x = sx;
  1126 		x = sx;
  1131 	if(y + h + 2 * c->bw < sy)
  1127 	if(y + h + 2 * c->bw < sy)
  1132 		y = sy;
  1128 		y = sy;
  1133 	if(c->x != x || c->y != y || c->w != w || c->h != h) {
  1129 	if(c->x != x || c->y != y || c->w != w || c->h != h || c->isbanned || c->ismax) {
       
  1130 		c->isbanned = c->ismax = False;
  1134 		c->x = wc.x = x;
  1131 		c->x = wc.x = x;
  1135 		c->y = wc.y = y;
  1132 		c->y = wc.y = y;
  1136 		c->w = wc.width = w;
  1133 		c->w = wc.width = w;
  1137 		c->h = wc.height = h;
  1134 		c->h = wc.height = h;
  1138 		wc.border_width = c->bw;
  1135 		wc.border_width = c->bw;
  1147 resizemouse(Client *c) {
  1144 resizemouse(Client *c) {
  1148 	int ocx, ocy;
  1145 	int ocx, ocy;
  1149 	int nw, nh;
  1146 	int nw, nh;
  1150 	XEvent ev;
  1147 	XEvent ev;
  1151 
  1148 
       
  1149 	restack();
  1152 	ocx = c->x;
  1150 	ocx = c->x;
  1153 	ocy = c->y;
  1151 	ocy = c->y;
  1154 	if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
  1152 	if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
  1155 	None, cursor[CurResize], CurrentTime) != GrabSuccess)
  1153 	None, cursor[CurResize], CurrentTime) != GrabSuccess)
  1156 		return;
  1154 		return;
  1194 	XWindowChanges wc;
  1192 	XWindowChanges wc;
  1195 
  1193 
  1196 	drawbar();
  1194 	drawbar();
  1197 	if(!sel)
  1195 	if(!sel)
  1198 		return;
  1196 		return;
  1199 	if(sel->isfloating || !lt->arrange)
  1197 	if(domax || sel->isfloating || !lt->arrange)
  1200 		XRaiseWindow(dpy, sel->win);
  1198 		XRaiseWindow(dpy, sel->win);
  1201 	if(lt->arrange) {
  1199 	if(!domax && lt->arrange) {
  1202 		wc.stack_mode = Below;
  1200 		wc.stack_mode = Below;
  1203 		wc.sibling = barwin;
  1201 		wc.sibling = barwin;
  1204 		for(c = stack; c; c = c->snext)
  1202 		for(c = stack; c; c = c->snext)
  1205 			if(!c->isfloating && VISIBLE(c)) {
  1203 			if(!c->isfloating && VISIBLE(c)) {
  1206 				XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc);
  1204 				XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc);
  1530 	else
  1528 	else
  1531 		drawbar();
  1529 		drawbar();
  1532 }
  1530 }
  1533 
  1531 
  1534 void
  1532 void
       
  1533 togglemax(const void *arg) {
       
  1534 	domax = !domax;
       
  1535 	arrange();
       
  1536 }
       
  1537 
       
  1538 void
  1535 toggletag(const void *arg) {
  1539 toggletag(const void *arg) {
  1536 	if(sel && (sel->tags ^ ((*(int *)arg) & TAGMASK))) {
  1540 	if(sel && (sel->tags ^ ((*(int *)arg) & TAGMASK))) {
  1537 		sel->tags ^= (*(int *)arg) & TAGMASK;
  1541 		sel->tags ^= (*(int *)arg) & TAGMASK;
  1538 		arrange();
  1542 		arrange();
  1539 	}
  1543 	}
  1543 toggleview(const void *arg) {
  1547 toggleview(const void *arg) {
  1544 	if((tagset[seltags] ^ ((*(int *)arg) & TAGMASK))) {
  1548 	if((tagset[seltags] ^ ((*(int *)arg) & TAGMASK))) {
  1545 		tagset[seltags] ^= (*(int *)arg) & TAGMASK;
  1549 		tagset[seltags] ^= (*(int *)arg) & TAGMASK;
  1546 		arrange();
  1550 		arrange();
  1547 	}
  1551 	}
  1548 }
       
  1549 
       
  1550 void
       
  1551 unban(Client *c) {
       
  1552 	if(!c->isbanned)
       
  1553 		return;
       
  1554 	XMoveWindow(dpy, c->win, c->x, c->y);
       
  1555 	c->isbanned = False;
       
  1556 }
  1552 }
  1557 
  1553 
  1558 void
  1554 void
  1559 unmanage(Client *c) {
  1555 unmanage(Client *c) {
  1560 	XWindowChanges wc;
  1556 	XWindowChanges wc;