dwm-alttabclass-6.4.diff - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       dwm-alttabclass-6.4.diff (9326B)
       ---
            1 diff -up a/config.def.h b/config.def.h
            2 --- a/config.def.h        2023-08-17 17:35:28.333393605 +0400
            3 +++ b/config.def.h        2023-08-17 17:24:46.724435876 +0400
            4 @@ -3,6 +3,7 @@
            5  /* alt-tab configuration */
            6  static const unsigned int tabModKey                 = 0x40;        /* if this key is hold the alt-tab functionality stays acitve. This key must be the same as key that is used to active functin altTabStart `*/
            7  static const unsigned int tabCycleKey                 = 0x17;        /* if this key is hit the alt-tab program moves one position forward in clients stack. This key must be the same as key that is used to active functin altTabStart */
            8 +static const unsigned int tabCycleKey2                 = 0x31;        /* grave key */
            9  static const unsigned int tabPosY                         = 1;        /* tab position on Y axis, 0 = bottom, 1 = center, 2 = top */
           10  static const unsigned int tabPosX                         = 1;        /* tab position on X axis, 0 = left, 1 = center, 2 = right */
           11  static const unsigned int maxWTab                         = 600;        /* tab menu width */
           12 @@ -93,7 +94,8 @@ static const Key keys[] = {
           13          { MODKEY,                       XK_period, focusmon,       {.i = +1 } },
           14          { MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } },
           15          { MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } },
           16 -        { Mod1Mask,                             XK_Tab,    altTabStart,           {0} },
           17 +        { Mod1Mask,                             XK_Tab,    altTabStart,           {.i = 1} },
           18 +        { Mod1Mask,                             XK_grave,  altTabStart,           {.i = 0} },
           19          TAGKEYS(                        XK_1,                      0)
           20          TAGKEYS(                        XK_2,                      1)
           21          TAGKEYS(                        XK_3,                      2)
           22 diff -up a/dwm.c b/dwm.c
           23 --- a/dwm.c        2023-08-17 17:24:19.753640383 +0400
           24 +++ b/dwm.c        2023-08-18 09:41:00.834187121 +0400
           25 @@ -87,6 +87,7 @@ typedef struct Monitor Monitor;
           26  typedef struct Client Client;
           27  struct Client {
           28          char name[256];
           29 +        char class[256];
           30          float mina, maxa;
           31          int x, y, w, h;
           32          int oldx, oldy, oldw, oldh;
           33 @@ -121,7 +122,9 @@ struct Monitor {
           34          int mx, my, mw, mh;   /* screen size */
           35          int wx, wy, ww, wh;   /* window area  */
           36          int altTabN;                  /* move that many clients forward */
           37 +        int altTabNc;                  /* move that many clients forward when using tab for same class */
           38          int nTabs;                          /* number of active clients in tag */
           39 +        int ncTabs;                          /* number of active clients under same class in tag */
           40          int isAlt;                           /* 1,0 */
           41          int maxWTab;
           42          int maxHTab;
           43 @@ -134,6 +137,7 @@ struct Monitor {
           44          Client *sel;
           45          Client *stack;
           46          Client ** altsnext; /* array of all clients in the tag */
           47 +        Client ** altsnextclass;        /* array of all clients under same class in the tag */
           48          Monitor *next;
           49          Window barwin;
           50          Window tabwin;
           51 @@ -245,6 +249,7 @@ static void zoom(const Arg *arg);
           52  void drawTab(int nwins, int first, Monitor *m);
           53  void altTabStart(const Arg *arg);
           54  static void altTabEnd();
           55 +static void getclassname(Client *c);
           56  
           57  /* variables */
           58  static const char broken[] = "broken";
           59 @@ -657,6 +662,7 @@ createmon(void)
           60          m->lt[0] = &layouts[0];
           61          m->lt[1] = &layouts[1 % LENGTH(layouts)];
           62          m->nTabs = 0;
           63 +        m->ncTabs = 0;
           64          strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
           65          return m;
           66  }
           67 @@ -1059,6 +1065,7 @@ manage(Window w, XWindowAttributes *wa)
           68          c->oldbw = wa->border_width;
           69  
           70          updatetitle(c);
           71 +        getclassname(c);
           72          if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
           73                  c->mon = t->mon;
           74                  c->tags = t->tags;
           75 @@ -1683,7 +1690,7 @@ altTab()
           76                          selmon->altTabN = 0; /* reset altTabN */
           77  
           78                  focus(selmon->altsnext[selmon->altTabN]);
           79 -                restack(selmon);
           80 +                /* restack(selmon); */
           81          }
           82  
           83          /* redraw tab */
           84 @@ -1692,8 +1699,64 @@ altTab()
           85  }
           86  
           87  void
           88 +altTabClass()
           89 +{
           90 +        /* move to next window */
           91 +        if (selmon->sel != NULL) {
           92 +                selmon->altTabNc++;
           93 +                if (selmon->altTabNc >= selmon->ncTabs)
           94 +                        selmon->altTabNc = 0; /* reset altTabNc */
           95 +
           96 +                focus(selmon->altsnextclass[selmon->altTabNc]);
           97 +        }
           98 +
           99 +        /* redraw tab */
          100 +        XRaiseWindow(dpy, selmon->tabwin);
          101 +        drawTab(selmon->ncTabs, 0, selmon);
          102 +}
          103 +
          104 +void
          105 +altTabShift()
          106 +{
          107 +        /* move to prev window */
          108 +        if (selmon->sel != NULL) {
          109 +                selmon->altTabN--;
          110 +                if (selmon->altTabN < 0)
          111 +                        selmon->altTabN = selmon->nTabs - 1; /* reset altTabN */
          112 +
          113 +                if (selmon->altsnext[selmon->altTabN]) {
          114 +                        focus(selmon->altsnext[selmon->altTabN]);
          115 +                }
          116 +         }
          117 + 
          118 +        /* redraw tab */
          119 +        XRaiseWindow(dpy, selmon->tabwin);
          120 +        drawTab(selmon->nTabs, 0, selmon);
          121 +}
          122 + 
          123 +void
          124 +altTabShiftClass()
          125 +{
          126 +        /* move to prev window */
          127 +        if (selmon->sel != NULL) {
          128 +                selmon->altTabNc--;
          129 +                if (selmon->altTabNc < 0)
          130 +                        selmon->altTabNc = selmon->ncTabs - 1; /* reset altTabNc */
          131 +
          132 +                if (selmon->altsnextclass[selmon->altTabNc]) {
          133 +                        focus(selmon->altsnextclass[selmon->altTabNc]);
          134 +                }
          135 +        }
          136 +
          137 +        /* redraw tab */
          138 +        XRaiseWindow(dpy, selmon->tabwin);
          139 +        drawTab(selmon->ncTabs, 0, selmon);
          140 +}
          141 +
          142 +void
          143  altTabEnd()
          144  {
          145 +        Client *buff = NULL;
          146          if (selmon->isAlt == 0)
          147                  return;
          148  
          149 @@ -1703,8 +1766,15 @@ altTabEnd()
          150          * so they remain in right order for the next time that alt-tab is used
          151          */
          152          if (selmon->nTabs > 1) {
          153 -                if (selmon->altTabN != 0) { /* if user picked original client do nothing */
          154 -                        Client *buff = selmon->altsnext[selmon->altTabN];
          155 +                if (selmon->altTabN != 0)
          156 +                        buff = selmon->altsnext[selmon->altTabN];
          157 +                else if (selmon->altTabNc != 0) {
          158 +                        buff = selmon->altsnextclass[selmon->altTabNc];
          159 +                        for (; selmon->altTabN < selmon->nTabs; selmon->altTabN++)
          160 +                                if (selmon->altsnext[selmon->altTabN] == selmon->altsnextclass[selmon->altTabNc])
          161 +                                        break;
          162 +                }
          163 +                if (buff) { /* if user picked original client do nothing */
          164                          if (selmon->altTabN > 1)
          165                                  for (int i = selmon->altTabN;i > 0;i--)
          166                                          selmon->altsnext[i] = selmon->altsnext[i - 1];
          167 @@ -1720,6 +1790,7 @@ altTabEnd()
          168                  }
          169  
          170                  free(selmon->altsnext); /* free list of clients */
          171 +                free(selmon->altsnextclass); /* free list of clients */
          172          }
          173  
          174          /* turn off/destroy the window */
          175 @@ -1779,16 +1850,17 @@ drawTab(int nwins, int first, Monitor *m
          176  
          177          }
          178  
          179 -        h = selmon->maxHTab  / m->nTabs;
          180 +        h = selmon->maxHTab / nwins;
          181  
          182          int y = 0;
          183 -        int n = 0;
          184 -        for (int i = 0;i < m->nTabs;i++) { /* draw all clients into tabwin */
          185 -                c = m->altsnext[i];
          186 +        for (int i = 0; i < nwins; i++) { /* draw all clients into tabwin */
          187 +                if (nwins == m->nTabs)
          188 +                        c = m->altsnext[i];
          189 +                else
          190 +                        c = m->altsnextclass[i];
          191                  if(!ISVISIBLE(c)) continue;
          192                  /* if (HIDDEN(c)) continue; uncomment if you're using awesomebar patch */
          193  
          194 -                n++;
          195                  drw_setscheme(drw, scheme[(c == m->sel) ? SchemeSel : SchemeNorm]);
          196                  drw_text(drw, 0, y, selmon->maxWTab, h, 0, c->name, 0);
          197                  y += h;
          198 @@ -1801,7 +1873,6 @@ drawTab(int nwins, int first, Monitor *m
          199  void
          200  altTabStart(const Arg *arg)
          201  {
          202 -        selmon->altsnext = NULL;
          203          if (selmon->tabwin)
          204                  altTabEnd();
          205  
          206 @@ -1810,30 +1881,47 @@ altTabStart(const Arg *arg)
          207          } else {
          208                  selmon->isAlt = 1;
          209                  selmon->altTabN = 0;
          210 +                selmon->altTabNc = 0;
          211  
          212                  Client *c;
          213                  Monitor *m = selmon;
          214  
          215 +                char tempclass[256] = {'\0'};
          216 +                if (selmon->sel)
          217 +                        strncpy(tempclass, selmon->sel->class, 256);
          218 +
          219                  m->nTabs = 0;
          220 +                m->ncTabs = 0;
          221                  for(c = m->clients; c; c = c->next) { /* count clients */
          222                          if(!ISVISIBLE(c)) continue;
          223                          /* if (HIDDEN(c)) continue; uncomment if you're using awesomebar patch */
          224  
          225                          ++m->nTabs;
          226 +
          227 +                        if (!strcmp(c->class, tempclass))
          228 +                                ++m->ncTabs;
          229                  }
          230  
          231                  if (m->nTabs > 0) {
          232                          m->altsnext = (Client **) malloc(m->nTabs * sizeof(Client *));
          233 +                        m->altsnextclass = (Client **) malloc(m->ncTabs * sizeof(Client *));
          234  
          235                          int listIndex = 0;
          236 +                        int listIndexc = 0;
          237                          for(c = m->stack; c; c = c->snext) { /* add clients to the list */
          238                                  if(!ISVISIBLE(c)) continue;
          239                                  /* if (HIDDEN(c)) continue; uncomment if you're using awesomebar patch */
          240  
          241                                  m->altsnext[listIndex++] = c;
          242 +
          243 +                                if (!strcmp(c->class, tempclass))
          244 +                                        m->altsnextclass[listIndexc++] = c;
          245                          }
          246  
          247 -                        drawTab(m->nTabs, 1, m);
          248 +                        if (arg->i)
          249 +                                drawTab(m->nTabs, 1, m);
          250 +                        else
          251 +                                drawTab(m->ncTabs, 1, m);
          252  
          253                          struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 };
          254  
          255 @@ -1848,7 +1936,10 @@ altTabStart(const Arg *arg)
          256                          }
          257  
          258                          XEvent event;
          259 -                        altTab();
          260 +                        if (arg->i)
          261 +                                altTab();
          262 +                        else
          263 +                                altTabClass();
          264                          if (grabbed == 0) {
          265                                  altTabEnd();
          266                          } else {
          267 @@ -1858,8 +1949,19 @@ altTabStart(const Arg *arg)
          268                                                  if (event.type == KeyRelease && event.xkey.keycode == tabModKey) { /* if super key is released break cycle */
          269                                                          break;
          270                                                  } else if (event.type == KeyPress) {
          271 -                                                        if (event.xkey.keycode == tabCycleKey) {/* if XK_s is pressed move to the next window */
          272 -                                                                altTab();
          273 +                                                        if (event.xkey.keycode == tabCycleKey || event.xkey.keycode == tabCycleKey2 ) { /* if XK_s is pressed move to the next window */
          274 +                                                                if (arg->i) {
          275 +                                                                        if (CLEANMASK((Mod1Mask|ShiftMask)) == CLEANMASK(event.xkey.state))
          276 +                                                                                altTabShift();
          277 +                                                                        else
          278 +                                                                                altTab();
          279 +                                                                } else {
          280 +                                                                        if (CLEANMASK((Mod1Mask|ShiftMask)) == CLEANMASK(event.xkey.state))
          281 +                                                                                altTabShiftClass();
          282 +                                                                        else
          283 +                                                                                altTabClass();
          284 +                                                                }
          285 +                                                                
          286                                                          }
          287                                                  }
          288                                          }
          289 @@ -2231,6 +2333,15 @@ updatetitle(Client *c)
          290                  strcpy(c->name, broken);
          291  }
          292  
          293 +void
          294 +getclassname(Client *c)
          295 +{
          296 +        gettextprop(c->win, XA_WM_CLASS, c->class, sizeof c->class);
          297 +
          298 +        if (c->class[0] == '\0') /* hack to mark broken clients */
          299 +                strcpy(c->name, broken);
          300 +}
          301 +
          302  void
          303  updatewindowtype(Client *c)
          304  {