summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config.def.h3
-rw-r--r--config.h3
-rw-r--r--dwm.c107
3 files changed, 111 insertions, 2 deletions
diff --git a/config.def.h b/config.def.h
index 5111a85..1b850db 100644
--- a/config.def.h
+++ b/config.def.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/config.h b/config.h
index b6d9868..4395dca 100644
--- 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 ab3a84c..884b79e 100644
--- 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)
{