]> Skullheadx's Git Forge - dwm.git/commitdiff
scratchpad
authorSkullheadx <admonty1@protonmail.com>
Fri, 1 May 2026 13:39:43 +0000 (09:39 -0400)
committerSkullheadx <admonty1@protonmail.com>
Fri, 1 May 2026 13:45:53 +0000 (09:45 -0400)
config.def.h
config.h
dwm.c

index 5111a85d0e3d3daa6b76e33bc83a04e9361c889d..1b850dbf344fc4fc5b8737f039b1f1d08e10e3ac 100644 (file)
@@ -96,6 +96,9 @@ static const 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 */
index b6d986809d6417475018d378d7d547dd90b1620e..4395dcac1bf4f9c0ecc2b9ff834cf516bdddc328 100644 (file)
--- a/config.h
+++ b/config.h
@@ -96,6 +96,9 @@ static const 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 ab3a84c007fd68b9a8db620256971cd1c82e92de..884b79e3e65ca8c32e6de109f0799544ac0f1019 100644 (file)
--- a/dwm.c
+++ b/dwm.c
@@ -194,6 +194,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);
@@ -267,11 +273,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
@@ -307,7 +317,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
@@ -1417,6 +1428,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)
 {