From 3868217466a2264f2645b5f63c74d0ae1a28acd6 Mon Sep 17 00:00:00 2001 From: David Donahue Date: Sun, 7 Feb 2021 00:31:01 -0600 Subject: [PATCH 01/10] Added interface to output information about tags, the currently selected monitor, and the focused client to a file for use by a status bar --- dwl.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/dwl.c b/dwl.c index 5b5e35e..8e43829 100644 --- a/dwl.c +++ b/dwl.c @@ -280,6 +280,7 @@ static void setmon(Client *c, Monitor *m, unsigned int newtags); static void setup(void); static void sigchld(int unused); static void spawn(const Arg *arg); +static void statusbar(void); static void tag(const Arg *arg); static void tagmon(const Arg *arg); static void tile(Monitor *m); @@ -1116,6 +1117,7 @@ focusclient(Client *c, int lift) wl_list_insert(&fstack, &c->flink); selmon = c->mon; } + statusbar(); /* Deactivate old client if focus is changing */ if (old && (!c || client_surface(c) != old)) { @@ -1914,6 +1916,7 @@ setlayout(const Arg *arg) selmon->lt[selmon->sellt] = (Layout *)arg->v; /* TODO change layout symbol? */ arrange(selmon); + statusbar(); } /* arg > 1.0 will set mfact absolutely */ @@ -2155,6 +2158,39 @@ spawn(const Arg *arg) } } +void +statusbar(void) +{ + Monitor *m = NULL; + Client *c = NULL; + FILE *taginfo; + const char *title; + char fname[30]=""; + unsigned int activetags; + + //Add WAYLAND_DISPLAY to filename so each session has a predictable file + snprintf(fname, 30, "/tmp/dwltags-%s", getenv("WAYLAND_DISPLAY")); + + if (!(taginfo = fopen(fname, "w"))) + return; + + wl_list_for_each(m, &mons, link) { + activetags=0; + wl_list_for_each(c, &clients, link) { + if (c->mon == m) + activetags |= c->tags; + } + if (focustop(m)) + fprintf(taginfo, "%s\n", client_get_title(focustop(m))); + else + fprintf(taginfo, "\n"); + + fprintf(taginfo, "%u %u %u %s\n", m == selmon, + activetags, m->tagset[m->seltags], selmon->lt[selmon->sellt]->symbol); + } + fclose (taginfo); +} + void tag(const Arg *arg) { From 27598bd04a17f78d3a3fb27d61fe72ffd9ae1f32 Mon Sep 17 00:00:00 2001 From: David Donahue Date: Sun, 7 Feb 2021 01:03:04 -0600 Subject: [PATCH 02/10] added statusbar update when tags are updated --- dwl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dwl.c b/dwl.c index 8e43829..7e9a2fd 100644 --- a/dwl.c +++ b/dwl.c @@ -2200,6 +2200,7 @@ tag(const Arg *arg) focusclient(focustop(selmon), 1); arrange(selmon); } + statusbar(); } void @@ -2269,6 +2270,7 @@ toggletag(const Arg *arg) focusclient(focustop(selmon), 1); arrange(selmon); } + statusbar(); } void @@ -2281,6 +2283,7 @@ toggleview(const Arg *arg) focusclient(focustop(selmon), 1); arrange(selmon); } + statusbar(); } void @@ -2361,6 +2364,7 @@ view(const Arg *arg) selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; focusclient(focustop(selmon), 1); arrange(selmon); + statusbar(); } void From a1e24075d81924926e5be4844e4e6faa8e0d744e Mon Sep 17 00:00:00 2001 From: David Donahue Date: Mon, 8 Feb 2021 18:12:24 -0600 Subject: [PATCH 03/10] Removed unused variable from statusbar --- dwl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/dwl.c b/dwl.c index 7e9a2fd..534c7ac 100644 --- a/dwl.c +++ b/dwl.c @@ -2164,7 +2164,6 @@ statusbar(void) Monitor *m = NULL; Client *c = NULL; FILE *taginfo; - const char *title; char fname[30]=""; unsigned int activetags; From 593b7eec3c58f3a332669cdea49a103017cfadf1 Mon Sep 17 00:00:00 2001 From: David Donahue Date: Mon, 1 Mar 2021 13:19:25 -0600 Subject: [PATCH 04/10] updated output format for better expansibility and easier parsing --- dwl.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dwl.c b/dwl.c index 534c7ac..a5d2dba 100644 --- a/dwl.c +++ b/dwl.c @@ -2180,12 +2180,13 @@ statusbar(void) activetags |= c->tags; } if (focustop(m)) - fprintf(taginfo, "%s\n", client_get_title(focustop(m))); + fprintf(taginfo, "%s title %s\n", m->wlr_output->name, client_get_title(focustop(m))); else - fprintf(taginfo, "\n"); + fprintf(taginfo, "%s title \n", m->wlr_output->name); - fprintf(taginfo, "%u %u %u %s\n", m == selmon, - activetags, m->tagset[m->seltags], selmon->lt[selmon->sellt]->symbol); + fprintf(taginfo, "%s selmon %u\n", m->wlr_output->name, m == selmon); + fprintf(taginfo, "%s tags %u %u\n", m->wlr_output->name, activetags, m->tagset[m->seltags]); + fprintf(taginfo, "%s layout %s\n", m->wlr_output->name, m->lt[m->sellt]->symbol); } fclose (taginfo); } From f5e7caac0029de10617eac1082a0e8bed27d41e3 Mon Sep 17 00:00:00 2001 From: David Donahue Date: Mon, 1 Mar 2021 13:49:29 -0600 Subject: [PATCH 05/10] Changed output to stdout instead of a file --- dwl.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/dwl.c b/dwl.c index a5d2dba..8193b2c 100644 --- a/dwl.c +++ b/dwl.c @@ -2163,16 +2163,8 @@ statusbar(void) { Monitor *m = NULL; Client *c = NULL; - FILE *taginfo; - char fname[30]=""; unsigned int activetags; - //Add WAYLAND_DISPLAY to filename so each session has a predictable file - snprintf(fname, 30, "/tmp/dwltags-%s", getenv("WAYLAND_DISPLAY")); - - if (!(taginfo = fopen(fname, "w"))) - return; - wl_list_for_each(m, &mons, link) { activetags=0; wl_list_for_each(c, &clients, link) { @@ -2180,15 +2172,15 @@ statusbar(void) activetags |= c->tags; } if (focustop(m)) - fprintf(taginfo, "%s title %s\n", m->wlr_output->name, client_get_title(focustop(m))); + fprintf(stdout, "%s title %s\n", m->wlr_output->name, client_get_title(focustop(m))); else - fprintf(taginfo, "%s title \n", m->wlr_output->name); + fprintf(stdout, "%s title \n", m->wlr_output->name); - fprintf(taginfo, "%s selmon %u\n", m->wlr_output->name, m == selmon); - fprintf(taginfo, "%s tags %u %u\n", m->wlr_output->name, activetags, m->tagset[m->seltags]); - fprintf(taginfo, "%s layout %s\n", m->wlr_output->name, m->lt[m->sellt]->symbol); + fprintf(stdout, "%s selmon %u\n", m->wlr_output->name, m == selmon); + fprintf(stdout, "%s tags %u %u\n", m->wlr_output->name, activetags, m->tagset[m->seltags]); + fprintf(stdout, "%s layout %s\n", m->wlr_output->name, m->lt[m->sellt]->symbol); } - fclose (taginfo); + fflush(stdout); } void From 5b51bb82e234010aea5b72aa97d8679928efe259 Mon Sep 17 00:00:00 2001 From: David Donahue Date: Mon, 1 Mar 2021 14:38:00 -0600 Subject: [PATCH 06/10] Fixed tab formatting in 6 locations where statusbar() is called --- dwl.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dwl.c b/dwl.c index 8193b2c..b0b9ef1 100644 --- a/dwl.c +++ b/dwl.c @@ -1117,7 +1117,7 @@ focusclient(Client *c, int lift) wl_list_insert(&fstack, &c->flink); selmon = c->mon; } - statusbar(); + statusbar(); /* Deactivate old client if focus is changing */ if (old && (!c || client_surface(c) != old)) { @@ -1916,7 +1916,7 @@ setlayout(const Arg *arg) selmon->lt[selmon->sellt] = (Layout *)arg->v; /* TODO change layout symbol? */ arrange(selmon); - statusbar(); + statusbar(); } /* arg > 1.0 will set mfact absolutely */ @@ -2192,7 +2192,7 @@ tag(const Arg *arg) focusclient(focustop(selmon), 1); arrange(selmon); } - statusbar(); + statusbar(); } void @@ -2262,7 +2262,7 @@ toggletag(const Arg *arg) focusclient(focustop(selmon), 1); arrange(selmon); } - statusbar(); + statusbar(); } void @@ -2275,7 +2275,7 @@ toggleview(const Arg *arg) focusclient(focustop(selmon), 1); arrange(selmon); } - statusbar(); + statusbar(); } void @@ -2356,7 +2356,7 @@ view(const Arg *arg) selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; focusclient(focustop(selmon), 1); arrange(selmon); - statusbar(); + statusbar(); } void From 7cee5060bc400bb0d81472e9c449cc1bc63b0409 Mon Sep 17 00:00:00 2001 From: David Donahue Date: Sat, 6 Mar 2021 12:20:56 -0600 Subject: [PATCH 07/10] added redirect from stdout to stderr for spawned processes to prevent conflicts with the statusbar outputs --- dwl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dwl.c b/dwl.c index b0b9ef1..f3018da 100644 --- a/dwl.c +++ b/dwl.c @@ -1846,6 +1846,7 @@ run(char *startup_cmd) if (startup_pid < 0) EBARF("startup: fork"); if (startup_pid == 0) { + dup2(STDERR_FILENO, STDOUT_FILENO); execl("/bin/sh", "/bin/sh", "-c", startup_cmd, NULL); EBARF("startup: execl"); } @@ -2152,6 +2153,7 @@ void spawn(const Arg *arg) { if (fork() == 0) { + dup2(STDERR_FILENO, STDOUT_FILENO); setsid(); execvp(((char **)arg->v)[0], (char **)arg->v); EBARF("dwl: execvp %s failed", ((char **)arg->v)[0]); From 43b6e804cf4d0e850db72a8a53b8b36130b21435 Mon Sep 17 00:00:00 2001 From: "Devin J. Pohly" Date: Sat, 13 Mar 2021 10:42:33 -0600 Subject: [PATCH 08/10] Revert "remove sigchld function" This reverts commit 1fa72b07728ebb396a9f236921b81c369bb12ccb. Fixes #97. --- dwl.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/dwl.c b/dwl.c index 0853f1e..2f9cc29 100644 --- a/dwl.c +++ b/dwl.c @@ -278,6 +278,7 @@ static void setlayout(const Arg *arg); static void setmfact(const Arg *arg); static void setmon(Client *c, Monitor *m, unsigned int newtags); static void setup(void); +static void sigchld(int unused); static void spawn(const Arg *arg); static void tag(const Arg *arg); static void tagmon(const Arg *arg); @@ -1983,9 +1984,8 @@ setup(void) * clients from the Unix socket, manging Wayland globals, and so on. */ dpy = wl_display_create(); - /* Indicate explicitly to the OS that we are not interested in info - * about child processes (per POSIX.1-2001) */ - signal(SIGCHLD, SIG_IGN); + /* clean up child processes immediately */ + sigchld(0); /* The backend is a wlroots feature which abstracts the underlying input and * output hardware. The autocreate option will choose the most suitable @@ -2136,6 +2136,20 @@ setup(void) #endif } +void +sigchld(int unused) +{ + /* We should be able to remove this function in favor of a simple + * signal(SIGCHLD, SIG_IGN); + * but the Xwayland implementation in wlroots currently prevents us from + * setting our own disposition for SIGCHLD. + */ + if (signal(SIGCHLD, sigchld) == SIG_ERR) + EBARF("can't install SIGCHLD handler"); + while (0 < waitpid(-1, NULL, WNOHANG)) + ; +} + void spawn(const Arg *arg) { From ecc60878b3739bf15fb5affbc6c35b500aa41f4c Mon Sep 17 00:00:00 2001 From: David Donahue Date: Sat, 13 Mar 2021 11:20:33 -0600 Subject: [PATCH 09/10] changed fprintf(stdout) instances to printf(), changed function name from statusbar to printstatus --- dwl.c | 64 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/dwl.c b/dwl.c index f3018da..e18f807 100644 --- a/dwl.c +++ b/dwl.c @@ -260,6 +260,7 @@ static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int static void outputmgrtest(struct wl_listener *listener, void *data); static void pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, uint32_t time); +static void printstatus(void); static void quit(const Arg *arg); static void render(struct wlr_surface *surface, int sx, int sy, void *data); static void renderclients(Monitor *m, struct timespec *now); @@ -280,7 +281,6 @@ static void setmon(Client *c, Monitor *m, unsigned int newtags); static void setup(void); static void sigchld(int unused); static void spawn(const Arg *arg); -static void statusbar(void); static void tag(const Arg *arg); static void tagmon(const Arg *arg); static void tile(Monitor *m); @@ -1117,7 +1117,7 @@ focusclient(Client *c, int lift) wl_list_insert(&fstack, &c->flink); selmon = c->mon; } - statusbar(); + printstatus(); /* Deactivate old client if focus is changing */ if (old && (!c || client_surface(c) != old)) { @@ -1604,6 +1604,31 @@ pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, focusclient(c, 0); } +void +printstatus(void) +{ + Monitor *m = NULL; + Client *c = NULL; + unsigned int activetags; + + wl_list_for_each(m, &mons, link) { + activetags=0; + wl_list_for_each(c, &clients, link) { + if (c->mon == m) + activetags |= c->tags; + } + if (focustop(m)) + printf("%s title %s\n", m->wlr_output->name, client_get_title(focustop(m))); + else + printf("%s title \n", m->wlr_output->name); + + printf("%s selmon %u\n", m->wlr_output->name, m == selmon); + printf("%s tags %u %u\n", m->wlr_output->name, activetags, m->tagset[m->seltags]); + printf("%s layout %s\n", m->wlr_output->name, m->lt[m->sellt]->symbol); + } + fflush(stdout); +} + void quit(const Arg *arg) { @@ -1917,7 +1942,7 @@ setlayout(const Arg *arg) selmon->lt[selmon->sellt] = (Layout *)arg->v; /* TODO change layout symbol? */ arrange(selmon); - statusbar(); + printstatus(); } /* arg > 1.0 will set mfact absolutely */ @@ -2160,31 +2185,6 @@ spawn(const Arg *arg) } } -void -statusbar(void) -{ - Monitor *m = NULL; - Client *c = NULL; - unsigned int activetags; - - wl_list_for_each(m, &mons, link) { - activetags=0; - wl_list_for_each(c, &clients, link) { - if (c->mon == m) - activetags |= c->tags; - } - if (focustop(m)) - fprintf(stdout, "%s title %s\n", m->wlr_output->name, client_get_title(focustop(m))); - else - fprintf(stdout, "%s title \n", m->wlr_output->name); - - fprintf(stdout, "%s selmon %u\n", m->wlr_output->name, m == selmon); - fprintf(stdout, "%s tags %u %u\n", m->wlr_output->name, activetags, m->tagset[m->seltags]); - fprintf(stdout, "%s layout %s\n", m->wlr_output->name, m->lt[m->sellt]->symbol); - } - fflush(stdout); -} - void tag(const Arg *arg) { @@ -2194,7 +2194,7 @@ tag(const Arg *arg) focusclient(focustop(selmon), 1); arrange(selmon); } - statusbar(); + printstatus(); } void @@ -2264,7 +2264,7 @@ toggletag(const Arg *arg) focusclient(focustop(selmon), 1); arrange(selmon); } - statusbar(); + printstatus(); } void @@ -2277,7 +2277,7 @@ toggleview(const Arg *arg) focusclient(focustop(selmon), 1); arrange(selmon); } - statusbar(); + printstatus(); } void @@ -2358,7 +2358,7 @@ view(const Arg *arg) selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; focusclient(focustop(selmon), 1); arrange(selmon); - statusbar(); + printstatus(); } void From 38ba6d2277cb521c1366c99f4845659e7b5ba451 Mon Sep 17 00:00:00 2001 From: Stivvo Date: Thu, 25 Mar 2021 10:05:12 -0500 Subject: [PATCH 10/10] Fullscreen: simplifications and fixes Merges #69. --- dwl.c | 44 ++++++++------------------------------------ 1 file changed, 8 insertions(+), 36 deletions(-) diff --git a/dwl.c b/dwl.c index e807330..ead6ec2 100644 --- a/dwl.c +++ b/dwl.c @@ -175,7 +175,6 @@ struct Monitor { unsigned int tagset[2]; double mfact; int nmaster; - Client *fullscreenclient; }; typedef struct { @@ -249,7 +248,6 @@ static void keypressmod(struct wl_listener *listener, void *data); static void killclient(const Arg *arg); static void maplayersurfacenotify(struct wl_listener *listener, void *data); static void mapnotify(struct wl_listener *listener, void *data); -static void maximizeclient(Client *c); static void monocle(Monitor *m); static void motionabsolute(struct wl_listener *listener, void *data); static void motionnotify(uint32_t time); @@ -485,8 +483,6 @@ arrange(Monitor *m) { if (m->lt[m->sellt]->arrange) m->lt[m->sellt]->arrange(m); - else if (m->fullscreenclient) - maximizeclient(m->fullscreenclient); /* TODO recheck pointer focus here... or in resize()? */ } @@ -885,9 +881,6 @@ createnotify(struct wl_listener *listener, void *data) if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) return; - wl_list_for_each(c, &clients, link) - if (c->isfullscreen && VISIBLEON(c, c->mon)) - setfullscreen(c, 0); /* Allocate a Client for this surface */ c = xdg_surface->data = calloc(1, sizeof(*c)); @@ -1042,14 +1035,8 @@ void togglefullscreen(const Arg *arg) { Client *sel = selclient(); - setfullscreen(sel, !sel->isfullscreen); -} - -void -maximizeclient(Client *c) -{ - resize(c, c->mon->m.x, c->mon->m.y, c->mon->m.width, c->mon->m.height, 0); - /* used for fullscreen clients */ + if (sel) + setfullscreen(sel, !sel->isfullscreen); } void @@ -1064,13 +1051,11 @@ setfullscreen(Client *c, int fullscreen) c->prevy = c->geom.y; c->prevheight = c->geom.height; c->prevwidth = c->geom.width; - c->mon->fullscreenclient = c; - maximizeclient(c); + resize(c, c->mon->m.x, c->mon->m.y, c->mon->m.width, c->mon->m.height, 0); } else { /* restore previous size instead of arrange for floating windows since * client positions are set by the user and cannot be recalculated */ resize(c, c->prevx, c->prevy, c->prevwidth, c->prevheight, 0); - c->mon->fullscreenclient = NULL; arrange(c->mon); } } @@ -1337,7 +1322,7 @@ void mapnotify(struct wl_listener *listener, void *data) { /* Called when the surface is mapped, or ready to display on-screen. */ - Client *c = wl_container_of(listener, c, map), *oldfocus = selclient(); + Client *c = wl_container_of(listener, c, map); if (client_is_unmanaged(c)) { /* Insert this independent into independents lists. */ @@ -1356,14 +1341,6 @@ mapnotify(struct wl_listener *listener, void *data) /* Set initial monitor, tags, floating status, and focus */ applyrules(c); - - if (c->mon->fullscreenclient && c->mon->fullscreenclient == oldfocus - && !c->isfloating && c->mon->lt[c->mon->sellt]->arrange) { - maximizeclient(c->mon->fullscreenclient); - focusclient(c->mon->fullscreenclient, 1); - /* give the focus back the fullscreen client on that monitor if exists, - * is focused and the new client isn't floating */ - } } void @@ -1372,12 +1349,9 @@ monocle(Monitor *m) Client *c; wl_list_for_each(c, &clients, link) { - if (!VISIBLEON(c, m) || c->isfloating) + if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) continue; - if (c->isfullscreen) - maximizeclient(c); - else - resize(c, m->w.x, m->w.y, m->w.width, m->w.height, 0); + resize(c, m->w.x, m->w.y, m->w.width, m->w.height, 0); } } @@ -2229,11 +2203,9 @@ tile(Monitor *m) mw = m->w.width; i = my = ty = 0; wl_list_for_each(c, &clients, link) { - if (!VISIBLEON(c, m) || c->isfloating) + if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) continue; - if (c->isfullscreen) - maximizeclient(c); - else if (i < m->nmaster) { + if (i < m->nmaster) { h = (m->w.height - my) / (MIN(n, m->nmaster) - i); resize(c, m->w.x, m->w.y + my, mw, h, 0); my += c->geom.height;