summary refs log tree commit diff
diff options
context:
space:
mode:
authorokan <okan>2009-08-24 23:49:04 +0000
committerokan <okan>2009-08-24 23:49:04 +0000
commit028a1778db0caa04ca4f82be32998a7f65c802a5 (patch)
tree9284024c4d2a1962e8959b43a9ad5d7b1d5cf997
parent09d88f4a18623fff580e7381aa242dae5b53cc18 (diff)
downloadcwm-028a1778db0caa04ca4f82be32998a7f65c802a5.tar.gz
cwm-028a1778db0caa04ca4f82be32998a7f65c802a5.tar.xz
cwm-028a1778db0caa04ca4f82be32998a7f65c802a5.zip
bring together gathering, calculating and applying of size hints;
additionally, respect aspect ratio hints.

ok oga@
-rw-r--r--calmwm.h7
-rw-r--r--client.c100
-rw-r--r--mousefunc.c24
-rw-r--r--xevents.c3
4 files changed, 100 insertions, 34 deletions
diff --git a/calmwm.h b/calmwm.h
index a60dee1..aa46793 100644
--- a/calmwm.h
+++ b/calmwm.h
@@ -121,8 +121,9 @@ struct client_ctx {
 
 	u_int			 bwidth;
 	struct {
-		int		 x, y, width, height;
-		int		 min_dx, min_dy;
+		int		 x, y, width, height, basew, baseh,
+				 minw, minh, maxw, maxh, incw, inch;
+		float		 mina, maxa;
 	} geom, savegeom;
 
 	struct {
@@ -349,6 +350,8 @@ void			 client_vertmaximize(struct client_ctx *);
 void			 client_map(struct client_ctx *);
 void			 client_mtf(struct client_ctx *);
 struct client_ctx	*client_cycle(int);
+void			 client_getsizehints(struct client_ctx *);
+void			 client_applysizehints(struct client_ctx *);
 
 struct menu  		*menu_filter(struct menu_q *, char *, char *, int,
 			     void (*)(struct menu_q *, struct menu_q *, char *),
diff --git a/client.c b/client.c
index b6e6ad2..31a0d7a 100644
--- a/client.c
+++ b/client.c
@@ -50,7 +50,6 @@ client_new(Window win, struct screen_ctx *sc, int mapped)
 	struct client_ctx	*cc;
 	XWindowAttributes	 wattr;
 	XWMHints		*wmhints;
-	long			 tmp;
 	int			 state;
 
 	if (win == None)
@@ -65,14 +64,7 @@ client_new(Window win, struct screen_ctx *sc, int mapped)
 	cc->win = win;
 	cc->size = XAllocSizeHints();
 
-	XGetWMNormalHints(X_Dpy, cc->win, cc->size, &tmp);
-	if (cc->size->flags & PBaseSize) {
-		cc->geom.min_dx = cc->size->base_width;
-		cc->geom.min_dy = cc->size->base_height;
-	} else if (cc->size->flags & PMinSize) {
-		cc->geom.min_dx = cc->size->min_width;
-		cc->geom.min_dy = cc->size->min_height;
-	}
+	client_getsizehints(cc);
 
 	TAILQ_INIT(&cc->nameq);
 	client_setname(cc);
@@ -628,6 +620,96 @@ client_mtf(struct client_ctx *cc)
 	TAILQ_INSERT_HEAD(&sc->mruq, cc, mru_entry);
 }
 
+void
+client_getsizehints(struct client_ctx *cc)
+{
+	long		 tmp;
+
+	if (!XGetWMNormalHints(X_Dpy, cc->win, cc->size, &tmp))
+		cc->size->flags = PSize;
+
+	if (cc->size->flags & PBaseSize) {
+		cc->geom.basew = cc->size->base_width;
+		cc->geom.baseh = cc->size->base_height;
+	} else if (cc->size->flags & PMinSize) {
+		cc->geom.basew = cc->size->min_width;
+		cc->geom.baseh = cc->size->min_height;
+	}
+	if (cc->size->flags & PMinSize) {
+		cc->geom.minw = cc->size->min_width;
+		cc->geom.minh = cc->size->min_height;
+	} else if (cc->size->flags & PBaseSize) {
+		cc->geom.minw = cc->size->base_width;
+		cc->geom.minh = cc->size->base_height;
+	}
+	if (cc->size->flags & PMaxSize) {
+		cc->geom.maxw = cc->size->max_width;
+		cc->geom.maxh = cc->size->max_height;
+	}
+	if (cc->size->flags & PResizeInc) {
+		cc->geom.incw = cc->size->width_inc;
+		cc->geom.inch = cc->size->height_inc;
+	}
+	if (cc->size->flags & PAspect) {
+		if (cc->size->min_aspect.x > 0) 
+			cc->geom.mina = (float)cc->size->min_aspect.y /
+			    cc->size->min_aspect.x;
+		if (cc->size->max_aspect.y > 0) 
+			cc->geom.maxa = (float)cc->size->max_aspect.x /
+			    cc->size->max_aspect.y;
+	}
+}
+void
+client_applysizehints(struct client_ctx *cc)
+{
+	Bool		 baseismin;
+
+	baseismin = (cc->geom.basew == cc->geom.minw) &&
+	    (cc->geom.baseh == cc->geom.minh);
+
+	/* temporarily remove base dimensions, ICCCM 4.1.2.3 */
+	if (!baseismin) {
+		cc->geom.width -= cc->geom.basew;
+		cc->geom.height -= cc->geom.baseh;
+	}
+
+	/* adjust for aspect limits */
+	if (cc->geom.mina > 0 && cc->geom.maxa > 0) {
+		if (cc->geom.maxa <
+		    (float)cc->geom.width / cc->geom.height)
+			cc->geom.width = cc->geom.height * cc->geom.maxa;
+		else if (cc->geom.mina <
+		    (float)cc->geom.height / cc->geom.width)
+			cc->geom.height = cc->geom.width * cc->geom.mina;
+	}
+
+	/* remove base dimensions for increment */
+	if (baseismin) {
+		cc->geom.width -= cc->geom.basew;
+		cc->geom.height -= cc->geom.baseh;
+	}
+
+	/* adjust for increment value */
+	if (cc->geom.incw)
+		cc->geom.width -= cc->geom.width % cc->geom.incw;
+	if (cc->geom.inch)
+		cc->geom.height -= cc->geom.height % cc->geom.inch;
+
+	/* restore base dimensions */
+	cc->geom.width += cc->geom.basew;
+	cc->geom.height += cc->geom.baseh;
+
+	/* adjust for min width/height */
+	cc->geom.width = MAX(cc->geom.width, cc->geom.minw);
+	cc->geom.height = MAX(cc->geom.height, cc->geom.minh);
+
+	/* adjust for max width/height */
+	if (cc->geom.maxw)
+		cc->geom.width = MIN(cc->geom.width, cc->geom.maxw);
+	if (cc->geom.maxh)
+		cc->geom.height = MIN(cc->geom.height, cc->geom.maxh);
+}
+
 static void
 client_gethints(struct client_ctx *cc)
 {
diff --git a/mousefunc.c b/mousefunc.c
index fc6c8b9..74bbf04 100644
--- a/mousefunc.c
+++ b/mousefunc.c
@@ -33,22 +33,7 @@ mousefunc_sweep_calc(struct client_ctx *cc, int x, int y, int mx, int my)
 	cc->geom.width = abs(x - mx) - cc->bwidth;
 	cc->geom.height = abs(y - my) - cc->bwidth;
 
-	if (cc->size->flags & PResizeInc) {
-		cc->geom.width -=
-		    (cc->geom.width - cc->geom.min_dx) % cc->size->width_inc;
-		cc->geom.height -=
-		    (cc->geom.height - cc->geom.min_dy) % cc->size->height_inc;
-	}
-
-	if (cc->size->flags & PMinSize) {
-		cc->geom.width = MAX(cc->geom.width, cc->size->min_width);
-		cc->geom.height = MAX(cc->geom.height, cc->size->min_height);
-	}
-
-	if (cc->size->flags & PMaxSize) {
-		cc->geom.width = MIN(cc->geom.width, cc->size->max_width);
-		cc->geom.height = MIN(cc->geom.height, cc->size->max_height);
-	}
+	client_applysizehints(cc);
 
 	cc->geom.x = x <= mx ? x : x - cc->geom.width;
 	cc->geom.y = y <= my ? y : y - cc->geom.height;
@@ -64,8 +49,8 @@ mousefunc_sweep_draw(struct client_ctx *cc)
 	int			 width, height, width_size, width_name;
 
 	snprintf(asize, sizeof(asize), "%dx%d",
-	    (cc->geom.width - cc->geom.min_dx) / cc->size->width_inc,
-	    (cc->geom.height - cc->geom.min_dy) / cc->size->height_inc);
+	    (cc->geom.width - cc->geom.basew) / MAX(1, cc->geom.incw),
+	    (cc->geom.height - cc->geom.baseh) / MAX(1, cc->geom.inch));
 	width_size = font_width(asize, strlen(asize)) + 4;
 	width_name = font_width(cc->name, strlen(cc->name)) + 4;
 	width = MAX(width_size, width_name);
@@ -90,9 +75,6 @@ mousefunc_window_resize(struct client_ctx *cc, void *arg)
 	struct screen_ctx	*sc = CCTOSC(cc);
 	int			 x = cc->geom.x, y = cc->geom.y;
 
-	cc->size->width_inc = MAX(1, cc->size->width_inc);
-	cc->size->height_inc = MAX(1, cc->size->height_inc);
-
 	client_raise(cc);
 	client_ptrsave(cc);
 
diff --git a/xevents.c b/xevents.c
index 74214f3..a9f7bd2 100644
--- a/xevents.c
+++ b/xevents.c
@@ -171,12 +171,11 @@ xev_handle_propertynotify(XEvent *ee)
 {
 	XPropertyEvent		*e = &ee->xproperty;
 	struct client_ctx	*cc;
-	long			 tmp;
 
 	if ((cc = client_find(e->window)) != NULL) {
 		switch (e->atom) {
 		case XA_WM_NORMAL_HINTS:
-			XGetWMNormalHints(X_Dpy, cc->win, cc->size, &tmp);
+			client_getsizehints(cc);
 			break;
 		case XA_WM_NAME:
 			client_setname(cc);