Below is a diff that enables cwm to maximize a window
in a given direction (left / right / up / down) only.

Only left/right is implemented actually; I want to make sure
this isn't completely wrong before writing up the other half
(which will be dual of course).

The motivating situation for me is that my usual X setup
is a vertically maximized xterm in the upper left corner
(to write what I am writing) and whatever accompanies it
(xdvi, firefox, mupdf, ...) in the rest of the screen.
Setting that up is not complicated, but maximizing the
other window to the "rest of the screen" means:
align its left border to the right border of the xterm,
then hold CMS-l until the window enlarges fully to the right.

Obviously, the obligate h/j/k/l keys are taken already,
so I chose (CM-) the arrows for the default keybindings.

In the current implementation of e.g. hmaximize,
it is checked whether this actually means full maximization.
As there are currently only two parts of full maximization
(CLIENT_HMAXIMIZED, CLIENT_VMAXIMIZED) it is done by checking
the other one. With four parts of maximization now, I have
used a macro (LASTMAX) instead that checks whether this is
the last bit that's missing in full maximization. I believe
the current [vh]maximizing function should be so altered too.

Xinerama considerations: first of all, I only have one monitor,
so could please someone with more screens test this?

My logic of placing the maximized window is obvious:
when left-maximizing, the new left border is the left border of
the screen where the current left border is; that is, the leftmost
screen which is 'hit' by the current window is where the left-maximization
happens. I believe this is the sensible thing. Similarly for right.

This differs from the logic currently implemented in the maximizing
functions: the screen holding the center of the window is found,
and the window is maximized within that screen. I object to this,
with the following counterexample in mind: with 3 screens,
and a window spanning a little more than the central screen,
"maximizing" it actually means shrinking it!

This difference in placement logic is what stops me from
replacing hmaximize with a call to lmaximize and rmaximize.

Comments?

        Jan


Index: calmwm.h
===================================================================
RCS file: /cvs/xenocara/app/cwm/calmwm.h,v
retrieving revision 1.185
diff -u -p -r1.185 calmwm.h
--- calmwm.h    4 Jan 2013 16:30:03 -0000       1.185
+++ calmwm.h    5 Jan 2013 18:52:35 -0000
@@ -148,15 +148,22 @@ struct client_ctx {
        int                      xproto;
 #define CLIENT_HIDDEN                  0x0001
 #define CLIENT_IGNORE                  0x0002
-#define CLIENT_VMAXIMIZED              0x0004
-#define CLIENT_HMAXIMIZED              0x0008
 #define CLIENT_FREEZE                  0x0010
 #define CLIENT_GROUP                   0x0020
 #define CLIENT_UNGROUP                 0x0040
+#define CLIENT_LMAXIMIZED              0x0100
+#define CLIENT_RMAXIMIZED              0x0200
+#define CLIENT_UMAXIMIZED              0x0400
+#define CLIENT_DMAXIMIZED              0x0800
 
 #define CLIENT_HIGHLIGHT               (CLIENT_GROUP | CLIENT_UNGROUP)
-#define CLIENT_MAXFLAGS                        (CLIENT_VMAXIMIZED | 
CLIENT_HMAXIMIZED)
+#define CLIENT_HMAXIMIZED              (CLIENT_LMAXIMIZED | CLIENT_RMAXIMIZED)
+#define CLIENT_VMAXIMIZED              (CLIENT_UMAXIMIZED | CLIENT_DMAXIMIZED)
 #define CLIENT_MAXIMIZED               (CLIENT_VMAXIMIZED | CLIENT_HMAXIMIZED)
+#define CLIENT_MAXFLAGS                        (CLIENT_MAXIMIZED)
+#define LASTMAX(f, b)                  (((f | b) & CLIENT_MAXFLAGS) \
+                                               == CLIENT_MAXIMIZED)
+
        int                      flags;
        int                      state;
        int                      active;
