From 3a7596968b740328c41f6807800d004c75e3c62f Mon Sep 17 00:00:00 2001 From: okan Date: Tue, 8 Jan 2013 15:16:04 +0000 Subject: add per-group vert/horiz tiling support; introduces 2 new bind commands, 'vtile' and 'htile'; from Alexander Polakov. --- calmwm.h | 7 ++++ client.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ conf.c | 4 +++ cwmrc.5 | 8 ++++- kbfunc.c | 13 +++++++ 5 files changed, 149 insertions(+), 1 deletion(-) 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; + } +} -- cgit 1.4.1