about summary refs log tree commit diff
diff options
context:
space:
mode:
authorokan <okan>2013-01-13 13:55:12 +0000
committerokan <okan>2013-01-13 13:55:12 +0000
commit9c6226faa81835067769d042f52520d01af0b70f (patch)
tree974f2ad28fa8d45fafae450ae839c92bbc0295d4
parent104c7d5de3a92da8b0c3514ef0692ff1e5d0ef82 (diff)
parent47aa485fa259965609d3e13cce7a03ac64b14e6f (diff)
downloadcwm-9c6226faa81835067769d042f52520d01af0b70f.tar.gz
cwm-9c6226faa81835067769d042f52520d01af0b70f.tar.xz
cwm-9c6226faa81835067769d042f52520d01af0b70f.zip
cvsimport
-rw-r--r--calmwm.h7
-rw-r--r--client.c153
-rw-r--r--conf.c4
-rw-r--r--cwmrc.58
-rw-r--r--group.c8
-rw-r--r--kbfunc.c13
-rw-r--r--menu.c2
-rw-r--r--screen.c10
8 files changed, 175 insertions, 30 deletions
diff --git a/calmwm.h b/calmwm.h
index bbc96b2..f85d37a 100644
--- a/calmwm.h
+++ b/calmwm.h
@@ -88,6 +88,10 @@ size_t strlcat(char *, const char *, size_t);
 
 #define ARG_CHAR		0x0001
 #define ARG_INT			0x0002
+
+#define CWM_TILE_HORIZ 		0x0001
+#define CWM_TILE_VERT 		0x0002
+
 union arg {
 	char	*c;
 	int	 i;
@@ -333,6 +337,7 @@ void			 client_freeze(struct client_ctx *);
 void			 client_getsizehints(struct client_ctx *);
 void			 client_hide(struct client_ctx *);
 void			 client_hmaximize(struct client_ctx *);
+void 			 client_htile(struct client_ctx *);
 void			 client_leave(struct client_ctx *);
 void			 client_lower(struct client_ctx *);
 void			 client_map(struct client_ctx *);
@@ -350,6 +355,7 @@ int			 client_snapcalc(int, int, int, int, int);
 void			 client_transient(struct client_ctx *);
 void			 client_unhide(struct client_ctx *);
 void			 client_vmaximize(struct client_ctx *);
+void 			 client_vtile(struct client_ctx *);
 void			 client_warp(struct client_ctx *);
 
 void			 group_alltoggle(struct screen_ctx *);
@@ -420,6 +426,7 @@ void			 kbfunc_quit_wm(struct client_ctx *, union arg *);
 void			 kbfunc_restart(struct client_ctx *, union arg *);
 void			 kbfunc_ssh(struct client_ctx *, union arg *);
 void			 kbfunc_term(struct client_ctx *, union arg *);
+void 			 kbfunc_tile(struct client_ctx *, union arg *);
 
 void			 mousefunc_menu_cmd(struct client_ctx *, void *);
 void			 mousefunc_menu_group(struct client_ctx *, void *);
diff --git a/client.c b/client.c
index a72ecfb..59b9fe9 100644
--- a/client.c
+++ b/client.c
@@ -286,10 +286,7 @@ client_maximize(struct client_ctx *cc)
 	    cc->geom.x + cc->geom.w / 2,
 	    cc->geom.y + cc->geom.h / 2);
 
-	cc->geom.x = xine.x + sc->gap.left;
-	cc->geom.y = xine.y + sc->gap.top;
-	cc->geom.h = xine.h - (sc->gap.top + sc->gap.bottom);
-	cc->geom.w = xine.w - (sc->gap.left + sc->gap.right);
+	cc->geom = xine;
 	cc->bwidth = 0;
 	cc->flags |= CLIENT_MAXIMIZED;
 
@@ -329,9 +326,8 @@ client_vmaximize(struct client_ctx *cc)
 	    cc->geom.x + cc->geom.w / 2,
 	    cc->geom.y + cc->geom.h / 2);
 
