sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

commit add833f448f1a7089e27257f0caee7127abf95df
parent f5618f1c4ad679952c078b4b8e4b7a15e19e41a1
Author: Akqyu <akqhybt@gmail.com>
Date:   Fri, 18 Aug 2023 10:08:28 +0400

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

Diffstat:
Adwm.suckless.org/patches/alt-tab-class/dwm-alttabclass-6.4.diff | 304+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/alt-tab-class/index.md | 31+++++++++++++++++++++++++++++++
2 files changed, 335 insertions(+), 0 deletions(-)

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 @@ -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] = {'\0'}; ++ 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] == '\0') /* hack to mark broken clients */ ++ 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 @@ -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 - akqhybt@gmail.com + + +Acknowledgements +---------------- +Thanks to Viliam Kováč for alt-tab patch which has most of the difficult part +already taken care of.