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 */
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 */
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);
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
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
}
}
+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)
{