diff options
author | Joe <rbo@gmx.us> | 2024-12-30 11:51:45 +0100 |
---|---|---|
committer | Joe <rbo@gmx.us> | 2024-12-30 11:51:45 +0100 |
commit | c4f95544c1f6d84ab489d49d96280e05f125adf7 (patch) | |
tree | 8daf3ccf65525376de598c2690dc4faa0deb8bab | |
parent | applied underline tags (diff) | |
download | dwm-c4f95544c1f6d84ab489d49d96280e05f125adf7.tar.gz dwm-c4f95544c1f6d84ab489d49d96280e05f125adf7.tar.bz2 dwm-c4f95544c1f6d84ab489d49d96280e05f125adf7.tar.xz dwm-c4f95544c1f6d84ab489d49d96280e05f125adf7.tar.zst dwm-c4f95544c1f6d84ab489d49d96280e05f125adf7.zip |
its a start
-rw-r--r-- | config.def.h | 4 | ||||
-rw-r--r-- | dwm-shif-tools-6.2.diff | 198 | ||||
-rw-r--r-- | dwm.c | 68 |
3 files changed, 269 insertions, 1 deletions
diff --git a/config.def.h b/config.def.h index ed736ea..0097501 100644 --- a/config.def.h +++ b/config.def.h @@ -281,6 +281,10 @@ static const Key keys[] = { { MODKEY, XK_minus, setgaps, {.i = -1 } }, { MODKEY, XK_equal, setgaps, {.i = +1 } }, { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } }, + { MODKEY|ControlMask, XK_h, shiftview, { .i = -1 } }, + { MODKEY|ControlMask, XK_l, shiftview, { .i = +1 } }, + { MODKEY|METAKEY, XK_h, shiftboth, { .i = -1 } }, + { MODKEY|METAKEY, XK_l, shiftboth, { .i = +1 } }, TAGKEYS( XK_1, 0) TAGKEYS( XK_2, 1) TAGKEYS( XK_3, 2) diff --git a/dwm-shif-tools-6.2.diff b/dwm-shif-tools-6.2.diff new file mode 100644 index 0000000..4535342 --- /dev/null +++ b/dwm-shif-tools-6.2.diff @@ -0,0 +1,198 @@ +From d57c8508c9f26be40667d402a2daaa2b27ae759f Mon Sep 17 00:00:00 2001 +From: explosion-mental <explosion0mental@gmail.com> +Date: Wed, 11 Aug 2021 21:05:44 -0500 +Subject: [PATCH] shift-tools - shifttag, moves the current selected client to + the adjacent tag - shifttagclients, moves the current selected client to the + adjacent tag that has at least one client else acts as shifttag - + shiftview, view adjacent tag - shiftviewclients, view the closes tag that has + a client. If none acts as shiftview - shiftboth, shifttag and shiftview. + Basically moves the window to the next/prev tag and follows it. - + shiftswaptags, its a shift implementation on the swaptags function (see + https://github.com/moizifty/DWM-Build/blob/65379c62640788881486401a0d8c79333751b02f/config.h#L48 + for more details), which in short 'swaps tags' (swaps all clients with + the clients on the adjacent tag). A pretty useful example of this is + chosing a tag empty and sending all your clients to that tag. - swapfunction + is the 'helper' function for the shiftswaptags. remember that these functions + **shift**, which means you can go from tag 1 to 9 or 9 to 1. Also remember + that the default argument is 1 and you can change it. + +--- + config.def.h | 9 ++++ + shift-tools.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 144 insertions(+) + create mode 100644 shift-tools.c + +diff --git a/config.def.h b/config.def.h +index 1c0b587..1390d17 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -58,9 +58,14 @@ static const Layout layouts[] = { + static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ + static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; + static const char *termcmd[] = { "st", NULL }; ++#include "shift-tools.c" + + static Key keys[] = { + /* modifier key function argument */ ++ { MODKEY, XK_o, shiftviewclients, { .i = +1 } }, ++ { MODKEY|ShiftMask, XK_o, shiftview, { .i = +1 } }, ++ { MODKEY|ShiftMask, XK_i, shiftview, { .i = -1 } }, ++ { MODKEY, XK_i, shiftviewclients, { .i = -1 } }, + { MODKEY, XK_p, spawn, {.v = dmenucmd } }, + { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, + { MODKEY, XK_b, togglebar, {0} }, +@@ -69,6 +74,10 @@ static Key keys[] = { + { MODKEY, XK_i, incnmaster, {.i = +1 } }, + { MODKEY, XK_d, incnmaster, {.i = -1 } }, + { MODKEY, XK_h, setmfact, {.f = -0.05} }, ++ { MODKEY|ShiftMask, XK_h, shiftboth, { .i = -1 } }, ++ { MODKEY|ControlMask, XK_h, shiftswaptags, { .i = -1 } }, ++ { MODKEY|ControlMask, XK_l, shiftswaptags, { .i = +1 } }, ++ { MODKEY|ShiftMask, XK_l, shiftboth, { .i = +1 } }, + { MODKEY, XK_l, setmfact, {.f = +0.05} }, + { MODKEY, XK_Return, zoom, {0} }, + { MODKEY, XK_Tab, view, {0} }, +diff --git a/shift-tools.c b/shift-tools.c +new file mode 100644 +index 0000000..cf130c8 +--- /dev/null ++++ b/shift-tools.c +@@ -0,0 +1,135 @@ ++/* Sends a window to the next/prev tag */ ++void ++shifttag(const Arg *arg) ++{ ++ Arg shifted; ++ shifted.ui = selmon->tagset[selmon->seltags]; ++ ++ ++ if (arg->i > 0) /* left circular shift */ ++ shifted.ui = ((shifted.ui << arg->i) | (shifted.ui >> (LENGTH(tags) - arg->i))); ++ else /* right circular shift */ ++ shifted.ui = (shifted.ui >> (- arg->i) | shifted.ui << (LENGTH(tags) + arg->i)); ++ tag(&shifted); ++} ++/* Sends a window to the next/prev tag that has a client, else it moves it to the next/prev one. */ ++void ++shifttagclients(const Arg *arg) ++{ ++ ++ Arg shifted; ++ Client *c; ++ unsigned int tagmask = 0; ++ shifted.ui = selmon->tagset[selmon->seltags]; ++ ++ for (c = selmon->clients; c; c = c->next) ++ if (!(c->tags)) ++ tagmask = tagmask | c->tags; ++ ++ ++ if (arg->i > 0) /* left circular shift */ ++ do { ++ shifted.ui = (shifted.ui << arg->i) ++ | (shifted.ui >> (LENGTH(tags) - arg->i)); ++ } while (tagmask && !(shifted.ui & tagmask)); ++ else /* right circular shift */ ++ do { ++ shifted.ui = (shifted.ui >> (- arg->i) ++ | shifted.ui << (LENGTH(tags) + arg->i)); ++ } while (tagmask && !(shifted.ui & tagmask)); ++ tag(&shifted); ++} ++/* Navigate to the next/prev tag */ ++void ++shiftview(const Arg *arg) ++{ ++ Arg shifted; ++ shifted.ui = selmon->tagset[selmon->seltags]; ++ ++ if (arg->i > 0) /* left circular shift */ ++ shifted.ui = (shifted.ui << arg->i) | (shifted.ui >> (LENGTH(tags) - arg->i)); ++ else /* right circular shift */ ++ shifted.ui = (shifted.ui >> (- arg->i) | shifted.ui << (LENGTH(tags) + arg->i)); ++ view(&shifted); ++} ++/* Navigate to the next/prev tag that has a client, else moves it to the next/prev tag */ ++void ++shiftviewclients(const Arg *arg) ++{ ++ Arg shifted; ++ Client *c; ++ unsigned int tagmask = 0; ++ shifted.ui = selmon->tagset[selmon->seltags]; ++ ++ for (c = selmon->clients; c; c = c->next) ++ if (!(c->tags)) ++ tagmask = tagmask | c->tags; ++ ++ ++ if (arg->i > 0) /* left circular shift */ ++ do { ++ shifted.ui = (shifted.ui << arg->i) ++ | (shifted.ui >> (LENGTH(tags) - arg->i)); ++ } while (tagmask && !(shifted.ui & tagmask)); ++ else /* right circular shift */ ++ do { ++ shifted.ui = (shifted.ui >> (- arg->i) ++ | shifted.ui << (LENGTH(tags) + arg->i)); ++ } while (tagmask && !(shifted.ui & tagmask)); ++ view(&shifted); ++} ++/* move the current active window to the next/prev tag and view it. More like following the window */ ++void ++shiftboth(const Arg *arg) ++{ ++ Arg shifted; ++ shifted.ui = selmon->tagset[selmon->seltags]; ++ ++ if (arg->i > 0) /* left circular shift */ ++ shifted.ui = ((shifted.ui << arg->i) | (shifted.ui >> (LENGTH(tags) - arg->i))); ++ else /* right circular shift */ ++ shifted.ui = ((shifted.ui >> (- arg->i) | shifted.ui << (LENGTH(tags) + arg->i))); ++ tag(&shifted); ++ view(&shifted); ++} ++//helper function for shiftswaptags. ++//see: https://github.com/moizifty/DWM-Build/blob/65379c62640788881486401a0d8c79333751b02f/config.h#L48 ++void ++swaptags(const Arg *arg) ++{ ++ Client *c; ++ unsigned int newtag = arg->ui & TAGMASK; ++ unsigned int curtag = selmon->tagset[selmon->seltags]; ++ ++ if (newtag == curtag || !curtag || (curtag & (curtag-1))) ++ return; ++ ++ for (c = selmon->clients; c != NULL; c = c->next) { ++ if ((c->tags & newtag) || (c->tags & curtag)) ++ c->tags ^= curtag ^ newtag; ++ ++ if (!c->tags) ++ c->tags = newtag; ++ } ++ ++ //move to the swaped tag ++ //selmon->tagset[selmon->seltags] = newtag; ++ ++ focus(NULL); ++ arrange(selmon); ++} ++/* swaps "tags" (all the clients) with the next/prev tag. */ ++void ++shiftswaptags(const Arg *arg) ++{ ++ Arg shifted; ++ shifted.ui = selmon->tagset[selmon->seltags]; ++ ++ if (arg->i > 0) /* left circular shift */ ++ shifted.ui = ((shifted.ui << arg->i) | (shifted.ui >> (LENGTH(tags) - arg->i))); ++ else /* right circular shift */ ++ shifted.ui = ((shifted.ui >> (- arg->i) | shifted.ui << (LENGTH(tags) + arg->i))); ++ swaptags(&shifted); ++ // uncomment if you also want to "go" (view) the tag where the the clients are going ++ //view(&shifted); ++} +-- +2.32.0 + @@ -85,7 +85,7 @@ enum { SchemeNorm, SchemeSel }; /* color schemes */ enum { NetSupported, NetWMName, NetWMState, NetWMCheck, NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz, NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ + NetWMWindowTypeDialog, NetClientList, NetClientInfo, NetLast }; /* EWMH atoms */ enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */ enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ enum { ClkTagBar, ClkLtSymbol, ClkStatusText, @@ -252,6 +252,7 @@ static void scan(void); static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4); static void sendmon(Client *c, Monitor *m); static void setclientstate(Client *c, long state); +static void setclienttagprop(Client *c); static void setfocus(Client *c); static void setfullscreen(Client *c, int fullscreen); static void setgaps(const Arg *arg); @@ -259,6 +260,8 @@ static void setlayout(const Arg *arg); static void setmfact(const Arg *arg); static void setup(void); static void seturgent(Client *c, int urg); +static void shiftboth(const Arg *arg); +static void shiftview(const Arg *arg); static void showhide(Client *c); static void sighup(int unused); static void sigterm(int unused); @@ -1626,6 +1629,26 @@ manage(Window w, XWindowAttributes *wa) updatewindowtype(c); updatesizehints(c); updatewmhints(c); + { + int format; + unsigned long *data, n, extra; + Monitor *m; + Atom atom; + if (XGetWindowProperty(dpy, c->win, netatom[NetClientInfo], 0L, 2L, False, XA_CARDINAL, + &atom, &format, &n, &extra, (unsigned char **)&data) == Success && n == 2) { + c->tags = *data; + for (m = mons; m; m = m->next) { + if (m->num == *(data+1)) { + c->mon = m; + break; + } + } + } + if (n > 0) + XFree(data); + } + setclienttagprop(c); + c->x = c->mon->mx + (c->mon->mw - WIDTH(c)) / 2; c->y = c->mon->my + (c->mon->mh - HEIGHT(c)) / 2; c->sfx = c->x; @@ -2330,6 +2353,7 @@ sendmon(Client *c, Monitor *m) c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ attachBelow(c); attachstack(c); + setclienttagprop(c); focus(NULL); arrange(NULL); } @@ -2508,6 +2532,7 @@ setup(void) netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); + netatom[NetClientInfo] = XInternAtom(dpy, "_NET_CLIENT_INFO", False); xatom[Manager] = XInternAtom(dpy, "MANAGER", False); xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False); xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False); @@ -2542,6 +2567,7 @@ setup(void) XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32, PropModeReplace, (unsigned char *) netatom, NetLast); XDeleteProperty(dpy, root, netatom[NetClientList]); + XDeleteProperty(dpy, root, netatom[NetClientInfo]); /* select events */ wa.cursor = cursor[CurNormal]->cursor; wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask @@ -2567,6 +2593,33 @@ seturgent(Client *c, int urg) } void +shiftboth(const Arg *arg) +{ + Arg shifted; + shifted.ui = selmon->tagset[selmon->seltags]; + + if (arg->i > 0) /* left circular shift */ + shifted.ui = ((shifted.ui << arg->i) | (shifted.ui >> (LENGTH(tags) - arg->i))); + else /* right circular shift */ + shifted.ui = ((shifted.ui >> (- arg->i) | shifted.ui << (LENGTH(tags) + arg->i))); + tag(&shifted); + view(&shifted); +} + +void +shiftview(const Arg *arg) +{ + Arg shifted; + shifted.ui = selmon->tagset[selmon->seltags]; + + if (arg->i > 0) /* left circular shift */ + shifted.ui = (shifted.ui << arg->i) | (shifted.ui >> (LENGTH(tags) - arg->i)); + else /* right circular shift */ + shifted.ui = (shifted.ui >> (- arg->i) | shifted.ui << (LENGTH(tags) + arg->i)); + view(&shifted); +} + +void showhide(Client *c) { if (!c) @@ -2681,12 +2734,23 @@ spawn(const Arg *arg) die("dwm: execvp '%s' failed:", ((char **)arg->v)[0]); } } +void +setclienttagprop(Client *c) +{ + long data[] = { (long) c->tags, (long) c->mon->num }; + XChangeProperty(dpy, c->win, netatom[NetClientInfo], XA_CARDINAL, 32, + PropModeReplace, (unsigned char *) data, 2); +} void tag(const Arg *arg) { + Client *c; + if (selmon->sel && arg->ui & TAGMASK) { + c = selmon->sel; selmon->sel->tags = arg->ui & TAGMASK; + setclienttagprop(c); focus(NULL); arrange(selmon); } @@ -2725,6 +2789,7 @@ tagothermon(const Arg *arg, int dir) sendmon(sel, newmon); if (arg->ui & TAGMASK) { sel->tags = arg->ui & TAGMASK; + setclienttagprop(selmon->sel); focus(NULL); arrange(newmon); } @@ -2866,6 +2931,7 @@ toggletag(const Arg *arg) newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); if (newtags) { selmon->sel->tags = newtags; + setclienttagprop(selmon->sel); focus(NULL); arrange(selmon); } |