| dwm-exresize-r1606.diff - sites - public wiki contents of suckless.org | |
| git clone git://git.suckless.org/sites | |
| Log | |
| Files | |
| Refs | |
| --- | |
| dwm-exresize-r1606.diff (12751B) | |
| --- | |
| 1 diff --git a/config.def.h b/config.def.h | |
| 2 index 7fb4d82..959a119 100644 | |
| 3 --- a/config.def.h | |
| 4 +++ b/config.def.h | |
| 5 @@ -88,6 +88,33 @@ static Key keys[] = { | |
| 6 TAGKEYS( XK_8, 7) | |
| 7 TAGKEYS( XK_9, 8) | |
| 8 { MODKEY|ShiftMask, XK_q, quit, {0} … | |
| 9 + | |
| 10 + { MODKEY, XK_KP_7, explace, … | |
| 11 + { MODKEY, XK_KP_8, explace, … | |
| 12 + { MODKEY, XK_KP_9, explace, … | |
| 13 + { MODKEY, XK_KP_4, explace, … | |
| 14 + { MODKEY, XK_KP_5, explace, … | |
| 15 + { MODKEY, XK_KP_6, explace, … | |
| 16 + { MODKEY, XK_KP_1, explace, … | |
| 17 + { MODKEY, XK_KP_2, explace, … | |
| 18 + { MODKEY, XK_KP_3, explace, … | |
| 19 + | |
| 20 + { MODKEY|ShiftMask, XK_KP_8, exresize, … | |
| 21 + { MODKEY|ShiftMask, XK_KP_2, exresize, … | |
| 22 + { MODKEY|ShiftMask, XK_KP_6, exresize, … | |
| 23 + { MODKEY|ShiftMask, XK_KP_4, exresize, … | |
| 24 + { MODKEY|ShiftMask, XK_KP_5, exresize, … | |
| 25 + { MODKEY|ShiftMask|ControlMask, XK_KP_5, exresize, … | |
| 26 + | |
| 27 + { MODKEY|ControlMask, XK_KP_6, togglehorizontalexpa… | |
| 28 + { MODKEY|ControlMask, XK_KP_3, togglehorizontalexpa… | |
| 29 + { MODKEY|ControlMask, XK_KP_4, togglehorizontalexpa… | |
| 30 + { MODKEY|ControlMask, XK_KP_8, toggleverticalexpand… | |
| 31 + { MODKEY|ControlMask, XK_KP_1, toggleverticalexpand… | |
| 32 + { MODKEY|ControlMask, XK_KP_2, toggleverticalexpand… | |
| 33 + { MODKEY|ControlMask, XK_KP_9, togglemaximize, … | |
| 34 + { MODKEY|ControlMask, XK_KP_7, togglemaximize, … | |
| 35 + { MODKEY|ControlMask, XK_KP_5, togglemaximize, … | |
| 36 }; | |
| 37 | |
| 38 /* button definitions */ | |
| 39 diff --git a/dwm.c b/dwm.c | |
| 40 index 4986b07..8fc0c57 100644 | |
| 41 --- a/dwm.c | |
| 42 +++ b/dwm.c | |
| 43 @@ -89,11 +89,14 @@ struct Client { | |
| 44 char name[256]; | |
| 45 float mina, maxa; | |
| 46 int x, y, w, h; | |
| 47 + int sfx, sfy, sfw, sfh; /* stored float geometry, used on mode … | |
| 48 int oldx, oldy, oldw, oldh; | |
| 49 int basew, baseh, incw, inch, maxw, maxh, minw, minh; | |
| 50 int bw, oldbw; | |
| 51 unsigned int tags; | |
| 52 - Bool isfixed, isfloating, isurgent, neverfocus, oldstate, isful… | |
| 53 + unsigned char expandmask; | |
| 54 + int expandx1, expandy1, expandx2, expandy2; | |
| 55 + Bool wasfloating, isfixed, isfloating, isurgent, neverfocus, ol… | |
| 56 Client *next; | |
| 57 Client *snext; | |
| 58 Monitor *mon; | |
| 59 @@ -1132,8 +1135,14 @@ manage(Window w, XWindowAttributes *wa) { | |
| 60 updatewindowtype(c); | |
| 61 updatesizehints(c); | |
| 62 updatewmhints(c); | |
| 63 + c->sfx = c->x; | |
| 64 + c->sfy = c->y; | |
| 65 + c->sfw = c->w; | |
| 66 + c->sfh = c->h; | |
| 67 XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyCh… | |
| 68 grabbuttons(c, False); | |
| 69 + c->wasfloating = False; | |
| 70 + c->expandmask = 0; | |
| 71 if(!c->isfloating) | |
| 72 c->isfloating = c->oldstate = trans != None || c->isfix… | |
| 73 if(c->isfloating) | |
| 74 @@ -1234,8 +1243,9 @@ movemouse(const Arg *arg) { | |
| 75 case MotionNotify: | |
| 76 nx = ocx + (ev.xmotion.x - x); | |
| 77 ny = ocy + (ev.xmotion.y - y); | |
| 78 - if(nx >= selmon->wx && nx <= selmon->wx + selmo… | |
| 79 - && ny >= selmon->wy && ny <= selmon->wy + selmo… | |
| 80 + if ((m = recttomon(nx, ny, c->w, c->h))) { | |
| 81 + if (m != selmon) | |
| 82 + sendmon(c, m); | |
| 83 if(abs(selmon->wx - nx) < snap) | |
| 84 nx = selmon->wx; | |
| 85 else if(abs((selmon->wx + selmon->ww) -… | |
| 86 @@ -1343,6 +1353,7 @@ resizeclient(Client *c, int x, int y, int w, int h… | |
| 87 c->oldy = c->y; c->y = wc.y = y; | |
| 88 c->oldw = c->w; c->w = wc.width = w; | |
| 89 c->oldh = c->h; c->h = wc.height = h; | |
| 90 + c->expandmask = 0; | |
| 91 wc.border_width = c->bw; | |
| 92 XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorder… | |
| 93 configure(c); | |
| 94 @@ -1379,9 +1390,9 @@ resizemouse(const Arg *arg) { | |
| 95 case MotionNotify: | |
| 96 nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1); | |
| 97 nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1); | |
| 98 - if(c->mon->wx + nw >= selmon->wx && c->mon->wx … | |
| 99 - && c->mon->wy + nh >= selmon->wy && c->mon->wy … | |
| 100 - { | |
| 101 + if ((m = recttomon(c->x, c->y, nw, nh))) { | |
| 102 + if (m != selmon) | |
| 103 + sendmon(c, m); | |
| 104 if(!c->isfloating && selmon->lt[selmon-… | |
| 105 && (abs(nw - c->w) > snap || abs(nh - c… | |
| 106 togglefloating(NULL); | |
| 107 @@ -1463,6 +1474,7 @@ scan(void) { | |
| 108 | |
| 109 void | |
| 110 sendmon(Client *c, Monitor *m) { | |
| 111 + Monitor *oldm = selmon; | |
| 112 if(c->mon == m) | |
| 113 return; | |
| 114 unfocus(c, True); | |
| 115 @@ -1472,8 +1484,11 @@ sendmon(Client *c, Monitor *m) { | |
| 116 c->tags = m->tagset[m->seltags]; /* assign tags of target monit… | |
| 117 attach(c); | |
| 118 attachstack(c); | |
| 119 - focus(NULL); | |
| 120 - arrange(NULL); | |
| 121 + if (oldm != m) | |
| 122 + arrange(oldm); | |
| 123 + arrange(m); | |
| 124 + focus(c); | |
| 125 + restack(m); | |
| 126 } | |
| 127 | |
| 128 void | |
| 129 @@ -1549,8 +1564,18 @@ setfullscreen(Client *c, Bool fullscreen) { | |
| 130 | |
| 131 void | |
| 132 setlayout(const Arg *arg) { | |
| 133 - if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) | |
| 134 + if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) { | |
| 135 selmon->sellt ^= 1; | |
| 136 + if (!selmon->lt[selmon->sellt]->arrange) { | |
| 137 + for (Client *c = selmon->clients ; c ; c = c->n… | |
| 138 + if(!c->isfloating) { | |
| 139 + /*restore last known float dime… | |
| 140 + resize(c, selmon->mx + c->sfx, … | |
| 141 + c->sfw, c->sfh, False); | |
| 142 + } | |
| 143 + } | |
| 144 + } | |
| 145 + } | |
| 146 if(arg && arg->v) | |
| 147 selmon->lt[selmon->sellt] = (Layout *)arg->v; | |
| 148 strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, si… | |
| 149 @@ -1732,9 +1757,19 @@ togglefloating(const Arg *arg) { | |
| 150 if(selmon->sel->isfullscreen) /* no support for fullscreen wind… | |
| 151 return; | |
| 152 selmon->sel->isfloating = !selmon->sel->isfloating || selmon->s… | |
| 153 - if(selmon->sel->isfloating) | |
| 154 - resize(selmon->sel, selmon->sel->x, selmon->sel->y, | |
| 155 - selmon->sel->w, selmon->sel->h, False); | |
| 156 + if(selmon->sel->isfloating) { | |
| 157 + /*restore last known float dimensions*/ | |
| 158 + resize(selmon->sel, selmon->mx + selmon->sel->sfx, selm… | |
| 159 + selmon->sel->sfw, selmon->sel->sfh, False); | |
| 160 + } else { | |
| 161 + if (selmon->sel->isfullscreen) | |
| 162 + setfullscreen(selmon->sel, False); | |
| 163 + /*save last known float dimensions*/ | |
| 164 + selmon->sel->sfx = selmon->sel->x - selmon->mx; | |
| 165 + selmon->sel->sfy = selmon->sel->y - selmon->my; | |
| 166 + selmon->sel->sfw = selmon->sel->w; | |
| 167 + selmon->sel->sfh = selmon->sel->h; | |
| 168 + } | |
| 169 arrange(selmon); | |
| 170 } | |
| 171 | |
| 172 diff --git a/exresize.c b/exresize.c | |
| 173 new file mode 100644 | |
| 174 index 0000000..2343ffe | |
| 175 --- /dev/null | |
| 176 +++ b/exresize.c | |
| 177 @@ -0,0 +1,195 @@ | |
| 178 +#define EXPAND_LEFT (1 << 0) | |
| 179 +#define EXPAND_RIGHT (1 << 2) | |
| 180 +#define EXPAND_UP (1 << 4) | |
| 181 +#define EXPAND_DOWN (1 << 6) | |
| 182 + | |
| 183 +#define IS_SET(q, w) ((q & w) != 0) | |
| 184 +#define IS_FORCED(q, w) IS_SET((q << 1), w) | |
| 185 + | |
| 186 +#define EXPANDALL (EXPAND_LEFT | EXPAND_RIGHT | EXPAND_UP | EXPAN… | |
| 187 +#define UNEXPAND (EXPANDALL << 1) // Force all directions to 0 | |
| 188 +#define FORCE_EXPANDALL ~0 // Force expand in all directions | |
| 189 + | |
| 190 +enum { EX_NW, EX_N, EX_NE, EX_W, EX_C, EX_E, EX_SW, EX_S, EX_SE }; | |
| 191 + | |
| 192 +void expand(unsigned char mask); | |
| 193 + | |
| 194 +void togglemaximize(const Arg *arg); | |
| 195 +void toggleverticalexpand(const Arg *arg); | |
| 196 +void togglehorizontalexpand(const Arg *arg); | |
| 197 +void exresize(const Arg *arg); | |
| 198 +void explace(const Arg *arg); | |
| 199 + | |
| 200 +void | |
| 201 +exresize(const Arg *arg) { | |
| 202 + Client *c; | |
| 203 + int x, y, nx, ny, nw, nh; | |
| 204 + c = selmon->sel; | |
| 205 + | |
| 206 + if (!c || !arg) return; | |
| 207 + if (selmon->lt[selmon->sellt]->arrange && !c->isfloating) | |
| 208 + togglefloating(NULL); | |
| 209 + if (c->expandmask != 0) | |
| 210 + expand(UNEXPAND); | |
| 211 + | |
| 212 + x = ((int *)arg->v)[0]; | |
| 213 + y = ((int *)arg->v)[1]; | |
| 214 + | |
| 215 + nw = MIN(selmon->ww - c->bw*2, c->w + x); | |
| 216 + nh = MIN(selmon->wh - c->bw*2, c->h + y); | |
| 217 + nx = c->x - x/2; | |
| 218 + ny = c->y - y/2; | |
| 219 + | |
| 220 + if (!((abs(c->x + c->w/2 - (selmon->wx + selmon->ww/2)) < snap)… | |
| 221 + if ((nw == selmon->ww) || | |
| 222 + (nx < selmon->wx) || | |
| 223 + (abs(selmon->wx - c->x) < snap)) | |
| 224 + nx = selmon->wx; | |
| 225 + else if ((nx+nw > (selmon->wx + selmon->ww)) || | |
| 226 + (abs((selmon->wx + selmon->ww) - (c->x … | |
| 227 + nx = (selmon->wx + selmon->ww) - nw - c->bw*2; | |
| 228 + } else | |
| 229 + nx = selmon->wx + selmon->ww/2 - nw/2; | |
| 230 + | |
| 231 + if (!((abs(c->y + c->h/2 - (selmon->wy + selmon->wh/2)) < snap))) { | |
| 232 + | |
| 233 + if ((nh == selmon->wh) || | |
| 234 + (ny < selmon->wy) || | |
| 235 + (abs(selmon->wy - c->y) < snap)) | |
| 236 + ny = selmon->wy; | |
| 237 + else if ((ny+nh > (selmon->wy + selmon->wh)) || | |
| 238 + (abs((selmon->wy + selmon->wh) - (c->y … | |
| 239 + ny = (selmon->wy + selmon->wh) - nh - c->bw*2; | |
| 240 + } else | |
| 241 + ny = selmon->wy + selmon->wh/2 - nh/2; | |
| 242 + | |
| 243 + | |
| 244 + resizeclient(c, nx, ny, MAX(nw, 32), MAX(nh, 32)); | |
| 245 + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w/2, c->h/2); | |
| 246 +} | |
| 247 + | |
| 248 +void | |
| 249 +explace(const Arg *arg) { | |
| 250 + Client *c; | |
| 251 + int nx, ny; | |
| 252 + | |
| 253 + c = selmon->sel; | |
| 254 + if (!c || (arg->ui >= 9)) return; | |
| 255 + if (selmon->lt[selmon->sellt]->arrange && !c->isfloating) | |
| 256 + togglefloating(NULL); | |
| 257 + | |
| 258 + nx = (arg->ui % 3) - 1; | |
| 259 + ny = (arg->ui / 3) - 1; | |
| 260 + | |
| 261 + if (nx < 0) nx = selmon->wx; | |
| 262 + else if (nx > 0) nx = selmon->wx + selmon->ww - c->w - c->bw*2; | |
| 263 + else nx = selmon->wx + selmon->ww/2 - c->w/2; | |
| 264 + | |
| 265 + if (ny < 0) ny = selmon->wy; | |
| 266 + else if (ny > 0) ny = selmon->wy + selmon->wh - c->h - c->bw*2; | |
| 267 + else ny = selmon->wy + selmon->wh/2 - c->h/2; | |
| 268 + | |
| 269 + resize(c, nx, ny, c->w, c->h, True); | |
| 270 + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w/2, c->h/2); | |
| 271 +} | |
| 272 + | |
| 273 +int | |
| 274 +calculate_expand(unsigned char mask, unsigned char curmask, | |
| 275 + unsigned char *newmask, unsigned char key, | |
| 276 + int *reset_value, int new_reset_value, | |
| 277 + int max_value, int old_value) { | |
| 278 + if (IS_SET(key, mask) || | |
| 279 + (IS_SET(key, curmask) && (!IS_SET(key, mask) &&… | |
| 280 + (!IS_SET(key, curmask) && (IS_SET(key, mask) &&… | |
| 281 + | |
| 282 + if (IS_SET(key, mask) && (!IS_SET(key,curmask) || IS_FO… | |
| 283 + { | |
| 284 + if (!IS_SET(key, curmask)) | |
| 285 + *reset_value = new_reset_value; | |
| 286 + *newmask |= key; | |
| 287 + return max_value; | |
| 288 + } else if ((IS_SET(key,curmask) && IS_SET(key, mask)) || | |
| 289 + (!IS_SET(key, mask) && IS_FORCED(key, m… | |
| 290 + *newmask &= ~key; | |
| 291 + return *reset_value; | |
| 292 + } else { | |
| 293 + *newmask &= ~key; | |
| 294 + return old_value; | |
| 295 + } | |
| 296 + } else | |
| 297 + return new_reset_value; | |
| 298 +} | |
| 299 + | |
| 300 +void | |
| 301 +expand(unsigned char mask) { | |
| 302 + XEvent ev; | |
| 303 + int nx1, ny1, nx2, ny2; | |
| 304 + unsigned char curmask; | |
| 305 + unsigned char newmask; | |
| 306 + | |
| 307 + if(!selmon->sel || selmon->sel->isfixed) | |
| 308 + return; | |
| 309 + XRaiseWindow(dpy, selmon->sel->win); | |
| 310 + newmask = curmask = selmon->sel->expandmask; | |
| 311 + | |
| 312 + if (curmask == 0) { | |
| 313 + if(!selmon->lt[selmon->sellt]->arrange || selmon->sel->… | |
| 314 + selmon->sel->wasfloating = True; | |
| 315 + else { | |
| 316 + togglefloating(NULL); | |
| 317 + selmon->sel->wasfloating = False; | |
| 318 + } | |
| 319 + } | |
| 320 + | |
| 321 + nx1 = calculate_expand(mask, curmask, &newmask, | |
| 322 + EXPAND_LEFT, &selmon->sel->expandx1, | |
| 323 + selmon->sel->x, | |
| 324 + selmon->wx, | |
| 325 + selmon->sel->oldx); | |
| 326 + nx2 = calculate_expand(mask, curmask, &newmask, | |
| 327 + EXPAND_RIGHT, &selmon->sel->expandx2, | |
| 328 + selmon->sel->x + selmon->sel->w, | |
| 329 + selmon->wx + selmon->ww - 2*borderpx, | |
| 330 + selmon->sel->oldw + selmon->sel->x); | |
| 331 + ny1 = calculate_expand(mask, curmask, &newmask, | |
| 332 + EXPAND_UP, &selmon->sel->expandy1, | |
| 333 + selmon->sel->y, | |
| 334 + selmon->wy, | |
| 335 + selmon->sel->oldy); | |
| 336 + ny2 = calculate_expand(mask, curmask, &newmask, | |
| 337 + EXPAND_DOWN, &selmon->sel->expandy2, | |
| 338 + selmon->sel->y + selmon->sel->h, | |
| 339 + selmon->wy + selmon->wh - 2*borderpx, | |
| 340 + selmon->sel->oldh + selmon->sel->y); | |
| 341 + | |
| 342 + | |
| 343 + resizeclient(selmon->sel, nx1, ny1, MAX(nx2-nx1, 32), MAX(ny2-n… | |
| 344 + | |
| 345 + if ((newmask == 0) && (!selmon->sel->wasfloating)) | |
| 346 + togglefloating(NULL); | |
| 347 + selmon->sel->expandmask = newmask; | |
| 348 + drawbar(selmon); | |
| 349 + while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); | |
| 350 +} | |
| 351 + | |
| 352 +void | |
| 353 +togglemaximize(const Arg *arg) { | |
| 354 + if (arg->i > 0) expand(FORCE_EXPANDALL); | |
| 355 + else if (arg->i < 0) expand(UNEXPAND); | |
| 356 + else expand(EXPANDALL); | |
| 357 +} | |
| 358 + | |
| 359 +void | |
| 360 +toggleverticalexpand(const Arg *arg) { | |
| 361 + if (arg->i < 0) expand(EXPAND_DOWN); | |
| 362 + else if (arg->i > 0) expand(EXPAND_UP); | |
| 363 + else expand(EXPAND_DOWN | EXPAND_UP); | |
| 364 +} | |
| 365 + | |
| 366 +void | |
| 367 +togglehorizontalexpand(const Arg *arg) { | |
| 368 + if (arg->i < 0) expand(EXPAND_LEFT); | |
| 369 + else if (arg->i > 0) expand(EXPAND_RIGHT); | |
| 370 + else expand(EXPAND_LEFT | EXPAND_RIGHT); | |
| 371 +} | |
| 372 + |