@@ -315,6 +322,7 @@ void                         client_cycle(struct screen_ctx 
*
 void                    client_cycle_leave(struct screen_ctx *,
                             struct client_ctx *);
 void                    client_delete(struct client_ctx *);
+void                    client_dmaximize(struct client_ctx *);
 void                    client_draw_border(struct client_ctx *);
 struct client_ctx      *client_find(Window);
 void                    client_freeze(struct client_ctx *);
@@ -322,6 +330,7 @@ void                         client_getsizehints(struct 
clien
 void                    client_hide(struct client_ctx *);
 void                    client_hmaximize(struct client_ctx *);
 void                    client_leave(struct client_ctx *);
+void                    client_lmaximize(struct client_ctx *);
 void                    client_lower(struct client_ctx *);
 void                    client_map(struct client_ctx *);
 void                    client_maximize(struct client_ctx *);
@@ -331,11 +340,13 @@ void                       client_ptrsave(struct 
client_ctx
 void                    client_ptrwarp(struct client_ctx *);
 void                    client_raise(struct client_ctx *);
 void                    client_resize(struct client_ctx *, int);
+void                    client_rmaximize(struct client_ctx *);
 void                    client_send_delete(struct client_ctx *);
 void                    client_setactive(struct client_ctx *, int);
 void                    client_setname(struct client_ctx *);
 int                     client_snapcalc(int, int, int, int, int);
 void                    client_transient(struct client_ctx *);
+void                    client_umaximize(struct client_ctx *);
 void                    client_unhide(struct client_ctx *);
 void                    client_vmaximize(struct client_ctx *);
 void                    client_warp(struct client_ctx *);
@@ -377,6 +388,8 @@ void                         kbfunc_client_cycle(struct 
clien
 void                    kbfunc_client_cyclegroup(struct client_ctx *,
                             union arg *);
 void                    kbfunc_client_delete(struct client_ctx *, union arg *);
+void                    kbfunc_client_dmaximize(struct client_ctx *,
+                            union arg *);
 void                    kbfunc_client_freeze(struct client_ctx *, union arg *);
 void                    kbfunc_client_group(struct client_ctx *, union arg *);
 void                    kbfunc_client_grouponly(struct client_ctx *,
@@ -387,6 +400,8 @@ void                         kbfunc_client_hide(struct 
client
 void                    kbfunc_client_hmaximize(struct client_ctx *,
                             union arg *);
 void                    kbfunc_client_label(struct client_ctx *, union arg *);
+void                    kbfunc_client_lmaximize(struct client_ctx *,
+                            union arg *);
 void                    kbfunc_client_lower(struct client_ctx *, union arg *);
 void                    kbfunc_client_maximize(struct client_ctx *,
                             union arg *);
@@ -396,7 +411,11 @@ void                        kbfunc_client_nogroup(struct 
cli
                             union arg *);
 void                    kbfunc_client_raise(struct client_ctx *, union arg *);
 void                    kbfunc_client_rcycle(struct client_ctx *, union arg *);
+void                    kbfunc_client_rmaximize(struct client_ctx *,
+                            union arg *);
 void                    kbfunc_client_search(struct client_ctx *, union arg *);
+void                    kbfunc_client_umaximize(struct client_ctx *,
+                            union arg *);
 void                    kbfunc_client_vmaximize(struct client_ctx *,
                             union arg *);
 void                    kbfunc_cmdexec(struct client_ctx *, union arg *);
Index: client.c
===================================================================
RCS file: /cvs/xenocara/app/cwm/client.c,v
retrieving revision 1.115
diff -u -p -r1.115 client.c
--- client.c    4 Jan 2013 16:30:03 -0000       1.115
+++ client.c    5 Jan 2013 18:52:35 -0000
@@ -320,7 +320,7 @@ client_vmaximize(struct client_ctx *cc)
        cc->savegeom.h = cc->geom.h;
 
        /* if this will make us fully maximized then remove boundary */
-       if ((cc->flags & CLIENT_MAXFLAGS) == CLIENT_HMAXIMIZED) {
+       if (LASTMAX(cc->flags, CLIENT_VMAXIMIZED)) {
                cc->geom.w += Conf.bwidth * 2;
                cc->bwidth = 0;
        }
@@ -361,7 +361,7 @@ client_hmaximize(struct client_ctx *cc)
        cc->savegeom.w = cc->geom.w;
 
        /* if this will make us fully maximized then remove boundary */
-       if ((cc->flags & CLIENT_MAXFLAGS) == CLIENT_VMAXIMIZED) {
+       if (LASTMAX(cc->flags, CLIENT_HMAXIMIZED)) {
                cc->geom.h += cc->bwidth * 2;
                cc->bwidth = 0;
        }
@@ -377,6 +377,95 @@ client_hmaximize(struct client_ctx *cc)
 
 resize:
        client_resize(cc, 0);
+}
+
+void
+client_lmaximize(struct client_ctx *cc)
+{
+       struct screen_ctx       *sc = cc->sc;
+       struct geom              xine;
+
+       if (cc->flags & CLIENT_FREEZE)
+               return;
+
+       if (cc->flags & CLIENT_LMAXIMIZED) {
+               cc->geom.x = cc->savegeom.x;
+               cc->geom.w = cc->savegeom.w;
+               cc->bwidth = Conf.bwidth;
+               /* when exiting full maximization, restore boundary */
+               if ((cc->flags & CLIENT_MAXFLAGS) == CLIENT_MAXIMIZED)
+                       cc->geom.h -= cc->bwidth * 2;
+               cc->flags &= ~CLIENT_LMAXIMIZED;
+               goto resize;
+       }
+
+       cc->savegeom.x = cc->geom.x;
+       if ((cc->flags & CLIENT_RMAXIMIZED) == 0)
+               cc->savegeom.w = cc->geom.w;
+
+       /* if this will make us fully maximized then remove boundary */
+       if (LASTMAX(cc->flags, CLIENT_LMAXIMIZED)) {
+               cc->geom.h += cc->bwidth * 2;
+               cc->bwidth = 0;
+       }
+
+       /* left-maximize in the screen(s) where the left boundary is now */
+       xine = screen_find_xinerama(sc, cc->geom.x, cc->geom.y);
+
+       cc->geom.w += (cc->geom.x - xine.x) - sc->gap.left;
+       cc->geom.x = xine.x + sc->gap.left;
+       cc->flags |= CLIENT_LMAXIMIZED;
+
+resize:
+       client_resize(cc, 0);
+}
+
+void
+client_rmaximize(struct client_ctx *cc)
+{
+       struct screen_ctx       *sc = cc->sc;
+       struct geom              xine;
+
+       if (cc->flags & CLIENT_FREEZE)
+               return;
+
+       if (cc->flags & CLIENT_RMAXIMIZED) {
+               cc->geom.w = cc->savegeom.w;
+               cc->bwidth = Conf.bwidth;
+               /* when exiting full maximization, restore boundary */
+               if ((cc->flags & CLIENT_MAXFLAGS) == CLIENT_MAXIMIZED)
+                       cc->geom.h -= cc->bwidth * 2;
+               cc->flags &= ~CLIENT_RMAXIMIZED;
+               goto resize;
+       }
+
+       if ((cc->flags & CLIENT_LMAXIMIZED) == 0)
+               cc->savegeom.w = cc->geom.w;
+
+       /* if this will make us fully maximized then remove boundary */
+       if (LASTMAX(cc->flags, CLIENT_RMAXIMIZED)) {
+               cc->geom.h += cc->bwidth * 2;
+               cc->bwidth = 0;
+       }
+
+       /* right-maximize in the screen(s) where the right boundary is now */
+       xine = screen_find_xinerama(sc, cc->geom.x + cc->geom.w, cc->geom.y);
+       cc->geom.w += (xine.x + xine.w) - (cc->geom.x + cc->geom.w)
+                       - (cc->bwidth * 2)  - sc->gap.right;
+       cc->flags |= CLIENT_RMAXIMIZED;
+
+resize:
+       client_resize(cc, 0);
+}
+
+void
+client_umaximize(struct client_ctx *cc)
+{
+}
+
+void
+client_dmaximize(struct client_ctx *cc)
+{
 }
 
 void
Index: conf.c
===================================================================
RCS file: /cvs/xenocara/app/cwm/conf.c,v
retrieving revision 1.120
diff -u -p -r1.120 conf.c
--- conf.c      4 Jan 2013 16:27:58 -0000       1.120
+++ conf.c      5 Jan 2013 18:52:36 -0000
@@ -121,6 +121,10 @@ static struct {
        { "CM-f",       "maximize" },
        { "CM-equal",   "vmaximize" },
        { "CMS-equal",  "hmaximize" },
+       { "CM-Left",    "lmaximize" },
+       { "CM-Right",   "rmaximize" },
+       { "CM-Up",      "umaximize" },
+       { "CM-Down",    "dmaximize" },
        { "CMS-f",      "freeze" },
        { "CMS-r",      "restart" },
        { "CMS-q",      "quit" },
@@ -322,6 +326,10 @@ static struct {
        { "maximize", kbfunc_client_maximize, KBFLAG_NEEDCLIENT, {0} },
        { "vmaximize", kbfunc_client_vmaximize, KBFLAG_NEEDCLIENT, {0} },
        { "hmaximize", kbfunc_client_hmaximize, KBFLAG_NEEDCLIENT, {0} },
+       { "lmaximize", kbfunc_client_lmaximize, KBFLAG_NEEDCLIENT, {0} },
+       { "rmaximize", kbfunc_client_rmaximize, KBFLAG_NEEDCLIENT, {0} },
+       { "umaximize", kbfunc_client_umaximize, KBFLAG_NEEDCLIENT, {0} },
+       { "dmaximize", kbfunc_client_dmaximize, KBFLAG_NEEDCLIENT, {0} },
        { "freeze", kbfunc_client_freeze, KBFLAG_NEEDCLIENT, {0} },
        { "restart", kbfunc_restart, 0, {0} },
        { "quit", kbfunc_quit_wm, 0, {0} },
Index: cwmrc.5
===================================================================
RCS file: /cvs/xenocara/app/cwm/cwmrc.5,v
retrieving revision 1.51
diff -u -p -r1.51 cwmrc.5
--- cwmrc.5     17 Dec 2012 02:53:29 -0000      1.51
+++ cwmrc.5     5 Jan 2013 18:52:37 -0000
@@ -169,7 +169,7 @@ This
 .Dq gap
 can be used for applications such as
 .Xr xclock 1 ,
-where the user may wish to remain visible.
+which the user might wish to remain visible.
 .Pp
 .It Ic ignore Ar windowname
 Ignore, and do not warp to, windows with the name
@@ -342,6 +342,14 @@ Maximize current window full-screen.
 Maximize current window vertically.
 .It hmaximize
 Maximize current window horizontally.
+.It lmaximize
+Maximize current window to the left.
+.It rmaximize
+Maximize current window to the right.
+.It umaximize
+Maximize current window up.
+.It dmaximize
+Maximize current window down.
 .It moveup
 Move window
 .Ar moveamount
Index: kbfunc.c
===================================================================
RCS file: /cvs/xenocara/app/cwm/kbfunc.c,v
retrieving revision 1.75
diff -u -p -r1.75 kbfunc.c
--- kbfunc.c    4 Jan 2013 16:30:03 -0000       1.75
+++ kbfunc.c    5 Jan 2013 18:52:37 -0000
@@ -462,6 +462,30 @@ kbfunc_client_hmaximize(struct client_ct
 }
 
 void
+kbfunc_client_lmaximize(struct client_ctx *cc, union arg *arg)
+{
+       client_lmaximize(cc);
+}
+
+void
+kbfunc_client_rmaximize(struct client_ctx *cc, union arg *arg)
+{
+       client_rmaximize(cc);
+}
+
+void
+kbfunc_client_umaximize(struct client_ctx *cc, union arg *arg)
+{
+       client_umaximize(cc);
+}
+
+void
+kbfunc_client_dmaximize(struct client_ctx *cc, union arg *arg)
+{
+       client_dmaximize(cc);
+}
+
+void
 kbfunc_client_freeze(struct client_ctx *cc, union arg *arg)
 {
        client_freeze(cc);

Reply via email to