summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--calmwm.h7
-rw-r--r--client.c118
-rw-r--r--conf.c4
-rw-r--r--cwmrc.58
-rw-r--r--kbfunc.c13
5 files changed, 149 insertions, 1 deletions
diff --git a/calmwm.h b/calmwm.h
index 47f60e7..c02db59 100644
--- a/calmwm.h
+++ b/calmwm.h
@@ -76,6 +76,10 @@
 
 #define ARG_CHAR		0x0001
 #define ARG_INT			0x0002
+
+#define CWM_TILE_HORIZ 		0x0001
+#define CWM_TILE_VERT 		0x0002
+
 union arg {
 	char	*c;
 	int	 i;
@@ -321,6 +325,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 *);
@@ -338,6 +343,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 *);
@@ -408,6 +414,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 459d024..4895817 100644
--- a/client.c
+++ b/client.c
@@ -866,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 6ef9375..67f58a6 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/kbfunc.c b/kbfunc.c
index d61193f..c742f7e 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;
+	}
+}