-	cc->geom.y = xine.y + sc->gap.top;
-	cc->geom.h = xine.h - (cc->bwidth * 2) - (sc->gap.top +
-	    sc->gap.bottom);
+	cc->geom.y = xine.y;
+	cc->geom.h = xine.h - (cc->bwidth * 2);
 	cc->flags |= CLIENT_VMAXIMIZED;
 
 resize:
@@ -370,9 +366,8 @@ client_hmaximize(struct client_ctx *cc)
 	    cc->geom.x + cc->geom.w / 2,
 	    cc->geom.y + cc->geom.h / 2);
 
-	cc->geom.x = xine.x + sc->gap.left;
-	cc->geom.w = xine.w - (cc->bwidth * 2) - (sc->gap.left +
-	    sc->gap.right);
+	cc->geom.x = xine.x;
+	cc->geom.w = xine.w - (cc->bwidth * 2);
 	cc->flags |= CLIENT_HMAXIMIZED;
 
 resize:
@@ -660,6 +655,8 @@ client_placecalc(struct client_ctx *cc)
 
 		xu_ptr_getpos(sc->rootwin, &xmouse, &ymouse);
 		xine = screen_find_xinerama(sc, xmouse, ymouse);
+		xine.w += xine.x;
+		xine.h += xine.y;
 		xmouse = MAX(xmouse, xine.x) - cc->geom.w / 2;
 		ymouse = MAX(ymouse, xine.y) - cc->geom.h / 2;
 
@@ -670,22 +667,16 @@ client_placecalc(struct client_ctx *cc)
 		yslack = xine.h - cc->geom.h - cc->bwidth * 2;
 
 		if (xslack >= xine.x) {
-			cc->geom.x = MAX(MIN(xmouse, xslack),
-			    xine.x + sc->gap.left);
-			if (cc->geom.x > (xslack - sc->gap.right))
-				cc->geom.x -= sc->gap.right;
+			cc->geom.x = MAX(MIN(xmouse, xslack), xine.x);
 		} else {
-			cc->geom.x = xine.x + sc->gap.left;
-			cc->geom.w = xine.w - sc->gap.left;
+			cc->geom.x = xine.x;
+			cc->geom.w = xine.w;
 		}
 		if (yslack >= xine.y) {
-			cc->geom.y = MAX(MIN(ymouse, yslack),
-			    xine.y + sc->gap.top);
-			if (cc->geom.y > (yslack - sc->gap.bottom))
-				cc->geom.y -= sc->gap.bottom;
+			cc->geom.y = MAX(MIN(ymouse, yslack), xine.y);
 		} else {
-			cc->geom.y = xine.y + sc->gap.top;
-			cc->geom.h = xine.h - sc->gap.top;
+			cc->geom.y = xine.y;
+			cc->geom.h = xine.h;
 		}
 	}
 }
@@ -875,3 +866,121 @@ client_snapcalc(int n0, int n1, int e0, int e1, int snapdist)
 	else
 		return (0);
 }
