From df34fdd4831bb4f94ad261d743edcd0493c24f9c Mon Sep 17 00:00:00 2001 From: Jan Beich Date: Fri, 2 Dec 2022 16:37:15 +0000 Subject: [PATCH 01/13] chase default terminal in manpage after 7710cf050d1a --- dwl.1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dwl.1 b/dwl.1 index d958210..cae1036 100644 --- a/dwl.1 +++ b/dwl.1 @@ -51,7 +51,7 @@ Spawn .Nm bemenu-run . .It Mod-Shift-Return Spawn -.Nm alacritty . +.Nm foot . .It Mod-[jk] Move focus down/up the stack. .It Mod-[id] @@ -135,7 +135,7 @@ Start with s6 in the background: .Dl dwl -s 's6-svscan <&-' .Sh SEE ALSO -.Xr alacritty 1 , +.Xr foot 1 , .Xr bemenu 1 , .Xr dwm 1 , .Xr xkeyboard-config 7 From 9c155eefdc018f878ea6950e6bd383b985401339 Mon Sep 17 00:00:00 2001 From: Ben Jargowsky Date: Fri, 2 Dec 2022 11:15:55 -0800 Subject: [PATCH 02/13] Check that inhibitor scene tree is not null --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 5f6d061..7ab649a 100644 --- a/dwl.c +++ b/dwl.c @@ -598,7 +598,7 @@ checkidleinhibitor(struct wlr_surface *exclude) wl_list_for_each(inhibitor, &idle_inhibit_mgr->inhibitors, link) { struct wlr_scene_tree *tree = inhibitor->surface->data; if (bypass_surface_visibility || (exclude != inhibitor->surface - && tree->node.enabled)) { + && tree && tree->node.enabled)) { inhibited = 1; break; } From 035bb99d67b59a84cfc2e911d222fb597591a8be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Fri, 2 Dec 2022 23:22:58 -0600 Subject: [PATCH 03/13] Revert "Check that inhibitor scene tree is not null" This reverts commit 9c155eefdc018f878ea6950e6bd383b985401339. This commit was applied just a workaround, the proper fix is the next commit --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 7ab649a..5f6d061 100644 --- a/dwl.c +++ b/dwl.c @@ -598,7 +598,7 @@ checkidleinhibitor(struct wlr_surface *exclude) wl_list_for_each(inhibitor, &idle_inhibit_mgr->inhibitors, link) { struct wlr_scene_tree *tree = inhibitor->surface->data; if (bypass_surface_visibility || (exclude != inhibitor->surface - && tree && tree->node.enabled)) { + && tree->node.enabled)) { inhibited = 1; break; } From fac3b6f2cf7e2d5e9de2b0618a5a2ad2e0809b03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Fri, 2 Dec 2022 22:53:03 -0600 Subject: [PATCH 04/13] use root surfaces to check idle inhibitors References: https://github.com/djpohly/dwl/pull/343 --- dwl.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dwl.c b/dwl.c index 5f6d061..a635cbe 100644 --- a/dwl.c +++ b/dwl.c @@ -596,8 +596,9 @@ checkidleinhibitor(struct wlr_surface *exclude) int inhibited = 0; struct wlr_idle_inhibitor_v1 *inhibitor; wl_list_for_each(inhibitor, &idle_inhibit_mgr->inhibitors, link) { - struct wlr_scene_tree *tree = inhibitor->surface->data; - if (bypass_surface_visibility || (exclude != inhibitor->surface + struct wlr_surface *surface = wlr_surface_get_root_surface(inhibitor->surface); + struct wlr_scene_tree *tree = surface->data; + if (bypass_surface_visibility || (exclude != surface && tree->node.enabled)) { inhibited = 1; break; @@ -1014,7 +1015,7 @@ destroyidleinhibitor(struct wl_listener *listener, void *data) { /* `data` is the wlr_surface of the idle inhibitor being destroyed, * at this point the idle inhibitor is still in the list of the manager */ - checkidleinhibitor(data); + checkidleinhibitor(wlr_surface_get_root_surface(data)); } void From 017bb7d7521f68d37bfe656c10f45edbcc92dd61 Mon Sep 17 00:00:00 2001 From: Palanix Date: Wed, 31 Aug 2022 06:11:07 +0200 Subject: [PATCH 05/13] fix flickering when resizing/spawning windows Fixes: https://github.com/djpohly/dwl/issues/306 --- client.h | 15 +++++++++++++++ dwl.c | 29 ++++++----------------------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/client.h b/client.h index c18d01a..4dc9e1a 100644 --- a/client.h +++ b/client.h @@ -197,6 +197,21 @@ client_is_mapped(Client *c) return c->surface.xdg->mapped; } +static inline int +client_is_rendered_on_mon(Client *c, Monitor *m) +{ + /* This is needed for when you don't want to check formal assignment, + * but rather actual displaying of the pixels. + * Usually VISIBLEON suffices and is also faster. */ + struct wlr_surface_output *s; + if (!c->scene->node.enabled) + return 0; + wl_list_for_each(s, &client_surface(c)->current_outputs, link) + if (s->output == m->wlr_output) + return 1; + return 0; +} + static inline int client_is_unmanaged(Client *c) { diff --git a/dwl.c b/dwl.c index a635cbe..c409187 100644 --- a/dwl.c +++ b/dwl.c @@ -182,7 +182,6 @@ struct Monitor { unsigned int tagset[2]; double mfact; int nmaster; - int un_map; /* If a map/unmap happened on this monitor, then this should be true */ }; typedef struct { @@ -1393,8 +1392,6 @@ mapnotify(struct wl_listener *listener, void *data) } printstatus(); - c->mon->un_map = 1; - unset_fullscreen: m = c->mon ? c->mon : xytomon(c->geom.x, c->geom.y); wl_list_for_each(w, &clients, link) @@ -1693,30 +1690,19 @@ rendermon(struct wl_listener *listener, void *data) * generally at the output's refresh rate (e.g. 60Hz). */ Monitor *m = wl_container_of(listener, m, frame); Client *c; - int skip = 0; struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - /* Render if no XDG clients have an outstanding resize and are visible on * this monitor. */ - /* Checking m->un_map for every client is not optimal but works */ - wl_list_for_each(c, &clients, link) { - if ((c->resize && m->un_map) || (c->type == XDGShell - && (c->surface.xdg->pending.geometry.width != - c->surface.xdg->current.geometry.width - || c->surface.xdg->pending.geometry.height != - c->surface.xdg->current.geometry.height))) { - /* Lie */ - wlr_surface_send_frame_done(client_surface(c), &now); - skip = 1; - } - } - if (!skip && !wlr_scene_output_commit(m->scene_output)) + wl_list_for_each(c, &clients, link) + if (client_is_rendered_on_mon(c, m) && (!c->isfloating && c->resize)) + goto skip; + if (!wlr_scene_output_commit(m->scene_output)) return; +skip: /* Let clients know a frame has been rendered */ + clock_gettime(CLOCK_MONOTONIC, &now); wlr_scene_output_send_frame_done(m->scene_output, &now); - m->un_map = 0; } void @@ -2281,9 +2267,6 @@ unmapnotify(struct wl_listener *listener, void *data) grabc = NULL; } - if (c->mon) - c->mon->un_map = 1; - if (client_is_unmanaged(c)) { if (c == exclusive_focus) exclusive_focus = NULL; From 30c24a53ad2aaa842bc3b028ba0b98e3362dad7c Mon Sep 17 00:00:00 2001 From: Palanix Date: Sat, 24 Sep 2022 13:37:05 +0200 Subject: [PATCH 06/13] remove unneeded changes in commitnotify() --- dwl.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/dwl.c b/dwl.c index c409187..cea34cc 100644 --- a/dwl.c +++ b/dwl.c @@ -729,14 +729,9 @@ commitnotify(struct wl_listener *listener, void *data) struct wlr_box box = {0}; client_get_geometry(c, &box); - if (c->mon && !wlr_box_empty(&box) && (box.width != c->geom.width - 2 * c->bw - || box.height != c->geom.height - 2 * c->bw)) - arrange(c->mon); /* mark a pending resize as completed */ - if (c->resize && (c->resize <= c->surface.xdg->current.configure_serial - || (c->surface.xdg->current.geometry.width == c->surface.xdg->pending.geometry.width - && c->surface.xdg->current.geometry.height == c->surface.xdg->pending.geometry.height))) + if (c->resize && (c->resize <= c->surface.xdg->current.configure_serial)) c->resize = 0; } From 16a49e99557563252b9f91db767b431e2238f587 Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Sat, 3 Dec 2022 12:06:29 +0200 Subject: [PATCH 07/13] fix null deref in sigchld() if Xwayland is disabled --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index cea34cc..3891cb7 100644 --- a/dwl.c +++ b/dwl.c @@ -2543,7 +2543,7 @@ sigchld(int unused) * XWayland process */ while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid - && in.si_pid != xwayland->server->pid) + && (!xwayland || in.si_pid != xwayland->server->pid)) waitpid(in.si_pid, NULL, 0); } From b6d6127733ea5f96db57a9f47fa4a6134a868a19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 1 Jun 2022 21:38:45 -0500 Subject: [PATCH 08/13] add option for set button map --- config.def.h | 5 +++++ dwl.c | 1 + 2 files changed, 6 insertions(+) diff --git a/config.def.h b/config.def.h index 8f01192..a4f7c13 100644 --- a/config.def.h +++ b/config.def.h @@ -85,6 +85,11 @@ LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE */ static const enum libinput_config_accel_profile accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE; static const double accel_speed = 0.0; +/* You can choose between: +LIBINPUT_CONFIG_TAP_MAP_LRM -- 1/2/3 finger tap maps to left/right/middle +LIBINPUT_CONFIG_TAP_MAP_LMR -- 1/2/3 finger tap maps to left/middle/right +*/ +static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TAP_MAP_LRM; /* If you want to use the windows key for MODKEY, use WLR_MODIFIER_LOGO */ #define MODKEY WLR_MODIFIER_ALT diff --git a/dwl.c b/dwl.c index 3891cb7..2a8162c 100644 --- a/dwl.c +++ b/dwl.c @@ -951,6 +951,7 @@ createpointer(struct wlr_pointer *pointer) libinput_device_config_tap_set_enabled(libinput_device, tap_to_click); libinput_device_config_tap_set_drag_enabled(libinput_device, tap_and_drag); libinput_device_config_tap_set_drag_lock_enabled(libinput_device, drag_lock); + libinput_device_config_tap_set_button_map(libinput_device, button_map); } if (libinput_device_config_scroll_has_natural_scroll(libinput_device)) From 13b929d7d79a7142901d0e7035806ee7f3b7af9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Mon, 5 Dec 2022 23:06:53 -0600 Subject: [PATCH 09/13] remove unneeded call to wlr_scene_rect_set_color() wlr_scene_rect_create() requires a color as parameter --- dwl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/dwl.c b/dwl.c index 2a8162c..c304256 100644 --- a/dwl.c +++ b/dwl.c @@ -1361,7 +1361,6 @@ mapnotify(struct wl_listener *listener, void *data) for (i = 0; i < 4; i++) { c->border[i] = wlr_scene_rect_create(c->scene, 0, 0, bordercolor); c->border[i]->node.data = c; - wlr_scene_rect_set_color(c->border[i], bordercolor); } /* Initialize client geometry with room for border */ From c56bc42eb5480783f3bc97f769bac3d9eebcb373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sat, 3 Dec 2022 14:30:38 -0600 Subject: [PATCH 10/13] sort client_get_parent() --- client.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/client.h b/client.h index 4dc9e1a..b443a8d 100644 --- a/client.h +++ b/client.h @@ -37,19 +37,6 @@ client_from_wlr_surface(struct wlr_surface *s) return NULL; } -static inline Client * -client_get_parent(Client *c) -{ -#ifdef XWAYLAND - if (client_is_x11(c) && c->surface.xwayland->parent) - return client_from_wlr_surface(c->surface.xwayland->parent->surface); -#endif - if (c->surface.xdg->toplevel->parent) - return client_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface); - - return NULL; -} - static inline void client_get_size_hints(Client *c, struct wlr_box *max, struct wlr_box *min) { @@ -153,6 +140,19 @@ client_get_geometry(Client *c, struct wlr_box *geom) wlr_xdg_surface_get_geometry(c->surface.xdg, geom); } +static inline Client * +client_get_parent(Client *c) +{ +#ifdef XWAYLAND + if (client_is_x11(c) && c->surface.xwayland->parent) + return toplevel_from_wlr_surface(c->surface.xwayland->parent->surface); +#endif + if (c->surface.xdg->toplevel->parent) + return toplevel_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface); + + return NULL; +} + static inline const char * client_get_title(Client *c) { From 38bd00351a444d37184716d6124bb47817758bc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sat, 3 Dec 2022 14:31:18 -0600 Subject: [PATCH 11/13] merge toplevel_from_{wlr_layer_surface,popup} into client_from_wlr_surface now it is a big function called toplevel_from_wlr_surface --- client.h | 108 ++++++++++++++++++++++++------------------------------- dwl.c | 10 +++--- 2 files changed, 52 insertions(+), 66 deletions(-) diff --git a/client.h b/client.h index b443a8d..c12a107 100644 --- a/client.h +++ b/client.h @@ -16,27 +16,6 @@ client_is_x11(Client *c) #endif } -static inline Client * -client_from_wlr_surface(struct wlr_surface *s) -{ - struct wlr_xdg_surface *surface; - -#ifdef XWAYLAND - struct wlr_xwayland_surface *xsurface; - if (s && wlr_surface_is_xwayland_surface(s) - && (xsurface = wlr_xwayland_surface_from_wlr_surface(s))) - return xsurface->data; -#endif - if (s && wlr_surface_is_xdg_surface(s) - && (surface = wlr_xdg_surface_from_wlr_surface(s)) - && surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) - return surface->data; - - if (s && wlr_surface_is_subsurface(s)) - return client_from_wlr_surface(wlr_surface_get_root_surface(s)); - return NULL; -} - static inline void client_get_size_hints(Client *c, struct wlr_box *max, struct wlr_box *min) { @@ -72,6 +51,53 @@ client_surface(Client *c) return c->surface.xdg->surface; } +static inline void * +toplevel_from_wlr_surface(struct wlr_surface *s) +{ + struct wlr_xdg_surface *xdg_surface; + struct wlr_surface *root_surface; + struct wlr_layer_surface_v1 *layer_surface; +#ifdef XWAYLAND + struct wlr_xwayland_surface *xsurface; +#endif + + if (!s) + return NULL; + root_surface = wlr_surface_get_root_surface(s); + +#ifdef XWAYLAND + if (wlr_surface_is_xwayland_surface(root_surface) + && (xsurface = wlr_xwayland_surface_from_wlr_surface(root_surface))) + return xsurface->data; +#endif + + if (wlr_surface_is_layer_surface(root_surface) + && (layer_surface = wlr_layer_surface_v1_from_wlr_surface(root_surface))) + return layer_surface->data; + + if (wlr_surface_is_xdg_surface(root_surface) + && (xdg_surface = wlr_xdg_surface_from_wlr_surface(root_surface))) { + while (1) { + switch (xdg_surface->role) { + case WLR_XDG_SURFACE_ROLE_POPUP: + if (!xdg_surface->popup->parent) + return NULL; + else if (!wlr_surface_is_xdg_surface(xdg_surface->popup->parent)) + return toplevel_from_wlr_surface(xdg_surface->popup->parent); + + xdg_surface = wlr_xdg_surface_from_wlr_surface(xdg_surface->popup->parent); + break; + case WLR_XDG_SURFACE_ROLE_TOPLEVEL: + return xdg_surface->data; + case WLR_XDG_SURFACE_ROLE_NONE: + return NULL; + } + } + } + + return NULL; +} + /* The others */ static inline void client_activate_surface(struct wlr_surface *s, int activated) @@ -320,43 +346,3 @@ client_wants_fullscreen(Client *c) #endif return c->surface.xdg->toplevel->requested.fullscreen; } - -static inline void * -toplevel_from_popup(struct wlr_xdg_popup *popup) -{ - struct wlr_xdg_surface *surface = popup->base; - - while (1) { - switch (surface->role) { - case WLR_XDG_SURFACE_ROLE_POPUP: - if (!surface->popup->parent) - return NULL; - else if (wlr_surface_is_layer_surface(surface->popup->parent)) - return wlr_layer_surface_v1_from_wlr_surface(surface->popup->parent)->data; - else if (!wlr_surface_is_xdg_surface(surface->popup->parent)) - return NULL; - - surface = wlr_xdg_surface_from_wlr_surface(surface->popup->parent); - break; - case WLR_XDG_SURFACE_ROLE_TOPLEVEL: - return surface->data; - case WLR_XDG_SURFACE_ROLE_NONE: - return NULL; - } - } -} - -static inline void * -toplevel_from_wlr_layer_surface(struct wlr_surface *s) -{ - Client *c; - struct wlr_layer_surface_v1 *wlr_layer_surface; - - if ((c = client_from_wlr_surface(s))) - return c; - else if (s && wlr_surface_is_layer_surface(s) - && (wlr_layer_surface = wlr_layer_surface_v1_from_wlr_surface(s))) - return wlr_layer_surface->data; - - return NULL; -} diff --git a/dwl.c b/dwl.c index c304256..9c2fc3d 100644 --- a/dwl.c +++ b/dwl.c @@ -908,7 +908,7 @@ createnotify(struct wl_listener *listener, void *data) if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { struct wlr_box box; - LayerSurface *l = toplevel_from_popup(xdg_surface->popup); + LayerSurface *l = toplevel_from_wlr_surface(xdg_surface->surface); if (!xdg_surface->popup->parent) return; xdg_surface->surface->data = wlr_scene_xdg_surface_create( @@ -1096,7 +1096,7 @@ focusclient(Client *c, int lift) /* If an overlay is focused, don't focus or activate the client, * but only update its position in fstack to render its border with focuscolor * and focus it after the overlay is closed. */ - Client *w = client_from_wlr_surface(old); + Client *w = toplevel_from_wlr_surface(old); if (wlr_surface_is_layer_surface(old)) { struct wlr_layer_surface_v1 *wlr_layer_surface = wlr_layer_surface_v1_from_wlr_surface(old); @@ -1472,7 +1472,7 @@ motionnotify(uint32_t time) xytonode(cursor->x, cursor->y, &surface, &c, NULL, &sx, &sy); if (cursor_mode == CurPressed && !seat->drag) { - if ((l = toplevel_from_wlr_layer_surface( + if ((l = toplevel_from_wlr_surface( seat->pointer_state.focused_surface))) { surface = seat->pointer_state.focused_surface; sx = cursor->x - l->geom.x; @@ -2357,8 +2357,8 @@ void urgent(struct wl_listener *listener, void *data) { struct wlr_xdg_activation_v1_request_activate_event *event = data; - Client *c = client_from_wlr_surface(event->surface); - if (c && c != selclient()) { + Client *c = toplevel_from_wlr_surface(event->surface); + if (c && c->type != LayerShell && c != selclient()) { c->isurgent = 1; printstatus(); } From 22336612ae75954c68a7d4cd3f30fbebf94f441f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sat, 3 Dec 2022 15:17:43 -0600 Subject: [PATCH 12/13] improve type safety of toplevel_from_wlr_surface() --- client.h | 47 ++++++++++++++++++++++++++++++++--------------- dwl.c | 49 ++++++++++++++++++++++++------------------------- 2 files changed, 56 insertions(+), 40 deletions(-) diff --git a/client.h b/client.h index c12a107..77cde58 100644 --- a/client.h +++ b/client.h @@ -51,29 +51,38 @@ client_surface(Client *c) return c->surface.xdg->surface; } -static inline void * -toplevel_from_wlr_surface(struct wlr_surface *s) +static inline int +toplevel_from_wlr_surface(struct wlr_surface *s, Client **pc, LayerSurface **pl) { struct wlr_xdg_surface *xdg_surface; struct wlr_surface *root_surface; struct wlr_layer_surface_v1 *layer_surface; + Client *c = NULL; + LayerSurface *l = NULL; + int type = -1; #ifdef XWAYLAND struct wlr_xwayland_surface *xsurface; #endif if (!s) - return NULL; + return type; root_surface = wlr_surface_get_root_surface(s); #ifdef XWAYLAND if (wlr_surface_is_xwayland_surface(root_surface) - && (xsurface = wlr_xwayland_surface_from_wlr_surface(root_surface))) - return xsurface->data; + && (xsurface = wlr_xwayland_surface_from_wlr_surface(root_surface))) { + c = xsurface->data; + type = c->type; + goto end; + } #endif if (wlr_surface_is_layer_surface(root_surface) - && (layer_surface = wlr_layer_surface_v1_from_wlr_surface(root_surface))) - return layer_surface->data; + && (layer_surface = wlr_layer_surface_v1_from_wlr_surface(root_surface))) { + l = layer_surface->data; + type = LayerShell; + goto end; + } if (wlr_surface_is_xdg_surface(root_surface) && (xdg_surface = wlr_xdg_surface_from_wlr_surface(root_surface))) { @@ -81,21 +90,28 @@ toplevel_from_wlr_surface(struct wlr_surface *s) switch (xdg_surface->role) { case WLR_XDG_SURFACE_ROLE_POPUP: if (!xdg_surface->popup->parent) - return NULL; + return -1; else if (!wlr_surface_is_xdg_surface(xdg_surface->popup->parent)) - return toplevel_from_wlr_surface(xdg_surface->popup->parent); + return toplevel_from_wlr_surface(xdg_surface->popup->parent, pc, pl); xdg_surface = wlr_xdg_surface_from_wlr_surface(xdg_surface->popup->parent); break; case WLR_XDG_SURFACE_ROLE_TOPLEVEL: - return xdg_surface->data; + c = xdg_surface->data; + type = c->type; + goto end; case WLR_XDG_SURFACE_ROLE_NONE: - return NULL; + return -1; } } } - return NULL; +end: + if (pl) + *pl = l; + if (pc) + *pc = c; + return type; } /* The others */ @@ -169,14 +185,15 @@ client_get_geometry(Client *c, struct wlr_box *geom) static inline Client * client_get_parent(Client *c) { + Client *p = NULL; #ifdef XWAYLAND if (client_is_x11(c) && c->surface.xwayland->parent) - return toplevel_from_wlr_surface(c->surface.xwayland->parent->surface); + toplevel_from_wlr_surface(c->surface.xwayland->parent->surface, &p, NULL); #endif if (c->surface.xdg->toplevel->parent) - return toplevel_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface); + toplevel_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface, &p, NULL); - return NULL; + return p; } static inline const char * diff --git a/dwl.c b/dwl.c index 9c2fc3d..3d71d19 100644 --- a/dwl.c +++ b/dwl.c @@ -904,22 +904,21 @@ createnotify(struct wl_listener *listener, void *data) * If you want to do something tricky with popups you should check if * its parent is wlr_xdg_shell or wlr_layer_shell */ struct wlr_xdg_surface *xdg_surface = data; - Client *c; + Client *c = NULL; + LayerSurface *l = NULL; if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { struct wlr_box box; - LayerSurface *l = toplevel_from_wlr_surface(xdg_surface->surface); + int type = toplevel_from_wlr_surface(xdg_surface->surface, &c, &l); if (!xdg_surface->popup->parent) return; xdg_surface->surface->data = wlr_scene_xdg_surface_create( xdg_surface->popup->parent->data, xdg_surface); - /* Probably the check of `l` is useless, the only thing that can be NULL - * is its monitor */ - if (!l || !l->mon) + if ((!l || !l->mon) || (!c || !c->mon)) return; - box = l->type == LayerShell ? l->mon->m : l->mon->w; - box.x -= l->geom.x; - box.y -= l->geom.y; + box = type == LayerShell ? l->mon->m : c->mon->w; + box.x -= (type == LayerShell ? l->geom.x : c->geom.x); + box.y -= (type == LayerShell ? l->geom.y : c->geom.y); wlr_xdg_popup_unconstrain_from_box(xdg_surface->popup, &box); return; } else if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_NONE) @@ -1096,15 +1095,12 @@ focusclient(Client *c, int lift) /* If an overlay is focused, don't focus or activate the client, * but only update its position in fstack to render its border with focuscolor * and focus it after the overlay is closed. */ - Client *w = toplevel_from_wlr_surface(old); - if (wlr_surface_is_layer_surface(old)) { - struct wlr_layer_surface_v1 *wlr_layer_surface = - wlr_layer_surface_v1_from_wlr_surface(old); - - if (wlr_layer_surface && ((LayerSurface *)wlr_layer_surface->data)->mapped - && (wlr_layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP - || wlr_layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY)) - return; + Client *w = NULL; + LayerSurface *l = NULL; + int type = toplevel_from_wlr_surface(old, &w, &l); + if (type == LayerShell && l->scene->node.enabled + && l->layer_surface->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) { + return; } else if (w && w == exclusive_focus && client_wants_focus(w)) { return; /* Don't deactivate old client if the new one wants focus, as this causes issues with winecfg @@ -1438,8 +1434,9 @@ void motionnotify(uint32_t time) { double sx = 0, sy = 0; - Client *c = NULL; - LayerSurface *l; + Client *c = NULL, *w = NULL; + LayerSurface *l = NULL; + int type; struct wlr_surface *surface = NULL; struct wlr_drag_icon *icon; @@ -1472,11 +1469,12 @@ motionnotify(uint32_t time) xytonode(cursor->x, cursor->y, &surface, &c, NULL, &sx, &sy); if (cursor_mode == CurPressed && !seat->drag) { - if ((l = toplevel_from_wlr_surface( - seat->pointer_state.focused_surface))) { + if ((type = toplevel_from_wlr_surface( + seat->pointer_state.focused_surface, &w, &l)) >= 0) { + c = w; surface = seat->pointer_state.focused_surface; - sx = cursor->x - l->geom.x; - sy = cursor->y - l->geom.y; + sx = cursor->x - (type == LayerShell ? l->geom.x : w->geom.x); + sy = cursor->y - (type == LayerShell ? l->geom.y : w->geom.y); } } @@ -2357,8 +2355,9 @@ void urgent(struct wl_listener *listener, void *data) { struct wlr_xdg_activation_v1_request_activate_event *event = data; - Client *c = toplevel_from_wlr_surface(event->surface); - if (c && c->type != LayerShell && c != selclient()) { + Client *c = NULL; + int type = toplevel_from_wlr_surface(event->surface, &c, NULL); + if (type >= 0 && type != LayerShell && c != selclient()) { c->isurgent = 1; printstatus(); } From c9a0a8bf6de9130655342e362a5a9f09c6a7fd08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Mon, 5 Dec 2022 23:21:21 -0600 Subject: [PATCH 13/13] bump version to 0.4-rc2 --- config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.mk b/config.mk index c2dd026..86b90ab 100644 --- a/config.mk +++ b/config.mk @@ -1,4 +1,4 @@ -_VERSION = 0.4-rc1 +_VERSION = 0.4-rc2 VERSION = `git describe --long --tags --dirty 2>/dev/null || echo $(_VERSION)` PKG_CONFIG = pkg-config