summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author0scar <qgt268@alumni.ku.dk>2024-09-30 10:16:05 +0000
committer0scar <qgt268@alumni.ku.dk>2024-10-01 11:53:31 +0000
commit7d0adc3c6331e1ff1a02d33e71cf00202ef2e26b (patch)
treeb67e1627719296d1fd8fe207846131c379cfe83a
parent5a61337342915ff0697546d0b88852f559bf84a5 (diff)
Patch: named scratchpads
-rw-r--r--config.def.h12
-rw-r--r--dwl.c126
2 files changed, 133 insertions, 5 deletions
diff --git a/config.def.h b/config.def.h
index 57e28e9..28e340c 100644
--- a/config.def.h
+++ b/config.def.h
@@ -28,10 +28,12 @@ static int log_level = WLR_ERROR;
/* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */
#define TAG(t) (1 << (t - 1))
static const Rule rules[] = {
- /* app_id title tags mask isfloating monitor */
+ /* app_id title tags mask isfloating monitor scratchkey */
/* examples: */
- { "Gimp", NULL, TAG(9), 1, -1 }, /* Start on currently visible tags floating, not tiled */
- { "firefox", NULL, TAG(2), 0, -1 }, /* Start on ONLY tag "9" */
+ { "Gimp", NULL, TAG(9), 1, -1, 0 }, /* Start on currently visible tags floating, not tiled */
+ { "firefox", NULL, TAG(2), 0, -1, 0 }, /* Start on ONLY tag "9" */
+ { NULL, "scratchpad", 0, 1, -1, 's' }, /* Used for terminal scratchpad */
+ { NULL, "spadcalc", 0, 1, -1, 'c' }, /* Used for terminal scratchpad */
};
#undef TAG
@@ -140,8 +142,8 @@ static const Key keys[] = {
/* modifier key function argument */
{ MODKEY, XKB_KEY_d, spawn, {.v = menucmd} },
{ MODKEY, XKB_KEY_Return, spawn, {.v = termcmd} },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn, {.v = scratchpadcmd} },
- { MODKEY, XKB_KEY_apostrophe, spawn, {.v = scratchpadcalc} },
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, togglescratch, {.v = scratchpadcmd} },
+ { MODKEY, XKB_KEY_apostrophe, togglescratch, {.v = scratchpadcalc} },
{ MODKEY, XKB_KEY_j, focusstack, {.i = +1} },
{ MODKEY, XKB_KEY_k, focusstack, {.i = -1} },
{ MODKEY, XKB_KEY_i, incnmaster, {.i = +1} },
diff --git a/dwl.c b/dwl.c
index eecdff1..5c5741b 100644
--- a/dwl.c
+++ b/dwl.c
@@ -143,6 +143,7 @@ typedef struct {
unsigned int bw;
uint32_t tags;
int isfloating, isurgent, isfullscreen;
+ char scratchkey;
uint32_t resize; /* configure serial of a pending resize */
} Client;
@@ -233,6 +234,7 @@ typedef struct {
uint32_t tags;
int isfloating;
int monitor;
+ const char scratchkey;
} Rule;
typedef struct {
@@ -289,6 +291,8 @@ static void destroykeyboardgroup(struct wl_listener *listener, void *data);
static Monitor *dirtomon(enum wlr_direction dir);
static void focusclient(Client *c, int lift);
static void focusmon(const Arg *arg);
+static void focusortogglematchingscratch(const Arg *arg);
+static void focusortogglescratch(const Arg *arg);
static void focusstack(const Arg *arg);
static Client *focustop(Monitor *m);
static void fullscreennotify(struct wl_listener *listener, void *data);
@@ -335,12 +339,14 @@ static void setpsel(struct wl_listener *listener, void *data);
static void setsel(struct wl_listener *listener, void *data);
static void setup(void);
static void spawn(const Arg *arg);
+static void spawnscratch(const Arg *arg);
static void startdrag(struct wl_listener *listener, void *data);
static void tag(const Arg *arg);
static void tagmon(const Arg *arg);
static void tile(Monitor *m);
static void togglefloating(const Arg *arg);
static void togglefullscreen(const Arg *arg);
+static void togglescratch(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unlocksession(struct wl_listener *listener, void *data);
@@ -461,6 +467,7 @@ applyrules(Client *c)
Monitor *mon = selmon, *m;
c->isfloating = client_is_float_type(c);
+ c->scratchkey = 0;
appid = client_get_appid(c);
title = client_get_title(c);
@@ -468,6 +475,7 @@ applyrules(Client *c)
if ((!r->title || strstr(title, r->title))
&& (!r->id || strstr(appid, r->id))) {
c->isfloating = r->isfloating;
+ c->scratchkey = r->scratchkey;
newtags |= r->tags;
i = 0;
wl_list_for_each(m, &mons, link) {
@@ -1434,6 +1442,91 @@ focusmon(const Arg *arg)
}
void
+focusortogglematchingscratch(const Arg *arg)
+{
+ Client *c;
+ unsigned int found = 0;
+ unsigned int hide = 0;
+
+ wl_list_for_each(c, &clients, link) {
+ if (c->scratchkey == 0) {
+ continue;
+ }
+ if (c->scratchkey == ((char**)arg->v)[0][0]) {
+ if (VISIBLEON(c, selmon)) {
+ if (found == 1) {
+ if (hide == 1) {
+ c->tags = 0;
+ focusclient(focustop(selmon), 1);
+ }
+ continue;
+ }
+ if (focustop(selmon) == c) {
+ // hide
+ c->tags = 0;
+ focusclient(focustop(selmon), 1);
+ hide = 1;
+ } else {
+ // focus
+ focusclient(c, 1);
+ }
+ } else {
+ // show
+ c->tags = selmon->tagset[selmon->seltags];
+ // focus
+ focusclient(c, 1);
+ }
+ found = 1;
+ continue;
+ }
+ if (VISIBLEON(c, selmon)) {
+ // hide
+ c->tags = 0;
+ }
+ }
+
+ if (found) {
+ arrange(selmon);
+ } else {
+ spawnscratch(arg);
+ }
+}
+
+void
+focusortogglescratch(const Arg *arg)
+{
+ Client *c;
+ unsigned int found = 0;
+
+ /* search for first window that matches the scratchkey */
+ wl_list_for_each(c, &clients, link)
+ if (c->scratchkey == ((char**)arg->v)[0][0]) {
+ found = 1;
+ break;
+ }
+
+ if (found) {
+ if (VISIBLEON(c, selmon)) {
+ if (focustop(selmon) == c) {
+ // hide
+ c->tags = 0;
+ focusclient(focustop(selmon), 1);
+ } else {
+ // focus
+ focusclient(c, 1);
+ }
+ } else {
+ // show
+ c->tags = selmon->tagset[selmon->seltags];
+ focusclient(c, 1);
+ }
+ arrange(selmon);
+ } else{
+ spawnscratch(arg);
+ }
+}
+
+void
focusstack(const Arg *arg)
{
/* Focus the next or previous client (in tiling order) on selmon */
@@ -2645,6 +2738,16 @@ spawn(const Arg *arg)
}
}
+void spawnscratch(const Arg *arg)
+{
+ if (fork() == 0) {
+ dup2(STDERR_FILENO, STDOUT_FILENO);
+ setsid();
+ execvp(((char **)arg->v)[1], ((char **)arg->v)+1);
+ die("dwl: execvp %s failed:", ((char **)arg->v)[1]);
+ }
+}
+
void
startdrag(struct wl_listener *listener, void *data)
{
@@ -2732,6 +2835,29 @@ togglefullscreen(const Arg *arg)
}
void
+togglescratch(const Arg *arg)
+{
+ Client *c;
+ unsigned int found = 0;
+
+ /* search for first window that matches the scratchkey */
+ wl_list_for_each(c, &clients, link)
+ if (c->scratchkey == ((char**)arg->v)[0][0]) {
+ found = 1;
+ break;
+ }
+
+ if (found) {
+ c->tags = VISIBLEON(c, selmon) ? 0 : selmon->tagset[selmon->seltags];
+
+ focusclient(c->tags == 0 ? focustop(selmon) : c, 1);
+ arrange(selmon);
+ } else{
+ spawnscratch(arg);
+ }
+}
+
+void
toggletag(const Arg *arg)
{
uint32_t newtags;