+
+void
+client_htile(struct client_ctx *cc)
+{
+	struct client_ctx	*ci;
+	struct group_ctx 	*gc = cc->group;
+	struct screen_ctx 	*sc = cc->sc;
+	struct geom 		 xine;
+	int 			 i, n, mh, x, h, w;
+
+	if (!gc)
+		return;
+	i = n = 0;
+
+	TAILQ_FOREACH(ci, &gc->clients, group_entry) {
+		if (ci->flags & CLIENT_HIDDEN ||
+		    ci->flags & CLIENT_IGNORE || (ci == cc))
+			continue;
+		n++;
+	}
+	if (n == 0)
+		return;
+
+	xine = screen_find_xinerama(sc,
+	    cc->geom.x + cc->geom.w / 2,
+	    cc->geom.y + cc->geom.h / 2);
+
+	if (cc->flags & CLIENT_VMAXIMIZED ||
+	    cc->geom.h + (cc->bwidth * 2) >= xine.h)
+		return;
+
+	cc->flags &= ~CLIENT_HMAXIMIZED;
+	cc->geom.x = xine.x;
+	cc->geom.y = xine.y;
+	cc->geom.w = xine.w - (cc->bwidth * 2);
+	client_resize(cc, 1);
+	client_ptrwarp(cc);
+
+	mh = cc->geom.h + (cc->bwidth * 2);
+	x = xine.x;
+	w = xine.w / n;
+	h = xine.h - mh;
+	TAILQ_FOREACH(ci, &gc->clients, group_entry) {
+		if (ci->flags & CLIENT_HIDDEN ||
+		    ci->flags & CLIENT_IGNORE || (ci == cc))
+			continue;
+		ci->bwidth = Conf.bwidth;
+		ci->geom.y = xine.y + mh;
+		ci->geom.x = x;
+		ci->geom.h = h - (ci->bwidth * 2);
+		ci->geom.w = w - (ci->bwidth * 2);
+		if (i + 1 == n)
+			ci->geom.w = xine.x + xine.w -
+			    ci->geom.x - (ci->bwidth * 2);
+		x += w;
+		client_resize(ci, 1);
+		i++;
+	}
+}
+
+void
+client_vtile(struct client_ctx *cc)
+{
+	struct client_ctx	*ci;
+	struct group_ctx 	*gc = cc->group;
+	struct screen_ctx 	*sc = cc->sc;
+	struct geom 		 xine;
+	int 			 i, n, mw, y, h, w;
+
+	if (!gc)
+		return;
+	i = n = 0;
+
+	TAILQ_FOREACH(ci, &gc->clients, group_entry) {
+		if (ci->flags & CLIENT_HIDDEN ||
+		    ci->flags & CLIENT_IGNORE || (ci == cc))
+			continue;
+		n++;
+	}
+	if (n == 0)
+		return;
+
+	xine = screen_find_xinerama(sc,
+	    cc->geom.x + cc->geom.w / 2,
+	    cc->geom.y + cc->geom.h / 2);
+
+	if (cc->flags & CLIENT_HMAXIMIZED ||
+	    cc->geom.w + (cc->bwidth * 2) >= xine.w)
+		return;
+
+	cc->flags &= ~CLIENT_VMAXIMIZED;
+	cc->geom.x = xine.x;
+	cc->geom.y = xine.y;
+	cc->geom.h = xine.h - (cc->bwidth * 2);
+	client_resize(cc, 1);
+	client_ptrwarp(cc);
+
+	mw = cc->geom.w + (cc->bwidth * 2);
+	y = xine.y;
+	h = xine.h / n;
+	w = xine.w - mw;
+	TAILQ_FOREACH(ci, &gc->clients, group_entry) {
+		if (ci->flags & CLIENT_HIDDEN ||
+		    ci->flags & CLIENT_IGNORE || (ci == cc))
+			continue;
+		ci->bwidth = Conf.bwidth;
+		ci->geom.y = y;
+		ci->geom.x = xine.x + mw;
+		ci->geom.h = h - (ci->bwidth * 2);
+		ci->geom.w = w - (ci->bwidth * 2);
+		if (i + 1 == n)
+			ci->geom.h = xine.y + xine.h -
+			    ci->geom.y - (ci->bwidth * 2);
+		y += h;
+		client_resize(ci, 1);
+		i++;
+	}
+}
diff --git a/conf.c b/conf.c
index 17c10b9..342fd6a 100644
--- a/conf.c
+++ b/conf.c
@@ -375,6 +375,10 @@ static struct {
 	    {.i = (CWM_LEFT|CWM_PTRMOVE|CWM_BIGMOVE)} },
 	{ "bigptrmoveright", kbfunc_moveresize, 0,
 	    {.i = (CWM_RIGHT|CWM_PTRMOVE|CWM_BIGMOVE)} },
