exresize.c (5175B)
1 #define EXPAND_LEFT (1 << 0) 2 #define EXPAND_RIGHT (1 << 2) 3 #define EXPAND_UP (1 << 4) 4 #define EXPAND_DOWN (1 << 6) 5 6 #define IS_SET(q, w) ((q & w) != 0) 7 #define IS_FORCED(q, w) IS_SET((q << 1), w) 8 9 #define EXPANDALL (EXPAND_LEFT | EXPAND_RIGHT | EXPAND_UP | EXPAND_DOWN) 10 #define UNEXPAND (EXPANDALL << 1) // Force all directions to 0 11 #define FORCE_EXPANDALL ~0 // Force expand in all directions 12 13 void 14 exresize(const Arg *arg) 15 { 16 Client *c; 17 int x, y, nx, ny, nw, nh; 18 c = selmon->sel; 19 20 if (!c || !arg) return; 21 if (selmon->lt[selmon->sellt]->arrange && !c->isfloating) 22 togglefloating(NULL); 23 if (c->expandmask != 0) 24 expand(UNEXPAND); 25 26 x = ((int *)arg->v)[0]; 27 y = ((int *)arg->v)[1]; 28 29 nw = MIN(selmon->ww - c->bw*2, c->w + x); 30 nh = MIN(selmon->wh - c->bw*2, c->h + y); 31 nx = c->x - x/2; 32 ny = c->y - y/2; 33 34 if (!((abs(c->x + c->w/2 - (selmon->wx + selmon->ww/2)) < snap))) { 35 if ((nw == selmon->ww) || 36 (nx < selmon->wx) || 37 (abs(selmon->wx - c->x) < snap)) 38 nx = selmon->wx; 39 else if ((nx+nw > (selmon->wx + selmon->ww)) || 40 (abs((selmon->wx + selmon->ww) - (c->x + c->w)) < snap)) 41 nx = (selmon->wx + selmon->ww) - nw - c->bw*2; 42 } else 43 nx = selmon->wx + selmon->ww/2 - nw/2; 44 45 if (!((abs(c->y + c->h/2 - (selmon->wy + selmon->wh/2)) < snap))) { 46 47 if ((nh == selmon->wh) || 48 (ny < selmon->wy) || 49 (abs(selmon->wy - c->y) < snap)) 50 ny = selmon->wy; 51 else if ((ny+nh > (selmon->wy + selmon->wh)) || 52 (abs((selmon->wy + selmon->wh) - (c->y + c->h)) < snap)) 53 ny = (selmon->wy + selmon->wh) - nh - c->bw*2; 54 } else 55 ny = selmon->wy + selmon->wh/2 - nh/2; 56 57 58 resizeclient(c, nx, ny, MAX(nw, 32), MAX(nh, 32)); 59 XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w/2, c->h/2); 60 } 61 62 void 63 explace(const Arg *arg) 64 { 65 Client *c; 66 int nx, ny; 67 68 c = selmon->sel; 69 if (!c || (arg->ui >= 9)) return; 70 if (selmon->lt[selmon->sellt]->arrange && !c->isfloating) 71 togglefloating(NULL); 72 73 nx = (arg->ui % 3) - 1; 74 ny = (arg->ui / 3) - 1; 75 76 if (nx < 0) nx = selmon->wx; 77 else if (nx > 0) nx = selmon->wx + selmon->ww - c->w - c->bw*2; 78 else nx = selmon->wx + selmon->ww/2 - c->w/2; 79 80 if (ny < 0) ny = selmon->wy; 81 else if (ny > 0) ny = selmon->wy + selmon->wh - c->h - c->bw*2; 82 else ny = selmon->wy + selmon->wh/2 - c->h/2; 83 84 resize(c, nx, ny, c->w, c->h, True); 85 XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w/2, c->h/2); 86 } 87 88 int 89 calculate_expand(unsigned char mask, unsigned char curmask, 90 unsigned char *newmask, unsigned char key, 91 int *reset_value, int new_reset_value, 92 int max_value, int old_value) 93 { 94 if (IS_SET(key, mask) || 95 (IS_SET(key, curmask) && (!IS_SET(key, mask) && IS_FORCED(key, mask))) || 96 (!IS_SET(key, curmask) && (IS_SET(key, mask) && IS_FORCED(key, mask)))) { 97 98 if (IS_SET(key, mask) && (!IS_SET(key,curmask) || IS_FORCED(key,mask))) { 99 if (!IS_SET(key, curmask)) 100 *reset_value = new_reset_value; 101 *newmask |= key; 102 return max_value; 103 } else if ((IS_SET(key,curmask) && IS_SET(key, mask)) || 104 (!IS_SET(key, mask) && IS_FORCED(key, mask))) { 105 *newmask &= ~key; 106 return *reset_value; 107 } else { 108 *newmask &= ~key; 109 return old_value; 110 } 111 } else 112 return new_reset_value; 113 } 114 115 void 116 expand(unsigned char mask) 117 { 118 XEvent ev; 119 int nx1, ny1, nx2, ny2; 120 #if SETBORDERPX_PATCH 121 int bp = selmon->borderpx; 122 #else 123 int bp = borderpx; 124 #endif // SETBORDERPX_PATCH 125 unsigned char curmask; 126 unsigned char newmask; 127 128 if (!selmon->sel || selmon->sel->isfixed) 129 return; 130 XRaiseWindow(dpy, selmon->sel->win); 131 newmask = curmask = selmon->sel->expandmask; 132 133 if (curmask == 0) { 134 if(!selmon->lt[selmon->sellt]->arrange || selmon->sel->isfloating) 135 selmon->sel->wasfloating = 1; 136 else { 137 togglefloating(NULL); 138 selmon->sel->wasfloating = 0; 139 } 140 } 141 142 nx1 = calculate_expand(mask, curmask, &newmask, 143 EXPAND_LEFT, &selmon->sel->expandx1, 144 selmon->sel->x, 145 selmon->wx, 146 selmon->sel->oldx); 147 nx2 = calculate_expand(mask, curmask, &newmask, 148 EXPAND_RIGHT, &selmon->sel->expandx2, 149 selmon->sel->x + selmon->sel->w, 150 selmon->wx + selmon->ww - 2*bp, 151 selmon->sel->oldw + selmon->sel->x); 152 ny1 = calculate_expand(mask, curmask, &newmask, 153 EXPAND_UP, &selmon->sel->expandy1, 154 selmon->sel->y, 155 selmon->wy, 156 selmon->sel->oldy); 157 ny2 = calculate_expand(mask, curmask, &newmask, 158 EXPAND_DOWN, &selmon->sel->expandy2, 159 selmon->sel->y + selmon->sel->h, 160 selmon->wy + selmon->wh - 2*bp, 161 selmon->sel->oldh + selmon->sel->y); 162 163 164 resizeclient(selmon->sel, nx1, ny1, MAX(nx2-nx1, 32), MAX(ny2-ny1, 32)); 165 166 if ((newmask == 0) && (!selmon->sel->wasfloating)) 167 togglefloating(NULL); 168 selmon->sel->expandmask = newmask; 169 drawbar(selmon); 170 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); 171 } 172 173 void 174 togglemaximize(const Arg *arg) 175 { 176 if (arg->i > 0) expand(FORCE_EXPANDALL); 177 else if (arg->i < 0) expand(UNEXPAND); 178 else expand(EXPANDALL); 179 } 180 181 void 182 toggleverticalexpand(const Arg *arg) 183 { 184 if (arg->i < 0) expand(EXPAND_DOWN); 185 else if (arg->i > 0) expand(EXPAND_UP); 186 else expand(EXPAND_DOWN | EXPAND_UP); 187 } 188 189 void 190 togglehorizontalexpand(const Arg *arg) 191 { 192 if (arg->i < 0) expand(EXPAND_LEFT); 193 else if (arg->i > 0) expand(EXPAND_RIGHT); 194 else expand(EXPAND_LEFT | EXPAND_RIGHT); 195 } 196