dwm-exresize-r1606.diff - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) 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,                {.ui = EX_NW }},
           11 +        { MODKEY,                       XK_KP_8,   explace,                {.ui = EX_N  }},
           12 +        { MODKEY,                       XK_KP_9,   explace,                {.ui = EX_NE }},
           13 +        { MODKEY,                       XK_KP_4,   explace,                {.ui = EX_W  }},
           14 +        { MODKEY,                       XK_KP_5,   explace,                {.ui = EX_C  }},
           15 +        { MODKEY,                       XK_KP_6,   explace,                {.ui = EX_E  }},
           16 +        { MODKEY,                       XK_KP_1,   explace,                {.ui = EX_SW }},
           17 +        { MODKEY,                       XK_KP_2,   explace,                {.ui = EX_S  }},
           18 +        { MODKEY,                       XK_KP_3,   explace,                {.ui = EX_SE }},
           19 +
           20 +        { MODKEY|ShiftMask,             XK_KP_8,   exresize,               {.v = (int []){   0,  25 }}},
           21 +        { MODKEY|ShiftMask,             XK_KP_2,   exresize,               {.v = (int []){   0, -25 }}},
           22 +        { MODKEY|ShiftMask,             XK_KP_6,   exresize,               {.v = (int []){  25,   0 }}},
           23 +        { MODKEY|ShiftMask,             XK_KP_4,   exresize,               {.v = (int []){ -25,   0 }}},
           24 +        { MODKEY|ShiftMask,             XK_KP_5,   exresize,               {.v = (int []){  25,  25 }}},
           25 +        { MODKEY|ShiftMask|ControlMask, XK_KP_5,   exresize,               {.v = (int []){ -25, -25 }}},
           26 +
           27 +        { MODKEY|ControlMask,           XK_KP_6,   togglehorizontalexpand, {.i = +1} },
           28 +        { MODKEY|ControlMask,           XK_KP_3,   togglehorizontalexpand, {.i =  0} },
           29 +        { MODKEY|ControlMask,           XK_KP_4,   togglehorizontalexpand, {.i = -1} },
           30 +        { MODKEY|ControlMask,           XK_KP_8,   toggleverticalexpand,   {.i = +1} },
           31 +        { MODKEY|ControlMask,           XK_KP_1,   toggleverticalexpand,   {.i =  0} },
           32 +        { MODKEY|ControlMask,           XK_KP_2,   toggleverticalexpand,   {.i = -1} },
           33 +        { MODKEY|ControlMask,           XK_KP_9,   togglemaximize,         {.i = -1} },
           34 +        { MODKEY|ControlMask,           XK_KP_7,   togglemaximize,         {.i = +1} },
           35 +        { MODKEY|ControlMask,           XK_KP_5,   togglemaximize,         {.i =  0} },
           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 revert */
           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, isfullscreen;
           53 +        unsigned char expandmask;
           54 +        int expandx1, expandy1, expandx2, expandy2;
           55 +        Bool wasfloating, isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
           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|PropertyChangeMask|StructureNotifyMask);
           68          grabbuttons(c, False);
           69 +        c->wasfloating = False;
           70 +        c->expandmask = 0;
           71          if(!c->isfloating)
           72                  c->isfloating = c->oldstate = trans != None || c->isfixed;
           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 + selmon->ww
           79 -                        && ny >= selmon->wy && ny <= selmon->wy + selmon->wh) {
           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) - (nx + WIDTH(c))) < snap)
           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|CWBorderWidth, &wc);
           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 + nw <= selmon->wx + selmon->ww
           99 -                        && c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh)
          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->sellt]->arrange
          105                                  && (abs(nw - c->w) > snap || abs(nh - c->h) > snap))
          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 monitor */
          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->next) {
          138 +                                if(!c->isfloating) {
          139 +                                        /*restore last known float dimensions*/
          140 +                                        resize(c, selmon->mx + c->sfx, selmon->my + c->sfy,
          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, sizeof selmon->ltsymbol);
          149 @@ -1732,9 +1757,19 @@ togglefloating(const Arg *arg) {
          150          if(selmon->sel->isfullscreen) /* no support for fullscreen windows */
          151                  return;
          152          selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed;
          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, selmon->my + selmon->sel->sfy,
          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 | EXPAND_DOWN)
          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 + c->w)) < snap))
          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 + c->h)) < snap))
          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) && IS_FORCED(key, mask))) ||
          280 +                        (!IS_SET(key, curmask) && (IS_SET(key, mask) && IS_FORCED(key, mask)))) {
          281 +
          282 +                if (IS_SET(key, mask) && (!IS_SET(key,curmask) || IS_FORCED(key,mask)))
          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, mask))) {
          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->isfloating)
          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-ny1, 32));
          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 +