+	{ "htile", kbfunc_tile, KBFLAG_NEEDCLIENT,
+	    {.i = CWM_TILE_HORIZ } },
+	{ "vtile", kbfunc_tile, KBFLAG_NEEDCLIENT,
+	    {.i = CWM_TILE_VERT } },
 };
 
 /*
diff --git a/cwmrc.5 b/cwmrc.5
index c8ea841..b475d5e 100644
--- a/cwmrc.5
+++ b/cwmrc.5
@@ -14,7 +14,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: November 29 2012 $
+.Dd $Mdocdate: December 17 2012 $
 .Dt CWMRC 5
 .Os
 .Sh NAME
@@ -438,6 +438,12 @@ pixels right.
 Move pointer 10 times
 .Ar moveamount
 pixels left.
+.It htile
+Current window is placed at the top of the screen and maximized
+horizontally, other windows in its group share remaining screen space.
+.It vtile
+Current window is placed on the left of the screen and maximized
+vertically, other windows in its group share remaining screen space.
 .El
 .Sh MOUSEBIND COMMAND LIST
 .Bl -tag -width 18n -compact
diff --git a/group.c b/group.c
index 8b8823c..e471d63 100644
--- a/group.c
+++ b/group.c
@@ -160,7 +160,7 @@ group_init(struct screen_ctx *sc)
 	xu_ewmh_net_showing_desktop(sc);
 	xu_ewmh_net_virtual_roots(sc);
 
-	group_setactive(sc, 0);
+	group_setactive(sc, 1);
 }
 
 void
@@ -269,8 +269,12 @@ group_hidetoggle(struct screen_ctx *sc, int idx)
 
 	if (gc->hidden)
 		group_show(sc, gc);
-	else
+	else {
 		group_hide(sc, gc);
+		/* make clients stick to empty group */
+		if (TAILQ_EMPTY(&gc->clients))
+			group_setactive(sc, idx);
+	}
 }
 
 void
diff --git a/kbfunc.c b/kbfunc.c
index eda9a39..473d1de 100644
--- a/kbfunc.c
+++ b/kbfunc.c
@@ -479,3 +479,16 @@ kbfunc_restart(struct client_ctx *cc, union arg *arg)
 	(void)setsid();
 	(void)execvp(cwm_argv[0], cwm_argv);
 }
+
+void
+kbfunc_tile(struct client_ctx *cc, union arg *arg)
+{
+	switch (arg->i) {
+		case CWM_TILE_HORIZ:
+			client_htile(cc);
+			break;
+		case CWM_TILE_VERT:
+			client_vtile(cc);
+			break;
+	}
+}
diff --git a/menu.c b/menu.c
index 9f152fb..5a1c601 100644
--- a/menu.c
+++ b/menu.c
@@ -394,6 +394,8 @@ menu_draw(struct screen_ctx *sc, struct menu_ctx *mc, struct menu_q *menuq,
 	}
 
 	xine = screen_find_xinerama(sc, mc->x, mc->y);
+	xine.w += xine.x;
+	xine.h += xine.y;
 
 	xsave = mc->x;
 	ysave = mc->y;
diff --git a/screen.c b/screen.c
index 5f7af56..f63032e 100644
--- a/screen.c
+++ b/screen.c
@@ -132,7 +132,7 @@ screen_find_xinerama(struct screen_ctx *sc, int x, int y)
 	struct geom		 geom;
 	int			 i;
 
-	geom = sc->view;
+	geom = sc->work;
 
 	if (sc->xinerama == NULL)
 		return (geom);
@@ -141,10 +141,10 @@ screen_find_xinerama(struct screen_ctx *sc, int x, int y)
 		info = &sc->xinerama[i];
 		if (x >= info->x_org && x < info->x_org + info->width &&
 		    y >= info->y_org && y < info->y_org + info->height) {
-			geom.x = info->x_org;
-			geom.y = info->y_org;
-			geom.w = info->width;
-			geom.h = info->height;
+			geom.x = info->x_org + sc->gap.left;
+			geom.y = info->y_org + sc->gap.top;
+			geom.w = info->width - (sc->gap.left + sc->gap.right);
+			geom.h = info->height - (sc->gap.top + sc->gap.bottom);
 			break;
 		}
 	}