dwm.c
changeset 1392 ee12ffbf93df
parent 1391 1409113e7808
child 1393 deaa276abac1
equal deleted inserted replaced
1391:1409113e7808 1392:ee12ffbf93df
   127 	Bool isfloating;
   127 	Bool isfloating;
   128 } Rule;
   128 } Rule;
   129 
   129 
   130 /* function declarations */
   130 /* function declarations */
   131 static void applyrules(Client *c);
   131 static void applyrules(Client *c);
   132 static void applysizehints(Client *c, int *w, int *h);
   132 static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h);
   133 static void arrange(void);
   133 static void arrange(void);
   134 static void attach(Client *c);
   134 static void attach(Client *c);
   135 static void attachstack(Client *c);
   135 static void attachstack(Client *c);
   136 static void buttonpress(XEvent *e);
   136 static void buttonpress(XEvent *e);
   137 static void checkotherwm(void);
   137 static void checkotherwm(void);
   250 	unsigned int i;
   250 	unsigned int i;
   251 	Rule *r;
   251 	Rule *r;
   252 	XClassHint ch = { 0 };
   252 	XClassHint ch = { 0 };
   253 
   253 
   254 	/* rule matching */
   254 	/* rule matching */
       
   255 	c->isfloating = c->tags = 0;
   255 	if(XGetClassHint(dpy, c->win, &ch)) {
   256 	if(XGetClassHint(dpy, c->win, &ch)) {
   256 		for(i = 0; i < LENGTH(rules); i++) {
   257 		for(i = 0; i < LENGTH(rules); i++) {
   257 			r = &rules[i];
   258 			r = &rules[i];
   258 			if((!r->title || strstr(c->name, r->title))
   259 			if((!r->title || strstr(c->name, r->title))
   259 			&& (!r->class || (ch.res_class && strstr(ch.res_class, r->class)))
   260 			&& (!r->class || (ch.res_class && strstr(ch.res_class, r->class)))
   260 			&& (!r->instance || (ch.res_name && strstr(ch.res_name, r->instance)))) {
   261 			&& (!r->instance || (ch.res_name && strstr(ch.res_name, r->instance)))) {
   261 				c->isfloating = r->isfloating;
   262 				c->isfloating = r->isfloating;
   262 				c->tags |= r->tags & TAGMASK ? r->tags & TAGMASK : tagset[seltags]; 
   263 				c->tags |= r->tags; 
   263 			}
   264 			}
   264 		}
   265 		}
   265 		if(ch.res_class)
   266 		if(ch.res_class)
   266 			XFree(ch.res_class);
   267 			XFree(ch.res_class);
   267 		if(ch.res_name)
   268 		if(ch.res_name)
   268 			XFree(ch.res_name);
   269 			XFree(ch.res_name);
   269 	}
   270 	}
   270 	if(!c->tags)
   271 	c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : tagset[seltags];
   271 		c->tags = tagset[seltags];
   272 }
   272 }
   273 
   273 
   274 Bool
   274 void
   275 applysizehints(Client *c, int *x, int *y, int *w, int *h) {
   275 applysizehints(Client *c, int *w, int *h) {
       
   276 	Bool baseismin;
   276 	Bool baseismin;
   277 
       
   278 	if(!resizehints && !c->isfloating)
       
   279 		return;
       
   280 
       
   281 	/* see last two sentences in ICCCM 4.1.2.3 */
       
   282 	baseismin = c->basew == c->minw && c->baseh == c->minh;
       
   283 
   277 
   284 	/* set minimum possible */
   278 	/* set minimum possible */
   285 	*w = MAX(1, *w);
   279 	*w = MAX(1, *w);
   286 	*h = MAX(1, *h);
   280 	*h = MAX(1, *h);
   287 
   281 
   288 	if(!baseismin) { /* temporarily remove base dimensions */
   282 	if(*x > sx + sw)
   289 		*w -= c->basew;
   283 		*x = sw - WIDTH(c);
   290 		*h -= c->baseh;
   284 	if(*y > sy + sh)
   291 	}
   285 		*y = sh - HEIGHT(c);
   292 
   286 	if(*x + *w + 2 * c->bw < sx)
   293 	/* adjust for aspect limits */
   287 		*x = sx;
   294 	if(c->mina > 0 && c->maxa > 0) {
   288 	if(*y + *h + 2 * c->bw < sy)
   295 		if(c->maxa < (float)*w / *h)
   289 		*y = sy;
   296 			*w = *h * c->maxa;
   290 	if(*h < bh)
   297 		else if(c->mina < (float)*h / *w)
   291 		*h = bh;
   298 			*h = *w * c->mina;
   292 	if(*w < bh)
   299 	}
   293 		*w = bh;
   300 
   294 
   301 	if(baseismin) { /* increment calculation requires this */
   295 	if(resizehints || c->isfloating) {
   302 		*w -= c->basew;
   296 		/* see last two sentences in ICCCM 4.1.2.3 */
   303 		*h -= c->baseh;
   297 		baseismin = c->basew == c->minw && c->baseh == c->minh;
   304 	}
   298 
   305 
   299 		if(!baseismin) { /* temporarily remove base dimensions */
   306 	/* adjust for increment value */
   300 			*w -= c->basew;
   307 	if(c->incw)
   301 			*h -= c->baseh;
   308 		*w -= *w % c->incw;
   302 		}
   309 	if(c->inch)
   303 
   310 		*h -= *h % c->inch;
   304 		/* adjust for aspect limits */
   311 
   305 		if(c->mina > 0 && c->maxa > 0) {
   312 	/* restore base dimensions */
   306 			if(c->maxa < (float)*w / *h)
   313 	*w += c->basew;
   307 				*w = *h * c->maxa;
   314 	*h += c->baseh;
   308 			else if(c->mina < (float)*h / *w)
   315 
   309 				*h = *w * c->mina;
   316 	*w = MAX(*w, c->minw);
   310 		}
   317 	*h = MAX(*h, c->minh);
   311 
   318 
   312 		if(baseismin) { /* increment calculation requires this */
   319 	if(c->maxw)
   313 			*w -= c->basew;
   320 		*w = MIN(*w, c->maxw);
   314 			*h -= c->baseh;
   321 
   315 		}
   322 	if(c->maxh)
   316 
   323 		*h = MIN(*h, c->maxh);
   317 		/* adjust for increment value */
       
   318 		if(c->incw)
       
   319 			*w -= *w % c->incw;
       
   320 		if(c->inch)
       
   321 			*h -= *h % c->inch;
       
   322 
       
   323 		/* restore base dimensions */
       
   324 		*w += c->basew;
       
   325 		*h += c->baseh;
       
   326 
       
   327 		*w = MAX(*w, c->minw);
       
   328 		*h = MAX(*h, c->minh);
       
   329 
       
   330 		if(c->maxw)
       
   331 			*w = MIN(*w, c->maxw);
       
   332 
       
   333 		if(c->maxh)
       
   334 			*h = MIN(*h, c->maxh);
       
   335 	}
       
   336 	return *x != c->x || *y != c->y || *w != c->w || *h != c->h;
   324 }
   337 }
   325 
   338 
   326 void
   339 void
   327 arrange(void) {
   340 arrange(void) {
   328 	unsigned int nt;
   341 	unsigned int nt;
  1003 	ocy = c->y;
  1016 	ocy = c->y;
  1004 	if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
  1017 	if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
  1005 	None, cursor[CurMove], CurrentTime) != GrabSuccess)
  1018 	None, cursor[CurMove], CurrentTime) != GrabSuccess)
  1006 		return;
  1019 		return;
  1007 	XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui);
  1020 	XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui);
  1008 	if(usegrab)
       
  1009 		XGrabServer(dpy);
       
  1010 	do {
  1021 	do {
  1011 		XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
  1022 		XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
  1012 		switch (ev.type) {
  1023 		switch (ev.type) {
  1013 		case ConfigureRequest:
  1024 		case ConfigureRequest:
  1014 		case Expose:
  1025 		case Expose:
  1035 				resize(c, nx, ny, c->w, c->h);
  1046 				resize(c, nx, ny, c->w, c->h);
  1036 			break;
  1047 			break;
  1037 		}
  1048 		}
  1038 	}
  1049 	}
  1039 	while(ev.type != ButtonRelease);
  1050 	while(ev.type != ButtonRelease);
  1040 	if(usegrab)
       
  1041 		XUngrabServer(dpy);
       
  1042 	XUngrabPointer(dpy, CurrentTime);
  1051 	XUngrabPointer(dpy, CurrentTime);
  1043 }
  1052 }
  1044 
  1053 
  1045 Client *
  1054 Client *
  1046 nexttiled(Client *c) {
  1055 nexttiled(Client *c) {
  1089 
  1098 
  1090 void
  1099 void
  1091 resize(Client *c, int x, int y, int w, int h) {
  1100 resize(Client *c, int x, int y, int w, int h) {
  1092 	XWindowChanges wc;
  1101 	XWindowChanges wc;
  1093 
  1102 
  1094 	applysizehints(c, &w, &h);
  1103 	if(applysizehints(c, &x, &y, &w, &h)) {
  1095 	if(w <= 0 || h <= 0)
       
  1096 		return;
       
  1097 	if(x > sx + sw)
       
  1098 		x = sw - WIDTH(c);
       
  1099 	if(y > sy + sh)
       
  1100 		y = sh - HEIGHT(c);
       
  1101 	if(x + w + 2 * c->bw < sx)
       
  1102 		x = sx;
       
  1103 	if(y + h + 2 * c->bw < sy)
       
  1104 		y = sy;
       
  1105 	if(h < bh)
       
  1106 		h = bh;
       
  1107 	if(w < bh)
       
  1108 		w = bh;
       
  1109 	if(c->x != x || c->y != y || c->w != w || c->h != h) {
       
  1110 		c->x = wc.x = x;
  1104 		c->x = wc.x = x;
  1111 		c->y = wc.y = y;
  1105 		c->y = wc.y = y;
  1112 		c->w = wc.width = w;
  1106 		c->w = wc.width = w;
  1113 		c->h = wc.height = h;
  1107 		c->h = wc.height = h;
  1114 		wc.border_width = c->bw;
  1108 		wc.border_width = c->bw;
  1133 	ocy = c->y;
  1127 	ocy = c->y;
  1134 	if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
  1128 	if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
  1135 	None, cursor[CurResize], CurrentTime) != GrabSuccess)
  1129 	None, cursor[CurResize], CurrentTime) != GrabSuccess)
  1136 		return;
  1130 		return;
  1137 	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
  1131 	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
  1138 	if(usegrab)
       
  1139 		XGrabServer(dpy);
       
  1140 	do {
  1132 	do {
  1141 		XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
  1133 		XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
  1142 		switch(ev.type) {
  1134 		switch(ev.type) {
  1143 		case ConfigureRequest:
  1135 		case ConfigureRequest:
  1144 		case Expose:
  1136 		case Expose:
  1159 				resize(c, c->x, c->y, nw, nh);
  1151 				resize(c, c->x, c->y, nw, nh);
  1160 			break;
  1152 			break;
  1161 		}
  1153 		}
  1162 	}
  1154 	}
  1163 	while(ev.type != ButtonRelease);
  1155 	while(ev.type != ButtonRelease);
  1164 	if(usegrab)
       
  1165 		XUngrabServer(dpy);
       
  1166 	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
  1156 	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
  1167 	XUngrabPointer(dpy, CurrentTime);
  1157 	XUngrabPointer(dpy, CurrentTime);
  1168 	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
  1158 	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
  1169 }
  1159 }
  1170 
  1160