dwm-scratchpads-20200414-728d397b.diff - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       dwm-scratchpads-20200414-728d397b.diff (7977B)
       ---
            1 From 728d397b21982af88737277fd9d6939a7b558786 Mon Sep 17 00:00:00 2001
            2 From: Christian Tenllado <ctenllado@gmail.com>
            3 Date: Tue, 14 Apr 2020 23:31:15 +0200
            4 Subject: [PATCH] Multiple scratchpads
            5 
            6 This patch enables multiple scratchpads, each with one asigned window.
            7 This enables the same scratchpad workflow that you have in i3.
            8 
            9 Scratchpads are implemented as special tags, whose mask does not
           10 apply to new spawned windows. To assign a window to a scratchpad you
           11 have to set up a rule, as you do with regular tags.
           12 
           13 Windows tagged with scratchpad tags can be set floating or not in the
           14 rules array. Most users would probably want them floating (i3 style),
           15 but having them tiled does also perfectly work and might fit better the
           16 DWM approach. In case they are set floating, the patch moves them to the
           17 center of the screen whenever they are shown. The patch can easily be
           18 modified to make this last feature configurable in the rules array (see
           19 the center patch).
           20 
           21 The togglescratch function, borrowed from the previous scratchpad patch
           22 and slightly modified, can be used to spawn a registered scratchpad
           23 process or toggle its view. This function looks for a window tagged with
           24 the selected scratchpad tag. If it is found its view is toggled. If it is
           25 not found the corresponding registered command is spawned. The
           26 config.def.h shows three examples of its use to spawn a terminal in the
           27 first scratchpad tag, a second terminal running ranger on the second
           28 scratchpad tag and the keepassxc application to manage passwords on a
           29 third scratchpad tag.
           30 
           31 If you prefer to spawn your scratchpad applications from the startup
           32 script, you might opt for binding keys to toggleview instead, as
           33 scratchpads are just special tags (you may even extend the TAGKEYS macro
           34 to generalize the key bindings).
           35 ---
           36  config.def.h | 28 ++++++++++++++++++++++++----
           37  dwm.c        | 43 +++++++++++++++++++++++++++++++++++++++++--
           38  2 files changed, 65 insertions(+), 6 deletions(-)
           39 
           40 diff --git a/config.def.h b/config.def.h
           41 index 1c0b587..06265e1 100644
           42 --- a/config.def.h
           43 +++ b/config.def.h
           44 @@ -18,17 +18,33 @@ static const char *colors[][3]      = {
           45          [SchemeSel]  = { col_gray4, col_cyan,  col_cyan  },
           46  };
           47  
           48 +typedef struct {
           49 +        const char *name;
           50 +        const void *cmd;
           51 +} Sp;
           52 +const char *spcmd1[] = {"st", "-n", "spterm", "-g", "120x34", NULL };
           53 +const char *spcmd2[] = {"st", "-n", "spfm", "-g", "144x41", "-e", "ranger", NULL };
           54 +const char *spcmd3[] = {"keepassxc", NULL };
           55 +static Sp scratchpads[] = {
           56 +        /* name          cmd  */
           57 +        {"spterm",      spcmd1},
           58 +        {"spranger",    spcmd2},
           59 +        {"keepassxc",   spcmd3},
           60 +};
           61 +
           62  /* tagging */
           63  static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
           64 -
           65  static const Rule rules[] = {
           66          /* xprop(1):
           67           *        WM_CLASS(STRING) = instance, class
           68           *        WM_NAME(STRING) = title
           69           */
           70          /* class      instance    title       tags mask     isfloating   monitor */
           71 -        { "Gimp",     NULL,       NULL,       0,            1,           -1 },
           72 -        { "Firefox",  NULL,       NULL,       1 << 8,       0,           -1 },
           73 +        { "Gimp",          NULL,                        NULL,                0,                                1,                         -1 },
           74 +        { "Firefox",  NULL,                        NULL,                1 << 8,                        0,                         -1 },
           75 +        { NULL,                  "spterm",                NULL,                SPTAG(0),                1,                         -1 },
           76 +        { NULL,                  "spfm",                NULL,                SPTAG(1),                1,                         -1 },
           77 +        { NULL,                  "keepassxc",        NULL,                SPTAG(2),                0,                         -1 },
           78  };
           79  
           80  /* layout(s) */
           81 @@ -59,6 +75,7 @@ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn()
           82  static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
           83  static const char *termcmd[]  = { "st", NULL };
           84  
           85 +
           86  static Key keys[] = {
           87          /* modifier                     key        function        argument */
           88          { MODKEY,                       XK_p,      spawn,          {.v = dmenucmd } },
           89 @@ -84,6 +101,9 @@ static Key keys[] = {
           90          { MODKEY,                       XK_period, focusmon,       {.i = +1 } },
           91          { MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } },
           92          { MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } },
           93 +        { MODKEY,                                    XK_y,             togglescratch,  {.ui = 0 } },
           94 +        { MODKEY,                                    XK_u,           togglescratch,  {.ui = 1 } },
           95 +        { MODKEY,                                    XK_x,           togglescratch,  {.ui = 2 } },
           96          TAGKEYS(                        XK_1,                      0)
           97          TAGKEYS(                        XK_2,                      1)
           98          TAGKEYS(                        XK_3,                      2)
           99 @@ -106,7 +126,7 @@ static Button buttons[] = {
          100          { ClkStatusText,        0,              Button2,        spawn,          {.v = termcmd } },
          101          { ClkClientWin,         MODKEY,         Button1,        movemouse,      {0} },
          102          { ClkClientWin,         MODKEY,         Button2,        togglefloating, {0} },
          103 -        { ClkClientWin,         MODKEY,         Button3,        resizemouse,    {0} },
          104 +        { ClkClientWin,         MODKEY,         Button1,        resizemouse,    {0} },
          105          { ClkTagBar,            0,              Button1,        view,           {0} },
          106          { ClkTagBar,            0,              Button3,        toggleview,     {0} },
          107          { ClkTagBar,            MODKEY,         Button1,        tag,            {0} },
          108 diff --git a/dwm.c b/dwm.c
          109 index 4465af1..646aa1a 100644
          110 --- a/dwm.c
          111 +++ b/dwm.c
          112 @@ -54,7 +54,10 @@
          113  #define MOUSEMASK               (BUTTONMASK|PointerMotionMask)
          114  #define WIDTH(X)                ((X)->w + 2 * (X)->bw)
          115  #define HEIGHT(X)               ((X)->h + 2 * (X)->bw)
          116 -#define TAGMASK                 ((1 << LENGTH(tags)) - 1)
          117 +#define NUMTAGS                                        (LENGTH(tags) + LENGTH(scratchpads))
          118 +#define TAGMASK                             ((1 << NUMTAGS) - 1)
          119 +#define SPTAG(i)                                 ((1 << LENGTH(tags)) << (i))
          120 +#define SPTAGMASK                           (((1 << LENGTH(scratchpads))-1) << LENGTH(tags))
          121  #define TEXTW(X)                (drw_fontset_getwidth(drw, (X)) + lrpad)
          122  
          123  /* enums */
          124 @@ -211,6 +214,7 @@ static void tagmon(const Arg *arg);
          125  static void tile(Monitor *);
          126  static void togglebar(const Arg *arg);
          127  static void togglefloating(const Arg *arg);
          128 +static void togglescratch(const Arg *arg);
          129  static void toggletag(const Arg *arg);
          130  static void toggleview(const Arg *arg);
          131  static void unfocus(Client *c, int setfocus);
          132 @@ -299,6 +303,11 @@ applyrules(Client *c)
          133                  {
          134                          c->isfloating = r->isfloating;
          135                          c->tags |= r->tags;
          136 +                        if ((r->tags & SPTAGMASK) && r->isfloating) {
          137 +                                c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) / 2);
          138 +                                c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c) / 2);
          139 +                        }
          140 +
          141                          for (m = mons; m && m->num != r->monitor; m = m->next);
          142                          if (m)
          143                                  c->mon = m;
          144 @@ -308,7 +317,7 @@ applyrules(Client *c)
          145                  XFree(ch.res_class);
          146          if (ch.res_name)
          147                  XFree(ch.res_name);
          148 -        c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags];
          149 +        c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : (c->mon->tagset[c->mon->seltags] & ~SPTAGMASK);
          150  }
          151  
          152  int
          153 @@ -1616,6 +1625,10 @@ showhide(Client *c)
          154          if (!c)
          155                  return;
          156          if (ISVISIBLE(c)) {
          157 +                if ((c->tags & SPTAGMASK) && c->isfloating) {
          158 +                        c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) / 2);
          159 +                        c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c) / 2);
          160 +                }
          161                  /* show clients top down */
          162                  XMoveWindow(dpy, c->win, c->x, c->y);
          163                  if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen)
          164 @@ -1719,6 +1732,32 @@ togglefloating(const Arg *arg)
          165          arrange(selmon);
          166  }
          167  
          168 +void
          169 +togglescratch(const Arg *arg)
          170 +{
          171 +        Client *c;
          172 +        unsigned int found = 0;
          173 +        unsigned int scratchtag = SPTAG(arg->ui);
          174 +        Arg sparg = {.v = scratchpads[arg->ui].cmd};
          175 +
          176 +        for (c = selmon->clients; c && !(found = c->tags & scratchtag); c = c->next);
          177 +        if (found) {
          178 +                unsigned int newtagset = selmon->tagset[selmon->seltags] ^ scratchtag;
          179 +                if (newtagset) {
          180 +                        selmon->tagset[selmon->seltags] = newtagset;
          181 +                        focus(NULL);
          182 +                        arrange(selmon);
          183 +                }
          184 +                if (ISVISIBLE(c)) {
          185 +                        focus(c);
          186 +                        restack(selmon);
          187 +                }
          188 +        } else {
          189 +                selmon->tagset[selmon->seltags] |= scratchtag;
          190 +                spawn(&sparg);
          191 +        }
          192 +}
          193 +
          194  void
          195  toggletag(const Arg *arg)
          196  {
          197 -- 
          198 2.20.1
          199