aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Leonhardt <equinox.salexander@gmail.com>
2026-09-05 13:27:35 +0200
committerAlexander Leonhardt <equinox.salexander@gmail.com>
2026-09-05 13:27:35 +0200
commit991e8641545c0544372389d0cb6b1a37cef8517f (patch)
treea56c4caa5caac19b4efbf9b43fdfb11d86780bd3
parent25de10088e31304b154e3ff5c64da945f2e4bf3d (diff)
parent598aa153a47d8e4fd5d8f6cbf4c44725d90b145f (diff)
downloaddwl-991e8641545c0544372389d0cb6b1a37cef8517f.tar.gz
dwl-991e8641545c0544372389d0cb6b1a37cef8517f.tar.bz2
dwl-991e8641545c0544372389d0cb6b1a37cef8517f.zip
Merge branch 'scratchpad' into merged
-rw-r--r--config.def.h4
-rw-r--r--dwl.c42
-rw-r--r--simple_scratchpad.c101
3 files changed, 145 insertions, 2 deletions
diff --git a/config.def.h b/config.def.h
index 2e00524..55a0130 100644
--- a/config.def.h
+++ b/config.def.h
@@ -25,6 +25,7 @@ static uint32_t colors[][3] = {
[SchemeTitle] = { 0x00CCEEff, 0x222222ff, 0x770000ff },
};
+#define SCRATCHPAD_COUNT 1
/* tagging - TAGCOUNT must be no greater than 31 */
/* tagging */
static char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
@@ -151,6 +152,9 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_Return, zoom, {0} },
{ MODKEY, XKB_KEY_Tab, view, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_c, killclient, {0} },
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_z, addscratchpad, {0} },
+ { MODKEY, XKB_KEY_z, togglescratchpad, {0} },
+ { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_z, removescratchpad, {0} },
{ MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} },
{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
{ MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
diff --git a/dwl.c b/dwl.c
index 1ad95e5..6136fa4 100644
--- a/dwl.c
+++ b/dwl.c
@@ -151,6 +151,7 @@ typedef struct {
uint32_t tags;
int isfloating, isurgent, isfullscreen, neverdim;
uint32_t resize; /* configure serial of a pending resize */
+ struct wl_list link_temp;
} Client;
typedef struct {
@@ -277,6 +278,7 @@ typedef struct {
} Menu;
/* function declarations */
+static void addscratchpad(const Arg *arg);
static void applybounds(Client *c, struct wlr_box *bbox);
static void applyrules(Client *c);
static void arrange(Monitor *m);
@@ -365,6 +367,7 @@ static void pointerfocus(Client *c, struct wlr_surface *surface,
static void powermgrsetmode(struct wl_listener *listener, void *data);
static void quit(const Arg *arg);
static void rendermon(struct wl_listener *listener, void *data);
+static void removescratchpad(const Arg *arg);
static void requestdecorationmode(struct wl_listener *listener, void *data);
static void requeststartdrag(struct wl_listener *listener, void *data);
static void requestmonstate(struct wl_listener *listener, void *data);
@@ -378,6 +381,7 @@ static void setlayout(const Arg *arg);
static void setmfact(const Arg *arg);
static void setmon(Client *c, Monitor *m, uint32_t newtags);
static void setpsel(struct wl_listener *listener, void *data);
+static void setscratchpad(const Arg *arg);
static void setsel(struct wl_listener *listener, void *data);
static void setup(void);
static void spawn(const Arg *arg);
@@ -389,6 +393,7 @@ static void tile(Monitor *m);
static void togglebar(const Arg *arg);
static void togglefloating(const Arg *arg);
static void togglefullscreen(const Arg *arg);
+static void togglescratchpad(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unlocksession(struct wl_listener *listener, void *data);
@@ -532,6 +537,10 @@ struct Pertag {
unsigned int sellts[sizeof(tags)/sizeof(tags[0]) + 1]; /* selected layouts */
const Layout *ltidxs[sizeof(tags)/sizeof(tags[0]) + 1][2]; /* matrix of tags and layouts indexes */
};
+static struct wl_list scratchpad_clients[SCRATCHPAD_COUNT];
+static int scratchpad_visible[SCRATCHPAD_COUNT];
+static int scratchpad_sel = 0;
+#include "simple_scratchpad.c"
/* function implementations */
void
@@ -1616,10 +1625,21 @@ void
destroynotify(struct wl_listener *listener, void *data)
{
/* Called when the xdg_toplevel is destroyed. */
- Client *c = wl_container_of(listener, c, destroy);
+ Client *sc, *c = wl_container_of(listener, c, destroy);
wl_list_remove(&c->destroy.link);
wl_list_remove(&c->set_title.link);
wl_list_remove(&c->fullscreen.link);
+ /* Check if destroyed client was part of any scratchpad slot
+ * and clean it from the list if so. */
+ for (int i = 0; i < SCRATCHPAD_COUNT; i++) {
+ wl_list_for_each(sc, &scratchpad_clients[i], link_temp) {
+ if (sc == c) {
+ wl_list_remove(&c->link_temp);
+ goto scratchpad_destroy_done;
+ }
+ }
+ }
+scratchpad_destroy_done:;
#ifdef XWAYLAND
if (c->type != XDGShell) {
wl_list_remove(&c->activate.link);
@@ -2833,11 +2853,24 @@ setcursorshape(struct wl_listener *listener, void *data)
void
setfloating(Client *c, int floating)
{
- Client *p = client_get_parent(c);
+ Client *sc, *p = client_get_parent(c);
c->isfloating = floating;
/* If in floating layout do not change the client's layer */
if (!c->mon || !client_surface(c)->mapped || !c->mon->lt[c->mon->sellt]->arrange)
return;
+ /* Check if unfloated client was part of any scratchpad slot
+ * and remove it from that slot if so */
+ if (!floating) {
+ for (int i = 0; i < SCRATCHPAD_COUNT; i++) {
+ wl_list_for_each(sc, &scratchpad_clients[i], link_temp) {
+ if (sc == c) {
+ wl_list_remove(&c->link_temp);
+ goto scratchpad_float_done;
+ }
+ }
+ }
+scratchpad_float_done:;
+ }
wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen ||
(p && p->isfullscreen) ? LyrFS
: c->isfloating ? LyrFloat : LyrTile]);
@@ -3058,6 +3091,11 @@ setup(void)
*/
wl_list_init(&clients);
wl_list_init(&fstack);
+ wl_list_init(&fstack);
+ for (int j = 0; j < SCRATCHPAD_COUNT; j++) {
+ wl_list_init(&scratchpad_clients[j]);
+ scratchpad_visible[j] = 1;
+ }
xdg_shell = wlr_xdg_shell_create(dpy, 6);
wl_signal_add(&xdg_shell->events.new_toplevel, &new_xdg_toplevel);
diff --git a/simple_scratchpad.c b/simple_scratchpad.c
new file mode 100644
index 0000000..271e72e
--- /dev/null
+++ b/simple_scratchpad.c
@@ -0,0 +1,101 @@
+/* ************************************************************************** */
+/* @@@ @@@@@@@@ */
+/* @@@ @@@@@@@@@@ */
+/* @@! @@! @@@@ */
+/* !@! !@! @!@!@ */
+/* simple_scratchpad.c @!! @!@ @! !@! */
+/* !!! !@!!! !!! */
+/* By: julmajustus <julmajustus@tutanota.com> !!: !!:! !!! */
+/* ::! :!: !:! */
+/* Created: 2024/12/19 19:35:02 by jmakkone :: ::::::: :: */
+/* Updated: 2026/05/20 23:58:16 by julmajustus : : : : : : */
+/* */
+/* ************************************************************************** */
+
+void draw_scratchpad(void) {
+ Client *c;
+ Monitor *m = selmon;
+
+ if (scratchpad_visible[scratchpad_sel]) {
+ wl_list_for_each(c, &scratchpad_clients[scratchpad_sel], link_temp) {
+ c->mon = m;
+ c->tags = m->tagset[m->seltags];
+ arrange(m);
+ focusclient(c, 1);
+ }
+ } else {
+ wl_list_for_each(c, &scratchpad_clients[scratchpad_sel], link_temp) {
+ c->tags = 0;
+ focusclient(focustop(m), 1);
+ arrange(m);
+ }
+ }
+}
+
+void
+addscratchpad(const Arg *arg)
+{
+ Client *cc, *c = focustop(selmon);
+ Monitor *m = selmon;
+
+ if (!c)
+ return;
+ /* Check if the added client is already a scratchpad client */
+ for (int i = 0; i < SCRATCHPAD_COUNT; i++) {
+ wl_list_for_each(cc, &scratchpad_clients[i], link_temp) {
+ if (cc == c)
+ return;
+ }
+ }
+ if (!c->isfloating) {
+ setfloating(c, 1);
+ }
+ scratchpad_visible[scratchpad_sel] = 0;
+ draw_scratchpad();
+ wl_list_insert(&scratchpad_clients[scratchpad_sel], &c->link_temp);
+ c->tags = 0;
+ arrange(m);
+ focusclient(focustop(m), 1);
+ arrange(m);
+}
+
+void
+togglescratchpad(const Arg *arg)
+{
+ scratchpad_visible[scratchpad_sel] = !scratchpad_visible[scratchpad_sel];
+ draw_scratchpad();
+}
+
+void
+removescratchpad(const Arg *arg)
+{
+ Client *sc, *c = focustop(selmon);
+ Monitor *m = selmon;
+ if (!c)
+ return;
+ for (int i = 0; i < SCRATCHPAD_COUNT; i++) {
+ /* Check if c is in scratchpad_clients */
+ wl_list_for_each(sc, &scratchpad_clients[i], link_temp) {
+ if (sc == c) {
+ wl_list_remove(&sc->link_temp);
+ setfloating(sc, 0);
+ arrange(m);
+ focusclient(sc, 1);
+ return;
+ }
+ }
+ }
+
+}
+
+void
+setscratchpad(const Arg *arg)
+{
+ int idx = arg->i;
+
+ if (idx < 0)
+ idx = 0;
+ else if (idx >= SCRATCHPAD_COUNT)
+ idx = SCRATCHPAD_COUNT - 1;
+ scratchpad_sel = idx;
+}