commit add833f448f1a7089e27257f0caee7127abf95df
Author: Akqyu <[email protected]>
Date:   Fri Aug 18 10:08:28 2023 +0400

    [dwm][patch][alt-tab-class] adding alt-tab patch for same class windows

diff --git a/dwm.suckless.org/patches/alt-tab-class/dwm-alttabclass-6.4.diff 
b/dwm.suckless.org/patches/alt-tab-class/dwm-alttabclass-6.4.diff
new file mode 100644
index 00000000..0236de47
--- /dev/null
+++ b/dwm.suckless.org/patches/alt-tab-class/dwm-alttabclass-6.4.diff
@@ -0,0 +1,304 @@
+diff -up a/config.def.h b/config.def.h
+--- a/config.def.h     2023-08-17 17:35:28.333393605 +0400
++++ b/config.def.h     2023-08-17 17:24:46.724435876 +0400
+@@ -3,6 +3,7 @@
+ /* alt-tab configuration */
+ 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 `*/
+ 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 */
++static const unsigned int tabCycleKey2                = 0x31; /* grave key */
+ static const unsigned int tabPosY                     = 1;    /* tab position 
on Y axis, 0 = bottom, 1 = center, 2 = top */
+ static const unsigned int tabPosX                     = 1;    /* tab position 
on X axis, 0 = left, 1 = center, 2 = right */
+ static const unsigned int maxWTab                     = 600;  /* tab menu 
width */
+@@ -93,7 +94,8 @@ static const Key keys[] = {
+       { MODKEY,                       XK_period, focusmon,       {.i = +1 } },
+       { MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } },
+       { MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } },
+-      { Mod1Mask,                             XK_Tab,    altTabStart,    {0} 
},
++      { Mod1Mask,                             XK_Tab,    altTabStart,    {.i 
= 1} },
++      { Mod1Mask,                             XK_grave,  altTabStart,    {.i 
= 0} },
+       TAGKEYS(                        XK_1,                      0)
+       TAGKEYS(                        XK_2,                      1)
+       TAGKEYS(                        XK_3,                      2)
+diff -up a/dwm.c b/dwm.c
+--- a/dwm.c    2023-08-17 17:24:19.753640383 +0400
++++ b/dwm.c    2023-08-18 09:41:00.834187121 +0400
+@@ -87,6 +87,7 @@ typedef struct Monitor Monitor;
+ typedef struct Client Client;
+ struct Client {
+       char name[256];
++      char class[256];
+       float mina, maxa;
+       int x, y, w, h;
+       int oldx, oldy, oldw, oldh;
+@@ -121,7 +122,9 @@ struct Monitor {
+       int mx, my, mw, mh;   /* screen size */
+       int wx, wy, ww, wh;   /* window area  */
+       int altTabN;              /* move that many clients forward */
++      int altTabNc;             /* move that many clients forward when using 
tab for same class */
+       int nTabs;                        /* number of active clients in tag */
++      int ncTabs;                       /* number of active clients under 
same class in tag */
+       int isAlt;                        /* 1,0 */
+       int maxWTab;
+       int maxHTab;
+@@ -134,6 +137,7 @@ struct Monitor {
+       Client *sel;
+       Client *stack;
+       Client ** altsnext; /* array of all clients in the tag */
++      Client ** altsnextclass;        /* array of all clients under same 
class in the tag */
+       Monitor *next;
+       Window barwin;
+       Window tabwin;
+@@ -245,6 +249,7 @@ static void zoom(const Arg *arg);
+ void drawTab(int nwins, int first, Monitor *m);
+ void altTabStart(const Arg *arg);
+ static void altTabEnd();
++static void getclassname(Client *c);
+ 
+ /* variables */
+ static const char broken[] = "broken";
+@@ -657,6 +662,7 @@ createmon(void)
+       m->lt[0] = &layouts[0];
+       m->lt[1] = &layouts[1 % LENGTH(layouts)];
+       m->nTabs = 0;
++      m->ncTabs = 0;
+       strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
+       return m;
+ }
+@@ -1059,6 +1065,7 @@ manage(Window w, XWindowAttributes *wa)
+       c->oldbw = wa->border_width;
+ 
+       updatetitle(c);
++      getclassname(c);
+       if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
+               c->mon = t->mon;
+               c->tags = t->tags;
+@@ -1683,7 +1690,7 @@ altTab()
+                       selmon->altTabN = 0; /* reset altTabN */
+ 
+               focus(selmon->altsnext[selmon->altTabN]);
+-              restack(selmon);
++              /* restack(selmon); */
+       }
+ 
+       /* redraw tab */
+@@ -1692,8 +1699,64 @@ altTab()
+ }
+ 
+ void
++altTabClass()
++{
++      /* move to next window */
++      if (selmon->sel != NULL) {
++              selmon->altTabNc++;
++              if (selmon->altTabNc >= selmon->ncTabs)
++                      selmon->altTabNc = 0; /* reset altTabNc */
++
++              focus(selmon->altsnextclass[selmon->altTabNc]);
++      }
++
++      /* redraw tab */
++      XRaiseWindow(dpy, selmon->tabwin);
++      drawTab(selmon->ncTabs, 0, selmon);
++}
++
++void
++altTabShift()
++{
++      /* move to prev window */
++      if (selmon->sel != NULL) {
++              selmon->altTabN--;
++              if (selmon->altTabN < 0)
++                      selmon->altTabN = selmon->nTabs - 1; /* reset altTabN */
++
++              if (selmon->altsnext[selmon->altTabN]) {
++                      focus(selmon->altsnext[selmon->altTabN]);
++              }
++      }
++ 
++      /* redraw tab */
++      XRaiseWindow(dpy, selmon->tabwin);
++      drawTab(selmon->nTabs, 0, selmon);
++}
++ 
++void
++altTabShiftClass()
++{
++      /* move to prev window */
++      if (selmon->sel != NULL) {
++              selmon->altTabNc--;
++              if (selmon->altTabNc < 0)
++                      selmon->altTabNc = selmon->ncTabs - 1; /* reset 
altTabNc */
++
++              if (selmon->altsnextclass[selmon->altTabNc]) {
++                      focus(selmon->altsnextclass[selmon->altTabNc]);
++              }
++      }
++
++      /* redraw tab */
++      XRaiseWindow(dpy, selmon->tabwin);
++      drawTab(selmon->ncTabs, 0, selmon);
++}
++
++void
+ altTabEnd()
+ {
++      Client *buff = NULL;
+       if (selmon->isAlt == 0)
+               return;
+ 
+@@ -1703,8 +1766,15 @@ altTabEnd()
+       * so they remain in right order for the next time that alt-tab is used
+       */
+       if (selmon->nTabs > 1) {
+-              if (selmon->altTabN != 0) { /* if user picked original client 
do nothing */
+-                      Client *buff = selmon->altsnext[selmon->altTabN];
++              if (selmon->altTabN != 0)
++                      buff = selmon->altsnext[selmon->altTabN];
++              else if (selmon->altTabNc != 0) {
++                      buff = selmon->altsnextclass[selmon->altTabNc];
++                      for (; selmon->altTabN < selmon->nTabs; 
selmon->altTabN++)
++                              if (selmon->altsnext[selmon->altTabN] == 
selmon->altsnextclass[selmon->altTabNc])
++                                      break;
++              }
++              if (buff) { /* if user picked original client do nothing */
+                       if (selmon->altTabN > 1)
+                               for (int i = selmon->altTabN;i > 0;i--)
+                                       selmon->altsnext[i] = 
selmon->altsnext[i - 1];
+@@ -1720,6 +1790,7 @@ altTabEnd()
+               }
+ 
+               free(selmon->altsnext); /* free list of clients */
++              free(selmon->altsnextclass); /* free list of clients */
+       }
+ 
+       /* turn off/destroy the window */
+@@ -1779,16 +1850,17 @@ drawTab(int nwins, int first, Monitor *m
+ 
+       }
+ 
+-      h = selmon->maxHTab  / m->nTabs;
++      h = selmon->maxHTab / nwins;
+ 
+       int y = 0;
+-      int n = 0;
+-      for (int i = 0;i < m->nTabs;i++) { /* draw all clients into tabwin */
+-              c = m->altsnext[i];
++      for (int i = 0; i < nwins; i++) { /* draw all clients into tabwin */
++              if (nwins == m->nTabs)
++                      c = m->altsnext[i];
++              else
++                      c = m->altsnextclass[i];
+               if(!ISVISIBLE(c)) continue;
+               /* if (HIDDEN(c)) continue; uncomment if you're using 
awesomebar patch */
+ 
+-              n++;
+               drw_setscheme(drw, scheme[(c == m->sel) ? SchemeSel : 
SchemeNorm]);
+               drw_text(drw, 0, y, selmon->maxWTab, h, 0, c->name, 0);
+               y += h;
+@@ -1801,7 +1873,6 @@ drawTab(int nwins, int first, Monitor *m
+ void
+ altTabStart(const Arg *arg)
+ {
+-      selmon->altsnext = NULL;
+       if (selmon->tabwin)
+               altTabEnd();
+ 
+@@ -1810,30 +1881,47 @@ altTabStart(const Arg *arg)
+       } else {
+               selmon->isAlt = 1;
+               selmon->altTabN = 0;
++              selmon->altTabNc = 0;
+ 
+               Client *c;
+               Monitor *m = selmon;
+ 
++              char tempclass[256] = {'++              if (selmon->sel)
++                      strncpy(tempclass, selmon->sel->class, 256);
++
+               m->nTabs = 0;
++              m->ncTabs = 0;
+               for(c = m->clients; c; c = c->next) { /* count clients */
+                       if(!ISVISIBLE(c)) continue;
+                       /* if (HIDDEN(c)) continue; uncomment if you're using 
awesomebar patch */
+ 
+                       ++m->nTabs;
++
++                      if (!strcmp(c->class, tempclass))
++                              ++m->ncTabs;
+               }
+ 
+               if (m->nTabs > 0) {
+                       m->altsnext = (Client **) malloc(m->nTabs * 
sizeof(Client *));
++                      m->altsnextclass = (Client **) malloc(m->ncTabs * 
sizeof(Client *));
+ 
+                       int listIndex = 0;
++                      int listIndexc = 0;
+                       for(c = m->stack; c; c = c->snext) { /* add clients to 
the list */
+                               if(!ISVISIBLE(c)) continue;
+                               /* if (HIDDEN(c)) continue; uncomment if you're 
using awesomebar patch */
+ 
+                               m->altsnext[listIndex++] = c;
++
++                              if (!strcmp(c->class, tempclass))
++                                      m->altsnextclass[listIndexc++] = c;
+                       }
+ 
+-                      drawTab(m->nTabs, 1, m);
++                      if (arg->i)
++                              drawTab(m->nTabs, 1, m);
++                      else
++                              drawTab(m->ncTabs, 1, m);
+ 
+                       struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 
};
+ 
+@@ -1848,7 +1936,10 @@ altTabStart(const Arg *arg)
+                       }
+ 
+                       XEvent event;
+-                      altTab();
++                      if (arg->i)
++                              altTab();
++                      else
++                              altTabClass();
+                       if (grabbed == 0) {
+                               altTabEnd();
+                       } else {
+@@ -1858,8 +1949,19 @@ altTabStart(const Arg *arg)
+                                               if (event.type == KeyRelease && 
event.xkey.keycode == tabModKey) { /* if super key is released break cycle */
+                                                       break;
+                                               } else if (event.type == 
KeyPress) {
+-                                                      if (event.xkey.keycode 
== tabCycleKey) {/* if XK_s is pressed move to the next window */
+-                                                              altTab();
++                                                      if (event.xkey.keycode 
== tabCycleKey || event.xkey.keycode == tabCycleKey2 ) { /* if XK_s is pressed 
move to the next window */
++                                                              if (arg->i) {
++                                                                      if 
(CLEANMASK((Mod1Mask|ShiftMask)) == CLEANMASK(event.xkey.state))
++                                                                              
altTabShift();
++                                                                      else
++                                                                              
altTab();
++                                                              } else {
++                                                                      if 
(CLEANMASK((Mod1Mask|ShiftMask)) == CLEANMASK(event.xkey.state))
++                                                                              
altTabShiftClass();
++                                                                      else
++                                                                              
altTabClass();
++                                                              }
++                                                              
+                                                       }
+                                               }
+                                       }
+@@ -2231,6 +2333,15 @@ updatetitle(Client *c)
+               strcpy(c->name, broken);
+ }
+ 
++void
++getclassname(Client *c)
++{
++      gettextprop(c->win, XA_WM_CLASS, c->class, sizeof c->class);
++
++      if (c->class[0] == '++          strcpy(c->name, broken);
++}
++
+ void
+ updatewindowtype(Client *c)
+ {
diff --git a/dwm.suckless.org/patches/alt-tab-class/index.md 
b/dwm.suckless.org/patches/alt-tab-class/index.md
new file mode 100644
index 00000000..9b394645
--- /dev/null
+++ b/dwm.suckless.org/patches/alt-tab-class/index.md
@@ -0,0 +1,31 @@
+Alt-tab for same class windows
+==============================
+
+
+Description
+-----------
+
+This patch is a modifications on alt-tab patch that enables alt-tabbing windows
+of the same class. Apply first [alt-tab](../alt-tab) patch to use this. Also 
another feature
+is enabling reverse alt-tab when holding `Shift` key.
+
+
+Configuration Options
+---------------------
+* `tabCycleKey2` - Set this to a key that you want for class alt-tab. By 
default it's set to `grave` key.
+
+
+Download
+--------
+* [dwm-alttabclass-6.4.diff](dwm-alttabclass-6.4.diff)
+
+
+Authors
+-------
+* Akqyu - [email protected]
+
+
+Acknowledgements
+----------------
+Thanks to Viliam Kováč for alt-tab patch which has most of the difficult part
+already taken care of.


Reply via email to