[wiki] [sites] Added exresize patch for dwm || Krister Svanlund

From: <hg_AT_suckless.org>
Date: Sat, 17 Nov 2012 18:21:02 +0100 (CET)

changeset: 1009:83d9be6a8c73
tag: tip
user: Krister Svanlund <krister.svanlund_AT_gmail.com>
date: Sat Nov 17 18:20:43 2012 +0100
files: dwm.suckless.org/patches/dwm-r1606-exresize.diff dwm.suckless.org/patches/exresize.md
description:
Added exresize patch for dwm


diff -r 887a394b79f4 -r 83d9be6a8c73 dwm.suckless.org/patches/dwm-r1606-exresize.diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dwm.suckless.org/patches/dwm-r1606-exresize.diff Sat Nov 17 18:20:43 2012 +0100
_AT_@ -0,0 +1,372 @@
+diff --git a/config.def.h b/config.def.h
+index 7fb4d82..959a119 100644
+--- a/config.def.h
++++ b/config.def.h
+_AT_@ -88,6 +88,33 @@ static Key keys[] = {
+ TAGKEYS( XK_8, 7)
+ TAGKEYS( XK_9, 8)
+ { MODKEY|ShiftMask, XK_q, quit, {0} },
++
++ { MODKEY, XK_KP_7, explace, {.ui = EX_NW }},
++ { MODKEY, XK_KP_8, explace, {.ui = EX_N }},
++ { MODKEY, XK_KP_9, explace, {.ui = EX_NE }},
++ { MODKEY, XK_KP_4, explace, {.ui = EX_W }},
++ { MODKEY, XK_KP_5, explace, {.ui = EX_C }},
++ { MODKEY, XK_KP_6, explace, {.ui = EX_E }},
++ { MODKEY, XK_KP_1, explace, {.ui = EX_SW }},
++ { MODKEY, XK_KP_2, explace, {.ui = EX_S }},
++ { MODKEY, XK_KP_3, explace, {.ui = EX_SE }},
++
++ { MODKEY|ShiftMask, XK_KP_8, exresize, {.v = (int []){ 0, 25 }}},
++ { MODKEY|ShiftMask, XK_KP_2, exresize, {.v = (int []){ 0, -25 }}},
++ { MODKEY|ShiftMask, XK_KP_6, exresize, {.v = (int []){ 25, 0 }}},
++ { MODKEY|ShiftMask, XK_KP_4, exresize, {.v = (int []){ -25, 0 }}},
++ { MODKEY|ShiftMask, XK_KP_5, exresize, {.v = (int []){ 25, 25 }}},
++ { MODKEY|ShiftMask|ControlMask, XK_KP_5, exresize, {.v = (int []){ -25, -25 }}},
++
++ { MODKEY|ControlMask, XK_KP_6, togglehorizontalexpand, {.i = +1} },
++ { MODKEY|ControlMask, XK_KP_3, togglehorizontalexpand, {.i = 0} },
++ { MODKEY|ControlMask, XK_KP_4, togglehorizontalexpand, {.i = -1} },
++ { MODKEY|ControlMask, XK_KP_8, toggleverticalexpand, {.i = +1} },
++ { MODKEY|ControlMask, XK_KP_1, toggleverticalexpand, {.i = 0} },
++ { MODKEY|ControlMask, XK_KP_2, toggleverticalexpand, {.i = -1} },
++ { MODKEY|ControlMask, XK_KP_9, togglemaximize, {.i = -1} },
++ { MODKEY|ControlMask, XK_KP_7, togglemaximize, {.i = +1} },
++ { MODKEY|ControlMask, XK_KP_5, togglemaximize, {.i = 0} },
+ };
+
+ /* button definitions */
+diff --git a/dwm.c b/dwm.c
+index 4986b07..8fc0c57 100644
+--- a/dwm.c
++++ b/dwm.c
+_AT_@ -89,11 +89,14 @@ struct Client {
+ char name[256];
+ float mina, maxa;
+ int x, y, w, h;
++ int sfx, sfy, sfw, sfh; /* stored float geometry, used on mode revert */
+ int oldx, oldy, oldw, oldh;
+ int basew, baseh, incw, inch, maxw, maxh, minw, minh;
+ int bw, oldbw;
+ unsigned int tags;
+- Bool isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
++ unsigned char expandmask;
++ int expandx1, expandy1, expandx2, expandy2;
++ Bool wasfloating, isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
+ Client *next;
+ Client *snext;
+ Monitor *mon;
+_AT_@ -1132,8 +1135,14 @@ manage(Window w, XWindowAttributes *wa) {
+ updatewindowtype(c);
+ updatesizehints(c);
+ updatewmhints(c);
++ c->sfx = c->x;
++ c->sfy = c->y;
++ c->sfw = c->w;
++ c->sfh = c->h;
+ XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
+ grabbuttons(c, False);
++ c->wasfloating = False;
++ c->expandmask = 0;
+ if(!c->isfloating)
+ c->isfloating = c->oldstate = trans != None || c->isfixed;
+ if(c->isfloating)
+_AT_@ -1234,8 +1243,9 @@ movemouse(const Arg *arg) {
+ case MotionNotify:
+ nx = ocx + (ev.xmotion.x - x);
+ ny = ocy + (ev.xmotion.y - y);
+- if(nx >= selmon->wx && nx <= selmon->wx + selmon->ww
+- && ny >= selmon->wy && ny <= selmon->wy + selmon->wh) {
++ if ((m = recttomon(nx, ny, c->w, c->h))) {
++ if (m != selmon)
++ sendmon(c, m);
+ if(abs(selmon->wx - nx) < snap)
+ nx = selmon->wx;
+ else if(abs((selmon->wx + selmon->ww) - (nx + WIDTH(c))) < snap)
+_AT_@ -1343,6 +1353,7 @@ resizeclient(Client *c, int x, int y, int w, int h) {
+ c->oldy = c->y; c->y = wc.y = y;
+ c->oldw = c->w; c->w = wc.width = w;
+ c->oldh = c->h; c->h = wc.height = h;
++ c->expandmask = 0;
+ wc.border_width = c->bw;
+ XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
+ configure(c);
+_AT_@ -1379,9 +1390,9 @@ resizemouse(const Arg *arg) {
+ case MotionNotify:
+ nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1);
+ nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1);
+- if(c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww
+- && c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh)
+- {
++ if ((m = recttomon(c->x, c->y, nw, nh))) {
++ if (m != selmon)
++ sendmon(c, m);
+ if(!c->isfloating && selmon->lt[selmon->sellt]->arrange
+ && (abs(nw - c->w) > snap || abs(nh - c->h) > snap))
+ togglefloating(NULL);
+_AT_@ -1463,6 +1474,7 @@ scan(void) {
+
+ void
+ sendmon(Client *c, Monitor *m) {
++ Monitor *oldm = selmon;
+ if(c->mon == m)
+ return;
+ unfocus(c, True);
+_AT_@ -1472,8 +1484,11 @@ sendmon(Client *c, Monitor *m) {
+ c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
+ attach(c);
+ attachstack(c);
+- focus(NULL);
+- arrange(NULL);
++ if (oldm != m)
++ arrange(oldm);
++ arrange(m);
++ focus(c);
++ restack(m);
+ }
+
+ void
+_AT_@ -1549,8 +1564,18 @@ setfullscreen(Client *c, Bool fullscreen) {
+
+ void
+ setlayout(const Arg *arg) {
+- if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
++ if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) {
+ selmon->sellt ^= 1;
++ if (!selmon->lt[selmon->sellt]->arrange) {
++ for (Client *c = selmon->clients ; c ; c = c->next) {
++ if(!c->isfloating) {
++ /*restore last known float dimensions*/
++ resize(c, selmon->mx + c->sfx, selmon->my + c->sfy,
++ c->sfw, c->sfh, False);
++ }
++ }
++ }
++ }
+ if(arg && arg->v)
+ selmon->lt[selmon->sellt] = (Layout *)arg->v;
+ strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
+_AT_@ -1732,9 +1757,19 @@ togglefloating(const Arg *arg) {
+ if(selmon->sel->isfullscreen) /* no support for fullscreen windows */
+ return;
+ selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed;
+- if(selmon->sel->isfloating)
+- resize(selmon->sel, selmon->sel->x, selmon->sel->y,
+- selmon->sel->w, selmon->sel->h, False);
++ if(selmon->sel->isfloating) {
++ /*restore last known float dimensions*/
++ resize(selmon->sel, selmon->mx + selmon->sel->sfx, selmon->my + selmon->sel->sfy,
++ selmon->sel->sfw, selmon->sel->sfh, False);
++ } else {
++ if (selmon->sel->isfullscreen)
++ setfullscreen(selmon->sel, False);
++ /*save last known float dimensions*/
++ selmon->sel->sfx = selmon->sel->x - selmon->mx;
++ selmon->sel->sfy = selmon->sel->y - selmon->my;
++ selmon->sel->sfw = selmon->sel->w;
++ selmon->sel->sfh = selmon->sel->h;
++ }
+ arrange(selmon);
+ }
+
+diff --git a/exresize.c b/exresize.c
+new file mode 100644
+index 0000000..2343ffe
+--- /dev/null
++++ b/exresize.c
+_AT_@ -0,0 +1,195 @@
++#define EXPAND_LEFT (1 << 0)
++#define EXPAND_RIGHT (1 << 2)
++#define EXPAND_UP (1 << 4)
++#define EXPAND_DOWN (1 << 6)
++
++#define IS_SET(q, w) ((q & w) != 0)
++#define IS_FORCED(q, w) IS_SET((q << 1), w)
++
++#define EXPANDALL (EXPAND_LEFT | EXPAND_RIGHT | EXPAND_UP | EXPAND_DOWN)
++#define UNEXPAND (EXPANDALL << 1) // Force all directions to 0
++#define FORCE_EXPANDALL ~0 // Force expand in all directions
++
++enum { EX_NW, EX_N, EX_NE, EX_W, EX_C, EX_E, EX_SW, EX_S, EX_SE };
++
++void expand(unsigned char mask);
++
++void togglemaximize(const Arg *arg);
++void toggleverticalexpand(const Arg *arg);
++void togglehorizontalexpand(const Arg *arg);
++void exresize(const Arg *arg);
++void explace(const Arg *arg);
++
++void
++exresize(const Arg *arg) {
++ Client *c;
++ int x, y, nx, ny, nw, nh;
++ c = selmon->sel;
++
++ if (!c || !arg) return;
++ if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
++ togglefloating(NULL);
++ if (c->expandmask != 0)
++ expand(UNEXPAND);
++
++ x = ((int *)arg->v)[0];
++ y = ((int *)arg->v)[1];
++
++ nw = MIN(selmon->ww - c->bw*2, c->w + x);
++ nh = MIN(selmon->wh - c->bw*2, c->h + y);
++ nx = c->x - x/2;
++ ny = c->y - y/2;
++
++ if (!((abs(c->x + c->w/2 - (selmon->wx + selmon->ww/2)) < snap))) {
++ if ((nw == selmon->ww) ||
++ (nx < selmon->wx) ||
++ (abs(selmon->wx - c->x) < snap))
++ nx = selmon->wx;
++ else if ((nx+nw > (selmon->wx + selmon->ww)) ||
++ (abs((selmon->wx + selmon->ww) - (c->x + c->w)) < snap))
++ nx = (selmon->wx + selmon->ww) - nw - c->bw*2;
++ } else
++ nx = selmon->wx + selmon->ww/2 - nw/2;
++
++ if (!((abs(c->y + c->h/2 - (selmon->wy + selmon->wh/2)) < snap))) {
++
++ if ((nh == selmon->wh) ||
++ (ny < selmon->wy) ||
++ (abs(selmon->wy - c->y) < snap))
++ ny = selmon->wy;
++ else if ((ny+nh > (selmon->wy + selmon->wh)) ||
++ (abs((selmon->wy + selmon->wh) - (c->y + c->h)) < snap))
++ ny = (selmon->wy + selmon->wh) - nh - c->bw*2;
++ } else
++ ny = selmon->wy + selmon->wh/2 - nh/2;
++
++
++ resizeclient(c, nx, ny, MAX(nw, 32), MAX(nh, 32));
++ XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w/2, c->h/2);
++}
++
++void
++explace(const Arg *arg) {
++ Client *c;
++ int nx, ny;
++
++ c = selmon->sel;
++ if (!c || (arg->ui >= 9)) return;
++ if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
++ togglefloating(NULL);
++
++ nx = (arg->ui % 3) - 1;
++ ny = (arg->ui / 3) - 1;
++
++ if (nx < 0) nx = selmon->wx;
++ else if (nx > 0) nx = selmon->wx + selmon->ww - c->w - c->bw*2;
++ else nx = selmon->wx + selmon->ww/2 - c->w/2;
++
++ if (ny < 0) ny = selmon->wy;
++ else if (ny > 0) ny = selmon->wy + selmon->wh - c->h - c->bw*2;
++ else ny = selmon->wy + selmon->wh/2 - c->h/2;
++
++ resize(c, nx, ny, c->w, c->h, True);
++ XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w/2, c->h/2);
++}
++
++int
++calculate_expand(unsigned char mask, unsigned char curmask,
++ unsigned char *newmask, unsigned char key,
++ int *reset_value, int new_reset_value,
++ int max_value, int old_value) {
++ if (IS_SET(key, mask) ||
++ (IS_SET(key, curmask) && (!IS_SET(key, mask) && IS_FORCED(key, mask))) ||
++ (!IS_SET(key, curmask) && (IS_SET(key, mask) && IS_FORCED(key, mask)))) {
++
++ if (IS_SET(key, mask) && (!IS_SET(key,curmask) || IS_FORCED(key,mask)))
++ {
++ if (!IS_SET(key, curmask))
++ *reset_value = new_reset_value;
++ *newmask |= key;
++ return max_value;
++ } else if ((IS_SET(key,curmask) && IS_SET(key, mask)) ||
++ (!IS_SET(key, mask) && IS_FORCED(key, mask))) {
++ *newmask &= ~key;
++ return *reset_value;
++ } else {
++ *newmask &= ~key;
++ return old_value;
++ }
++ } else
++ return new_reset_value;
++}
++
++void
++expand(unsigned char mask) {
++ XEvent ev;
++ int nx1, ny1, nx2, ny2;
++ unsigned char curmask;
++ unsigned char newmask;
++
++ if(!selmon->sel || selmon->sel->isfixed)
++ return;
++ XRaiseWindow(dpy, selmon->sel->win);
++ newmask = curmask = selmon->sel->expandmask;
++
++ if (curmask == 0) {
++ if(!selmon->lt[selmon->sellt]->arrange || selmon->sel->isfloating)
++ selmon->sel->wasfloating = True;
++ else {
++ togglefloating(NULL);
++ selmon->sel->wasfloating = False;
++ }
++ }
++
++ nx1 = calculate_expand(mask, curmask, &newmask,
++ EXPAND_LEFT, &selmon->sel->expandx1,
++ selmon->sel->x,
++ selmon->wx,
++ selmon->sel->oldx);
++ nx2 = calculate_expand(mask, curmask, &newmask,
++ EXPAND_RIGHT, &selmon->sel->expandx2,
++ selmon->sel->x + selmon->sel->w,
++ selmon->wx + selmon->ww - 2*borderpx,
++ selmon->sel->oldw + selmon->sel->x);
++ ny1 = calculate_expand(mask, curmask, &newmask,
++ EXPAND_UP, &selmon->sel->expandy1,
++ selmon->sel->y,
++ selmon->wy,
++ selmon->sel->oldy);
++ ny2 = calculate_expand(mask, curmask, &newmask,
++ EXPAND_DOWN, &selmon->sel->expandy2,
++ selmon->sel->y + selmon->sel->h,
++ selmon->wy + selmon->wh - 2*borderpx,
++ selmon->sel->oldh + selmon->sel->y);
++
++
++ resizeclient(selmon->sel, nx1, ny1, MAX(nx2-nx1, 32), MAX(ny2-ny1, 32));
++
++ if ((newmask == 0) && (!selmon->sel->wasfloating))
++ togglefloating(NULL);
++ selmon->sel->expandmask = newmask;
++ drawbar(selmon);
++ while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
++}
++
++void
++togglemaximize(const Arg *arg) {
++ if (arg->i > 0) expand(FORCE_EXPANDALL);
++ else if (arg->i < 0) expand(UNEXPAND);
++ else expand(EXPANDALL);
++}
++
++void
++toggleverticalexpand(const Arg *arg) {
++ if (arg->i < 0) expand(EXPAND_DOWN);
++ else if (arg->i > 0) expand(EXPAND_UP);
++ else expand(EXPAND_DOWN | EXPAND_UP);
++}
++
++void
++togglehorizontalexpand(const Arg *arg) {
++ if (arg->i < 0) expand(EXPAND_LEFT);
++ else if (arg->i > 0) expand(EXPAND_RIGHT);
++ else expand(EXPAND_LEFT | EXPAND_RIGHT);
++}
++
diff -r 887a394b79f4 -r 83d9be6a8c73 dwm.suckless.org/patches/exresize.md
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dwm.suckless.org/patches/exresize.md Sat Nov 17 18:20:43 2012 +0100
_AT_@ -0,0 +1,24 @@
+exresize
+========
+
+Description
+-----------
+
+This allows the user to change size and placement of floating windows using only
+the keyboard. It also allows for temporary vertical and horizontal extension of
+windows similar to other WMs fill command. This patch is inspired by
+[maximize](http://dwm.suckless.org/patches/maximize) and
+[moveresize](http://dwm.suckless.org/patches/moveresize) but fixes a lot of
+problems I had with those patches. It also includes the functionality of
+[save floats](http://dwm.suckless.org/patches/save_floats) judging by it's
+description.
+
+Download
+--------
+
+ * [dwm-r1606-exresize.dif](dwm-r1606-exresize.diff) (20121117)
+
+Authors
+-------
+
+ * Krister Svanlund - `<krister.svanlund_AT_gmail.com>`
Received on Sat Nov 17 2012 - 18:21:02 CET

This archive was generated by hypermail 2.3.0 : Sat Nov 17 2012 - 18:24:08 CET