diff options
Diffstat (limited to 'dwm/exresize.c')
| -rw-r--r-- | dwm/exresize.c | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/dwm/exresize.c b/dwm/exresize.c new file mode 100644 index 0000000..e3f0424 --- /dev/null +++ b/dwm/exresize.c @@ -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, 0); + 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 = 0; + else { + togglefloating(NULL); + selmon->sel->wasfloating = 0; + } + } + + 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); +} + |
