commit a7c5786dcf8437c86a29241df1c0606178adf15b
parent b3202c9201d49aa6038ffb8c6fa4569a67920a29
Author: GasparVardanyan <gaspar.vardanyan.mailbox@gmail.com>
Date: Tue, 29 Jun 2021 23:35:06 +0400
apply the dynamicscratchpads patch for dwm
Diffstat:
2 files changed, 193 insertions(+), 0 deletions(-)
diff --git a/dwm.suckless.org/patches/dynamicscratchpads/dwm-scratchpad-20200727-bb2e7222baeec7776930354d0e9f210cc2aaad5f.diff b/dwm.suckless.org/patches/dynamicscratchpads/dwm-scratchpad-20200727-bb2e7222baeec7776930354d0e9f210cc2aaad5f.diff
@@ -0,0 +1,166 @@
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..48cf601 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -94,6 +94,9 @@ static Key keys[] = {
+ TAGKEYS( XK_8, 7)
+ TAGKEYS( XK_9, 8)
+ { MODKEY|ShiftMask, XK_q, quit, {0} },
++ { MODKEY, XK_minus, scratchpad_show, {0} },
++ { MODKEY|ShiftMask, XK_minus, scratchpad_hide, {0} },
++ { MODKEY, XK_equal,scratchpad_remove,{0} },
+ };
+
+ /* button definitions */
+diff --git a/dwm.c b/dwm.c
+index 9fd0286..c647493 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -195,6 +195,12 @@ static void resizemouse(const Arg *arg);
+ static void restack(Monitor *m);
+ static void run(void);
+ static void scan(void);
++static void scratchpad_hide ();
++static _Bool scratchpad_last_showed_is_killed (void);
++static void scratchpad_remove ();
++static void scratchpad_show ();
++static void scratchpad_show_client (Client * c);
++static void scratchpad_show_first (void);
+ static int sendevent(Client *c, Atom proto);
+ static void sendmon(Client *c, Monitor *m);
+ static void setclientstate(Client *c, long state);
+@@ -269,11 +275,15 @@ static Drw *drw;
+ static Monitor *mons, *selmon;
+ static Window root, wmcheckwin;
+
++/* scratchpad */
++# define SCRATCHPAD_MASK (1u << sizeof tags / sizeof * tags)
++static Client * scratchpad_last_showed = NULL;
++
+ /* configuration, allows nested code to access above variables */
+ #include "config.h"
+
+ /* compile-time check if all tags fit into an unsigned int bit array. */
+-struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
++struct NumTags { char limitexceeded[LENGTH(tags) > 30 ? -1 : 1]; };
+
+ /* function implementations */
+ void
+@@ -309,7 +319,8 @@ applyrules(Client *c)
+ XFree(ch.res_class);
+ if (ch.res_name)
+ XFree(ch.res_name);
+- c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags];
++ if (c->tags != SCRATCHPAD_MASK)
++ c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags];
+ }
+
+ int
+@@ -1408,6 +1419,98 @@ scan(void)
+ }
+ }
+
++static void scratchpad_hide ()
++{
++ if (selmon -> sel)
++ {
++ selmon -> sel -> tags = SCRATCHPAD_MASK;
++ selmon -> sel -> isfloating = 1;
++ focus(NULL);
++ arrange(selmon);
++ }
++}
++
++static _Bool scratchpad_last_showed_is_killed (void)
++{
++ _Bool killed = 1;
++ for (Client * c = selmon -> clients; c != NULL; c = c -> next)
++ {
++ if (c == scratchpad_last_showed)
++ {
++ killed = 0;
++ break;
++ }
++ }
++ return killed;
++}
++
++static void scratchpad_remove ()
++{
++ if (selmon -> sel && scratchpad_last_showed != NULL && selmon -> sel == scratchpad_last_showed)
++ scratchpad_last_showed = NULL;
++}
++
++static void scratchpad_show ()
++{
++ if (scratchpad_last_showed == NULL || scratchpad_last_showed_is_killed ())
++ scratchpad_show_first ();
++ else
++ {
++ if (scratchpad_last_showed -> tags != SCRATCHPAD_MASK)
++ {
++ scratchpad_last_showed -> tags = SCRATCHPAD_MASK;
++ focus(NULL);
++ arrange(selmon);
++ }
++ else
++ {
++ _Bool found_current = 0;
++ _Bool found_next = 0;
++ for (Client * c = selmon -> clients; c != NULL; c = c -> next)
++ {
++ if (found_current == 0)
++ {
++ if (c == scratchpad_last_showed)
++ {
++ found_current = 1;
++ continue;
++ }
++ }
++ else
++ {
++ if (c -> tags == SCRATCHPAD_MASK)
++ {
++ found_next = 1;
++ scratchpad_show_client (c);
++ break;
++ }
++ }
++ }
++ if (found_next == 0) scratchpad_show_first ();
++ }
++ }
++}
++
++static void scratchpad_show_client (Client * c)
++{
++ scratchpad_last_showed = c;
++ c -> tags = selmon->tagset[selmon->seltags];
++ focus(c);
++ arrange(selmon);
++}
++
++static void scratchpad_show_first (void)
++{
++ for (Client * c = selmon -> clients; c != NULL; c = c -> next)
++ {
++ if (c -> tags == SCRATCHPAD_MASK)
++ {
++ scratchpad_show_client (c);
++ break;
++ }
++ }
++}
++
+ void
+ sendmon(Client *c, Monitor *m)
+ {
+@@ -1781,6 +1884,8 @@ unmanage(Client *c, int destroyed)
+ XSetErrorHandler(xerror);
+ XUngrabServer(dpy);
+ }
++ if (scratchpad_last_showed == c)
++ scratchpad_last_showed = NULL;
+ free(c);
+ focus(NULL);
+ updateclientlist();
diff --git a/dwm.suckless.org/patches/dynamicscratchpads/index.md b/dwm.suckless.org/patches/dynamicscratchpads/index.md
@@ -0,0 +1,27 @@
+dynamicscratchpads
+==================
+
+Description
+-----------
+More i3-like behaviour. Allows for the management of scratchpad windows dynamically. You can hide, show (cycle through) and remove any window from scratchpad without specifying them in the config.h.
+
+There are just three keybindings to manage the scratchpad:
+* Move selected window to scratchpad
+* Remove selected window from scratchpad
+* Restore sequential window from scratchpad
+
+You also can create rules to start specific windows in scratchpad.
+
+Doesn't conflict with the [namedscratchpads](../namedscratchpads/) patch.
+
+Contribution
+------------
+You can create issues and do pull requests on [this github repo](https://github.com/GasparVardanyan/dwm-scratchpad).
+
+Download
+--------
+* [dwm-scratchpad-20200727-bb2e7222baeec7776930354d0e9f210cc2aaad5f.diff](dwm-scratchpad-20200727-bb2e7222baeec7776930354d0e9f210cc2aaad5f.diff)
+
+Author
+------
+* [Gaspar Vardanyan](https://github.com/GasparVardanyan)