From 47984509443e9be8776e96b9b21e81d5305d68a6 Mon Sep 17 00:00:00 2001 From: "Devin J. Pohly" Date: Tue, 16 Feb 2021 13:13:47 -0600 Subject: [PATCH 01/14] Revert "Revert "document that we currently follow wlroots-git"" This reverts commit ed8e80d9613599770ed2b11a3bc1d0057c075510. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f504672..2777613 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Feature *non-goals* include: ## Building dwl -dwl has only two dependencies: wlroots 0.12 and wayland-protocols. Simply install these and run `make`. +dwl has only two dependencies: wlroots-git and wayland-protocols. Simply install these and run `make`. To enable XWayland, you should also install xorg-xwayland and uncomment its flag in `config.mk`. From e8192b4fc920cba6c272a48fa86ca51bfd73f101 Mon Sep 17 00:00:00 2001 From: "Devin J. Pohly" Date: Tue, 16 Feb 2021 13:13:48 -0600 Subject: [PATCH 02/14] Revert "Revert "fix undeclared WLR_KEY_PRESSED"" This reverts commit a11f2bbc7a4068321767bd7e8c7eee1aee278bc9. --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 4098f86..6803594 100644 --- a/dwl.c +++ b/dwl.c @@ -1284,7 +1284,7 @@ keypress(struct wl_listener *listener, void *data) wlr_idle_notify_activity(idle, seat); /* On _press_, attempt to process a compositor keybinding. */ - if (event->state == WLR_KEY_PRESSED) + if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) for (i = 0; i < nsyms; i++) handled = keybinding(mods, syms[i]) || handled; From c1eb2b49cdc7d85fb52c877ce47cd2a677cf3d5c Mon Sep 17 00:00:00 2001 From: "Devin J. Pohly" Date: Tue, 16 Feb 2021 13:13:49 -0600 Subject: [PATCH 03/14] Revert "Revert "remove EGL parameter from backend_autocreate"" This reverts commit 8ed88822ca4448b06c2d7e6155d8022152b78017. --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 6803594..72f1046 100644 --- a/dwl.c +++ b/dwl.c @@ -1995,7 +1995,7 @@ setup(void) * backend uses the renderer, for example, to fall back to software cursors * if the backend does not support hardware cursors (some older GPUs * don't). */ - if (!(backend = wlr_backend_autocreate(dpy, NULL))) + if (!(backend = wlr_backend_autocreate(dpy))) BARF("couldn't create backend"); /* If we don't provide a renderer, autocreate makes a GLES2 renderer for us. From 87b16e6095379ce0e0a44c73926d5cbaf9a269d9 Mon Sep 17 00:00:00 2001 From: "Devin J. Pohly" Date: Mon, 1 Mar 2021 11:17:10 -0600 Subject: [PATCH 04/14] Defaults should match dwm/Xorg default behavior --- config.def.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.def.h b/config.def.h index 4aefa2b..ceb5b34 100644 --- a/config.def.h +++ b/config.def.h @@ -49,7 +49,7 @@ static const int repeat_delay = 600; /* Trackpad */ static const int tap_to_click = 1; -static const int natural_scrolling = 1; +static const int natural_scrolling = 0; #define MODKEY WLR_MODIFIER_ALT #define TAGKEYS(KEY,SKEY,TAG) \ From 2d71c9b9ff19d76ed3e78f67ed84d4ae03edd99d Mon Sep 17 00:00:00 2001 From: "Devin J. Pohly" Date: Mon, 1 Mar 2021 11:21:15 -0600 Subject: [PATCH 05/14] Add default menu command dwm config parity --- config.def.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/config.def.h b/config.def.h index ceb5b34..f287384 100644 --- a/config.def.h +++ b/config.def.h @@ -62,11 +62,13 @@ static const int natural_scrolling = 0; #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } /* commands */ -static const char *termcmd[] = { "alacritty", NULL }; +static const char *termcmd[] = { "alacritty", NULL }; +static const char *menucmd[] = { "bemenu-run", NULL }; static const Key keys[] = { /* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */ /* modifier key function argument */ + { MODKEY, XKB_p, spawn, {.v = menucmd} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn, {.v = termcmd} }, { MODKEY, XKB_KEY_j, focusstack, {.i = +1} }, { MODKEY, XKB_KEY_k, focusstack, {.i = -1} }, From 02eed717ca912f126c1bbabc0a8a7fa19a197f3c Mon Sep 17 00:00:00 2001 From: "Devin J. Pohly" Date: Mon, 1 Mar 2021 11:22:08 -0600 Subject: [PATCH 06/14] add explanatory command about Ctrl-Alt-Bksp/Fx --- config.def.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config.def.h b/config.def.h index f287384..9384ef6 100644 --- a/config.def.h +++ b/config.def.h @@ -101,6 +101,8 @@ static const Key keys[] = { TAGKEYS( XKB_KEY_8, XKB_KEY_asterisk, 7), TAGKEYS( XKB_KEY_9, XKB_KEY_parenleft, 8), { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q, quit, {0} }, + + /* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */ { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_Terminate_Server, quit, {0} }, #define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} } CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6), From fd498e1910d51def032d2b68f52cd89db7ba15f6 Mon Sep 17 00:00:00 2001 From: "Devin J. Pohly" Date: Mon, 1 Mar 2021 11:25:28 -0600 Subject: [PATCH 07/14] clarify a bit about status bars --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 92c6221..7fe130d 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ dwl is a compact, hackable compositor for Wayland based on [wlroots](https://git dwl is not meant to provide every feature under the sun. Instead, like dwm, it sticks to features which are necessary, simple, and straightforward to implement given the base on which it is built. Implemented default features are: -- Any features provided by dwm/Xlib: simple window borders, tags, keybindings, client rules, mouse move/resize. The built-in status bar is an exception to avoid taking a dependency on FreeType or Pango and increasing the SLOC +- Any features provided by dwm/Xlib: simple window borders, tags, keybindings, client rules, mouse move/resize. Providing a built-in status bar is an exception to this goal, to avoid dependencies on font rendering and/or drawing libraries when an external bar could work well. - Configurable multi-monitor layout support, including position and rotation - Configurable HiDPI/multi-DPI support - Various Wayland protocols @@ -21,7 +21,7 @@ dwl is not meant to provide every feature under the sun. Instead, like dwm, it s Features under consideration (possibly as patches) are: - Protocols made trivial by wlroots -- Communication from the compositor to status bars. A straightforward possibility would be to use stdout or a provided file descriptor. +- Provide information to external status bars via stdout or another file descriptor - Implement the input-inhibitor protocol to support screen lockers - Implement the idle-inhibit protocol which lets applications such as mpv disable idle monitoring - Layer shell popups (used by Waybar) From 15f5d31f98565ef740c0aa70b01765c2e564501c Mon Sep 17 00:00:00 2001 From: "Devin J. Pohly" Date: Wed, 3 Mar 2021 11:29:53 -0600 Subject: [PATCH 08/14] correct key constant name Fixes #94. --- config.def.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.def.h b/config.def.h index 9384ef6..089aa37 100644 --- a/config.def.h +++ b/config.def.h @@ -68,7 +68,7 @@ static const char *menucmd[] = { "bemenu-run", NULL }; static const Key keys[] = { /* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */ /* modifier key function argument */ - { MODKEY, XKB_p, spawn, {.v = menucmd} }, + { MODKEY, XKB_KEY_p, spawn, {.v = menucmd} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn, {.v = termcmd} }, { MODKEY, XKB_KEY_j, focusstack, {.i = +1} }, { MODKEY, XKB_KEY_k, focusstack, {.i = -1} }, From 1fa72b07728ebb396a9f236921b81c369bb12ccb Mon Sep 17 00:00:00 2001 From: "Devin J. Pohly" Date: Wed, 10 Mar 2021 09:50:09 -0600 Subject: [PATCH 09/14] remove sigchld function Explicitly setting the handler for SIGCHLD to SIG_IGN tells the OS to reap zombie processes automatically, which is what we wanted anyway. --- dwl.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/dwl.c b/dwl.c index 4098f86..0853f1e 100644 --- a/dwl.c +++ b/dwl.c @@ -278,7 +278,6 @@ 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); @@ -1984,8 +1983,9 @@ setup(void) * clients from the Unix socket, manging Wayland globals, and so on. */ dpy = wl_display_create(); - /* clean up child processes immediately */ - sigchld(0); + /* Indicate explicitly to the OS that we are not interested in info + * about child processes (per POSIX.1-2001) */ + signal(SIGCHLD, SIG_IGN); /* The backend is a wlroots feature which abstracts the underlying input and * output hardware. The autocreate option will choose the most suitable @@ -2136,15 +2136,6 @@ setup(void) #endif } -void -sigchld(int unused) -{ - if (signal(SIGCHLD, sigchld) == SIG_ERR) - EBARF("can't install SIGCHLD handler"); - while (0 < waitpid(-1, NULL, WNOHANG)) - ; -} - void spawn(const Arg *arg) { From 43b6e804cf4d0e850db72a8a53b8b36130b21435 Mon Sep 17 00:00:00 2001 From: "Devin J. Pohly" Date: Sat, 13 Mar 2021 10:42:33 -0600 Subject: [PATCH 10/14] 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 914bb4c886d2ce000aba2121cdc456d12d0de08e Mon Sep 17 00:00:00 2001 From: Stivvo Date: Sun, 14 Mar 2021 23:31:46 +0100 Subject: [PATCH 11/14] Track subsurfaces damages This prevents applications such as firefox from freezing when nothing else is going on. Those applications use subsurfaces (for efficiency reasons), which we were not keeping track of before. Applications who use subsurfaces were working fine as long as other applications were updating or the user was simply moving the mouse (and thus damaging the whole screen anyway). I'm not sure if listening to map and unmap events of subsurfaces is necessary. Most of this was inspired by sway. --- dwl.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/dwl.c b/dwl.c index 2bfd526..45be771 100644 --- a/dwl.c +++ b/dwl.c @@ -93,6 +93,7 @@ typedef struct { struct wlr_xwayland_surface *xwayland; } surface; struct wl_listener commit; + struct wl_listener new_sub; struct wl_listener map; struct wl_listener unmap; struct wl_listener destroy; @@ -115,6 +116,15 @@ typedef struct { int isfullscreen; } Client; +typedef struct { + struct wl_listener commit; + struct wl_listener map; + struct wl_listener unmap; + struct wl_listener destroy; + struct wlr_subsurface *subsurface; + Monitor *mon; +} Subsurface; + typedef struct { struct wl_listener request_mode; struct wl_listener destroy; @@ -227,6 +237,7 @@ static void cleanupmon(struct wl_listener *listener, void *data); static void closemon(Monitor *m); static void commitlayersurfacenotify(struct wl_listener *listener, void *data); static void commitnotify(struct wl_listener *listener, void *data); +static void commitnotify_sub(struct wl_listener *listener, void *data); static void createkeyboard(struct wlr_input_device *device); static void createmon(struct wl_listener *listener, void *data); static void createnotify(struct wl_listener *listener, void *data); @@ -236,6 +247,7 @@ static void createxdeco(struct wl_listener *listener, void *data); static void cursorframe(struct wl_listener *listener, void *data); static void destroylayersurfacenotify(struct wl_listener *listener, void *data); static void destroynotify(struct wl_listener *listener, void *data); +static void destroynotify_sub(struct wl_listener *listener, void *data); static void destroyxdeco(struct wl_listener *listener, void *data); static Monitor *dirtomon(enum wlr_direction dir); static void focusclient(Client *c, int lift); @@ -252,12 +264,14 @@ 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 mapnotify_sub(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); static void motionrelative(struct wl_listener *listener, void *data); static void moveresize(const Arg *arg); +static void new_subnotify(struct wl_listener *listener, void *data); static void outputmgrapply(struct wl_listener *listener, void *data); static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test); static void outputmgrtest(struct wl_listener *listener, void *data); @@ -293,6 +307,7 @@ static void toggleview(const Arg *arg); static void unmaplayersurface(LayerSurface *layersurface); static void unmaplayersurfacenotify(struct wl_listener *listener, void *data); static void unmapnotify(struct wl_listener *listener, void *data); +static void unmapnotify_sub(struct wl_listener *listener, void *data); static void updatemons(struct wl_listener *listener, void *data); static void view(const Arg *arg); static void virtualkeyboard(struct wl_listener *listener, void *data); @@ -791,6 +806,13 @@ commitnotify(struct wl_listener *listener, void *data) wlr_output_damage_add_whole(c->mon->damage); } +void +commitnotify_sub(struct wl_listener *listener, void *data) +{ + Subsurface *s = wl_container_of(listener, s, commit); + wlr_output_damage_add_whole(s->mon->damage); +} + void createkeyboard(struct wlr_input_device *device) { @@ -909,6 +931,7 @@ createnotify(struct wl_listener *listener, void *data) WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT); LISTEN(&xdg_surface->surface->events.commit, &c->commit, commitnotify); + LISTEN(&xdg_surface->surface->events.new_subsurface, &c->new_sub, new_subnotify); LISTEN(&xdg_surface->events.map, &c->map, mapnotify); LISTEN(&xdg_surface->events.unmap, &c->unmap, unmapnotify); LISTEN(&xdg_surface->events.destroy, &c->destroy, destroynotify); @@ -1042,6 +1065,18 @@ destroynotify(struct wl_listener *listener, void *data) free(c); } +void +destroynotify_sub(struct wl_listener *listener, void *data) +{ + Subsurface *s = wl_container_of(listener, s, destroy); + wlr_output_damage_add_whole(s->mon->damage); + wl_list_remove(&s->commit.link); + wl_list_remove(&s->map.link); + wl_list_remove(&s->unmap.link); + wl_list_remove(&s->destroy.link); + free(s); +} + void destroyxdeco(struct wl_listener *listener, void *data) { @@ -1347,6 +1382,14 @@ maplayersurfacenotify(struct wl_listener *listener, void *data) motionnotify(0); } +void +mapnotify_sub(struct wl_listener *listener, void *data) +{ + Subsurface *s = wl_container_of(listener, s, map); + wlr_output_damage_add_whole(s->mon->damage); +} + + void mapnotify(struct wl_listener *listener, void *data) { @@ -1521,6 +1564,20 @@ moveresize(const Arg *arg) } } +void +new_subnotify(struct wl_listener *listener, void *data) { + Subsurface *s = calloc(1, sizeof(Subsurface)); + Client *c = wl_container_of(listener, c, new_sub); + s->subsurface = data; + s->mon = c->mon; + + LISTEN(&s->subsurface->surface->events.commit, &s->commit, commitnotify_sub); + LISTEN(&s->subsurface->events.map, &s->map, mapnotify_sub); + LISTEN(&s->subsurface->events.unmap, &s->unmap, unmapnotify_sub); + LISTEN(&s->subsurface->events.destroy, &s->destroy, destroynotify_sub); +} + + void outputmgrapply(struct wl_listener *listener, void *data) { @@ -2317,6 +2374,14 @@ unmapnotify(struct wl_listener *listener, void *data) wl_list_remove(&c->slink); } +void +unmapnotify_sub(struct wl_listener *listener, void *data) +{ + Subsurface *s = wl_container_of(listener, s, unmap); + wlr_output_damage_add_whole(s->mon->damage); +} + + void updatemons(struct wl_listener *listener, void *data) { From 64b5c4c9f93a122c777ca02908802cd60fd774da Mon Sep 17 00:00:00 2001 From: Stivvo Date: Mon, 15 Mar 2021 01:07:34 +0100 Subject: [PATCH 12/14] Fix windows not showing up switching between tags When switching from an empty tag to a tag with clients the screen wasn't updating. This is easily fixed damaging the screen directly in arrange() --- dwl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dwl.c b/dwl.c index 45be771..9c4abf0 100644 --- a/dwl.c +++ b/dwl.c @@ -505,6 +505,7 @@ arrange(Monitor *m) else if (m->fullscreenclient) maximizeclient(m->fullscreenclient); /* TODO recheck pointer focus here... or in resize()? */ + wlr_output_damage_add_whole(m->damage); } void @@ -2028,7 +2029,6 @@ setmon(Client *c, Monitor *m, unsigned int newtags) if (oldmon) { wlr_surface_send_leave(client_surface(c), oldmon->wlr_output); arrange(oldmon); - wlr_output_damage_add_whole(oldmon->damage); } if (m) { /* Make sure window actually overlaps with the monitor */ @@ -2036,7 +2036,6 @@ setmon(Client *c, Monitor *m, unsigned int newtags) wlr_surface_send_enter(client_surface(c), m->wlr_output); c->tags = newtags ? newtags : m->tagset[m->seltags]; /* assign tags of target monitor */ arrange(m); - wlr_output_damage_add_whole(m->damage); } focusclient(focustop(selmon), 1); } From e8c5838a2ead4abb630d712a445d1f1311a9e825 Mon Sep 17 00:00:00 2001 From: Stivvo Date: Mon, 15 Mar 2021 09:47:44 +0100 Subject: [PATCH 13/14] Fix stuttering moving clients across monitors Memorize a pointer to the parent in each subsurface. This way, when that clients is moved to another monitor, that monitor will be damaged instead. --- dwl.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/dwl.c b/dwl.c index 9c4abf0..45fe8a8 100644 --- a/dwl.c +++ b/dwl.c @@ -122,7 +122,7 @@ typedef struct { struct wl_listener unmap; struct wl_listener destroy; struct wlr_subsurface *subsurface; - Monitor *mon; + Client *c; } Subsurface; typedef struct { @@ -811,7 +811,7 @@ void commitnotify_sub(struct wl_listener *listener, void *data) { Subsurface *s = wl_container_of(listener, s, commit); - wlr_output_damage_add_whole(s->mon->damage); + wlr_output_damage_add_whole(s->c->mon->damage); } void @@ -1070,7 +1070,7 @@ void destroynotify_sub(struct wl_listener *listener, void *data) { Subsurface *s = wl_container_of(listener, s, destroy); - wlr_output_damage_add_whole(s->mon->damage); + wlr_output_damage_add_whole(s->c->mon->damage); wl_list_remove(&s->commit.link); wl_list_remove(&s->map.link); wl_list_remove(&s->unmap.link); @@ -1387,7 +1387,7 @@ void mapnotify_sub(struct wl_listener *listener, void *data) { Subsurface *s = wl_container_of(listener, s, map); - wlr_output_damage_add_whole(s->mon->damage); + wlr_output_damage_add_whole(s->c->mon->damage); } @@ -1568,9 +1568,8 @@ moveresize(const Arg *arg) void new_subnotify(struct wl_listener *listener, void *data) { Subsurface *s = calloc(1, sizeof(Subsurface)); - Client *c = wl_container_of(listener, c, new_sub); + s->c = wl_container_of(listener, s->c, new_sub); s->subsurface = data; - s->mon = c->mon; LISTEN(&s->subsurface->surface->events.commit, &s->commit, commitnotify_sub); LISTEN(&s->subsurface->events.map, &s->map, mapnotify_sub); @@ -2377,7 +2376,7 @@ void unmapnotify_sub(struct wl_listener *listener, void *data) { Subsurface *s = wl_container_of(listener, s, unmap); - wlr_output_damage_add_whole(s->mon->damage); + wlr_output_damage_add_whole(s->c->mon->damage); } From 59bbf9f87f0339201d2119ed29568e60f85db9c3 Mon Sep 17 00:00:00 2001 From: Stivvo Date: Mon, 15 Mar 2021 11:39:32 +0100 Subject: [PATCH 14/14] Fix crash closing applications wlr_output_damage_add_whole() has no effect in mapnotifu_sub, destroynotify_sub and caused crashes when closing applications which use subsurfaces Keep track of subsurfaces in a list so that it is possible to remove and free them. --- dwl.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/dwl.c b/dwl.c index 45fe8a8..4f2fb1c 100644 --- a/dwl.c +++ b/dwl.c @@ -117,6 +117,7 @@ typedef struct { } Client; typedef struct { + struct wl_list link; struct wl_listener commit; struct wl_listener map; struct wl_listener unmap; @@ -329,6 +330,7 @@ static struct wl_list clients; /* tiling order */ static struct wl_list fstack; /* focus order */ static struct wl_list stack; /* stacking z-order */ static struct wl_list independents; +static struct wl_list subsurfaces; static struct wlr_idle *idle; static struct wlr_layer_shell_v1 *layer_shell; static struct wlr_xdg_decoration_manager_v1 *xdeco_mgr; @@ -1070,7 +1072,6 @@ void destroynotify_sub(struct wl_listener *listener, void *data) { Subsurface *s = wl_container_of(listener, s, destroy); - wlr_output_damage_add_whole(s->c->mon->damage); wl_list_remove(&s->commit.link); wl_list_remove(&s->map.link); wl_list_remove(&s->unmap.link); @@ -1383,14 +1384,6 @@ maplayersurfacenotify(struct wl_listener *listener, void *data) motionnotify(0); } -void -mapnotify_sub(struct wl_listener *listener, void *data) -{ - Subsurface *s = wl_container_of(listener, s, map); - wlr_output_damage_add_whole(s->c->mon->damage); -} - - void mapnotify(struct wl_listener *listener, void *data) { @@ -1427,6 +1420,15 @@ mapnotify(struct wl_listener *listener, void *data) } } +void +mapnotify_sub(struct wl_listener *listener, void *data) +{ + Subsurface *s = wl_container_of(listener, s, map); + wl_list_insert(&subsurfaces, &s->link); + wlr_output_damage_add_whole(s->c->mon->damage); +} + + void monocle(Monitor *m) { @@ -1567,9 +1569,10 @@ moveresize(const Arg *arg) void new_subnotify(struct wl_listener *listener, void *data) { - Subsurface *s = calloc(1, sizeof(Subsurface)); + struct wlr_subsurface *subsurface = data; + Subsurface *s = subsurface->data = calloc(1, sizeof(*s)); + s->subsurface = subsurface; s->c = wl_container_of(listener, s->c, new_sub); - s->subsurface = data; LISTEN(&s->subsurface->surface->events.commit, &s->commit, commitnotify_sub); LISTEN(&s->subsurface->events.map, &s->map, mapnotify_sub); @@ -2124,6 +2127,7 @@ setup(void) wl_list_init(&fstack); wl_list_init(&stack); wl_list_init(&independents); + wl_list_init(&subsurfaces); idle = wlr_idle_create(dpy); @@ -2376,10 +2380,9 @@ void unmapnotify_sub(struct wl_listener *listener, void *data) { Subsurface *s = wl_container_of(listener, s, unmap); - wlr_output_damage_add_whole(s->c->mon->damage); + wl_list_remove(&s->link); } - void updatemons(struct wl_listener *listener, void *data) {