dwm-stacker-6.0.diff - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       dwm-stacker-6.0.diff (6401B)
       ---
            1 diff --git a/config.def.h b/config.def.h
            2 index 77ff358..566e0c7 100644
            3 --- a/config.def.h
            4 +++ b/config.def.h
            5 @@ -41,6 +41,14 @@ static const Layout layouts[] = {
            6          { MODKEY|ControlMask,           KEY,      toggleview,     {.ui = 1 << TAG} }, \
            7          { MODKEY|ShiftMask,             KEY,      tag,            {.ui = 1 << TAG} }, \
            8          { MODKEY|ControlMask|ShiftMask, KEY,      toggletag,      {.ui = 1 << TAG} },
            9 +#define STACKKEYS(MOD,ACTION) \
           10 +        { MOD, XK_j,     ACTION##stack, {.i = INC(+1) } }, \
           11 +        { MOD, XK_k,     ACTION##stack, {.i = INC(-1) } }, \
           12 +        { MOD, XK_grave, ACTION##stack, {.i = PREVSEL } }, \
           13 +        { MOD, XK_q,     ACTION##stack, {.i = 0 } }, \
           14 +        { MOD, XK_a,     ACTION##stack, {.i = 1 } }, \
           15 +        { MOD, XK_z,     ACTION##stack, {.i = 2 } }, \
           16 +        { MOD, XK_x,     ACTION##stack, {.i = -1 } },
           17  
           18  /* helper for spawning shell commands in the pre dwm-5.0 fashion */
           19  #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
           20 @@ -54,8 +62,8 @@ static Key keys[] = {
           21          { MODKEY,                       XK_p,      spawn,          {.v = dmenucmd } },
           22          { MODKEY|ShiftMask,             XK_Return, spawn,          {.v = termcmd } },
           23          { MODKEY,                       XK_b,      togglebar,      {0} },
           24 -        { MODKEY,                       XK_j,      focusstack,     {.i = +1 } },
           25 -        { MODKEY,                       XK_k,      focusstack,     {.i = -1 } },
           26 +        STACKKEYS(MODKEY,                          focus)
           27 +        STACKKEYS(MODKEY|ShiftMask,                push)
           28          { MODKEY,                       XK_i,      incnmaster,     {.i = +1 } },
           29          { MODKEY,                       XK_d,      incnmaster,     {.i = -1 } },
           30          { MODKEY,                       XK_h,      setmfact,       {.f = -0.05} },
           31 @@ -83,7 +91,7 @@ static Key keys[] = {
           32          TAGKEYS(                        XK_7,                      6)
           33          TAGKEYS(                        XK_8,                      7)
           34          TAGKEYS(                        XK_9,                      8)
           35 -        { MODKEY|ShiftMask,             XK_q,      quit,           {0} },
           36 +        { MODKEY|ShiftMask,             XK_BackSpace, quit,        {0} },
           37  };
           38  
           39  /* button definitions */
           40 diff --git a/dwm.c b/dwm.c
           41 index 1d78655..6129f56 100644
           42 --- a/dwm.c
           43 +++ b/dwm.c
           44 @@ -43,17 +43,23 @@
           45  /* macros */
           46  #define BUTTONMASK              (ButtonPressMask|ButtonReleaseMask)
           47  #define CLEANMASK(mask)         (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
           48 +#define GETINC(X)               ((X) - 2000)
           49 +#define INC(X)                  ((X) + 2000)
           50  #define INTERSECT(x,y,w,h,m)    (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
           51                                 * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
           52 +#define ISINC(X)                ((X) > 1000 && (X) < 3000)
           53  #define ISVISIBLE(C)            ((C->tags & C->mon->tagset[C->mon->seltags]))
           54 +#define PREVSEL                 3000
           55  #define LENGTH(X)               (sizeof X / sizeof X[0])
           56  #define MAX(A, B)               ((A) > (B) ? (A) : (B))
           57  #define MIN(A, B)               ((A) < (B) ? (A) : (B))
           58 +#define MOD(N,M)                ((N)%(M) < 0 ? (N)%(M) + (M) : (N)%(M))
           59  #define MOUSEMASK               (BUTTONMASK|PointerMotionMask)
           60  #define WIDTH(X)                ((X)->w + 2 * (X)->bw)
           61  #define HEIGHT(X)               ((X)->h + 2 * (X)->bw)
           62  #define TAGMASK                 ((1 << LENGTH(tags)) - 1)
           63  #define TEXTW(X)                (textnw(X, strlen(X)) + dc.font.height)
           64 +#define TRUNC(X,A,B)            (MAX((A), MIN((X), (B))))
           65  
           66  /* enums */
           67  enum { CurNormal, CurResize, CurMove, CurLast };        /* cursor */
           68 @@ -205,6 +211,7 @@ static void movemouse(const Arg *arg);
           69  static Client *nexttiled(Client *c);
           70  static void pop(Client *);
           71  static void propertynotify(XEvent *e);
           72 +static void pushstack(const Arg *arg);
           73  static void quit(const Arg *arg);
           74  static Monitor *recttomon(int x, int y, int w, int h);
           75  static void resize(Client *c, int x, int y, int w, int h, Bool interact);
           76 @@ -224,6 +231,7 @@ static void setup(void);
           77  static void showhide(Client *c);
           78  static void sigchld(int unused);
           79  static void spawn(const Arg *arg);
           80 +static int stackpos(const Arg *arg);
           81  static void tag(const Arg *arg);
           82  static void tagmon(const Arg *arg);
           83  static int textnw(const char *text, unsigned int len);
           84 @@ -887,28 +895,16 @@ focusmon(const Arg *arg) {
           85  
           86  void
           87  focusstack(const Arg *arg) {
           88 -        Client *c = NULL, *i;
           89 +        int i = stackpos(arg);
           90 +        Client *c, *p;
           91  
           92 -        if(!selmon->sel)
           93 +        if(i < 0)
           94                  return;
           95 -        if(arg->i > 0) {
           96 -                for(c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next);
           97 -                if(!c)
           98 -                        for(c = selmon->clients; c && !ISVISIBLE(c); c = c->next);
           99 -        }
          100 -        else {
          101 -                for(i = selmon->clients; i != selmon->sel; i = i->next)
          102 -                        if(ISVISIBLE(i))
          103 -                                c = i;
          104 -                if(!c)
          105 -                        for(; i; i = i->next)
          106 -                                if(ISVISIBLE(i))
          107 -                                        c = i;
          108 -        }
          109 -        if(c) {
          110 -                focus(c);
          111 -                restack(selmon);
          112 -        }
          113 +
          114 +        for(p = NULL, c = selmon->clients; c && (i || !ISVISIBLE(c));
          115 +            i -= ISVISIBLE(c) ? 1 : 0, p = c, c = c->next);
          116 +        focus(c ? c : p);
          117 +        restack(selmon);
          118  }
          119  
          120  Atom
          121 @@ -1324,6 +1320,29 @@ propertynotify(XEvent *e) {
          122  }
          123  
          124  void
          125 +pushstack(const Arg *arg) {
          126 +        int i = stackpos(arg);
          127 +        Client *sel = selmon->sel, *c, *p;
          128 +
          129 +        if(i < 0)
          130 +                return;
          131 +        else if(i == 0) {
          132 +                detach(sel);
          133 +                attach(sel);
          134 +        }
          135 +        else {
          136 +                for(p = NULL, c = selmon->clients; c; p = c, c = c->next)
          137 +                        if(!(i -= (ISVISIBLE(c) && c != sel)))
          138 +                                break;
          139 +                c = c ? c : p;
          140 +                detach(sel);
          141 +                sel->next = c->next;
          142 +                c->next = sel;
          143 +        }
          144 +        arrange(selmon);
          145 +}
          146 +
          147 +void
          148  quit(const Arg *arg) {
          149          running = False;
          150  }
          151 @@ -1674,6 +1693,36 @@ spawn(const Arg *arg) {
          152          }
          153  }
          154  
          155 +int
          156 +stackpos(const Arg *arg) {
          157 +        int n, i;
          158 +        Client *c, *l;
          159 +
          160 +        if(!selmon->clients)
          161 +                return -1;
          162 +
          163 +        if(arg->i == PREVSEL) {
          164 +                for(l = selmon->stack; l && (!ISVISIBLE(l) || l == selmon->sel); l = l->snext);
          165 +                if(!l)
          166 +                        return -1;
          167 +                for(i = 0, c = selmon->clients; c != l; i += ISVISIBLE(c) ? 1 : 0, c = c->next);
          168 +                return i;
          169 +        }
          170 +        else if(ISINC(arg->i)) {
          171 +                if(!selmon->sel)
          172 +                        return -1;
          173 +                for(i = 0, c = selmon->clients; c != selmon->sel; i += ISVISIBLE(c) ? 1 : 0, c = c->next);
          174 +                for(n = i; c; n += ISVISIBLE(c) ? 1 : 0, c = c->next);
          175 +                return MOD(i + GETINC(arg->i), n);
          176 +        }
          177 +        else if(arg->i < 0) {
          178 +                for(i = 0, c = selmon->clients; c; i += ISVISIBLE(c) ? 1 : 0, c = c->next);
          179 +                return MAX(i + arg->i, 0);
          180 +        }
          181 +        else
          182 +                return arg->i;
          183 +}
          184 +
          185  void
          186  tag(const Arg *arg) {
          187          if(selmon->sel && arg->ui & TAGMASK) {