From b5910af75300551f2d45696e22f5962238add39b Mon Sep 17 00:00:00 2001 From: wochap Date: Sat, 23 Mar 2024 19:12:14 -0500 Subject: [PATCH] Squashed commit of the following: commit dd4b749ca21e3be926e083c01ee6db77843280a9 Author: wochap Date: Sat Mar 23 19:00:15 2024 -0500 regenerate patch commit 35fecb60bbe3d110d190eaee9e254bade06caea5 Author: wochap Date: Sat Mar 23 18:59:21 2024 -0500 feat: add shadow_ignore_list option commit 06b085ee4d3e1301321e36fe9b7a07463ba0e2b0 Author: wochap Date: Sat Mar 23 09:17:30 2024 -0500 regenerate patches commit 536bea34283aafd0b98846560706e6dde62c1eac Author: wochap Date: Sat Mar 23 09:17:01 2024 -0500 add variables to change shadow color|blur_sigma when focused commit 57469a99b3c514eeae604f27287560879826509d Author: wochap Date: Fri Mar 22 11:29:50 2024 -0500 regenerate patches commit 501200f34179b1d05a15674ca8b99d709a8e5870 Author: wochap Date: Fri Mar 22 11:29:30 2024 -0500 fix shadow_only_floating commit 49523d85dafe1734bb76205d52c1b4c9a423cced Author: wochap Date: Fri Mar 22 11:29:10 2024 -0500 fix build warnings/notes commit ad573f6a8552abab97345e823ccaa4850eb7c3fb Author: wochap Date: Fri Mar 22 11:14:18 2024 -0500 add patches commit 4b4f630a60f2f68ffe4992c6a6bcdbc9505e8667 Author: wochap Date: Fri Mar 22 11:12:12 2024 -0500 implement wlrfx/scenefx shadows add options for shadow --- Makefile | 2 +- config.def.h | 7 ++++ dwl.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 117 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 6cde460..f235edf 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ DWLDEVCFLAGS = -g -pedantic -Wall -Wextra -Wdeclaration-after-statement -Wno-unu -Werror=strict-prototypes -Werror=implicit -Werror=return-type -Werror=incompatible-pointer-types # CFLAGS / LDFLAGS -PKGS = wlroots wayland-server xkbcommon libinput $(XLIBS) +PKGS = scenefx wlroots wayland-server xkbcommon libinput $(XLIBS) DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CFLAGS) LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(LIBS) diff --git a/config.def.h b/config.def.h index db0babc..502a2da 100644 --- a/config.def.h +++ b/config.def.h @@ -12,6 +12,13 @@ static const float focuscolor[] = COLOR(0x005577ff); static const float urgentcolor[] = COLOR(0xff0000ff); /* To conform the xdg-protocol, set the alpha to zero to restore the old behavior */ static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0}; /* You can also use glsl colors */ +static const int shadow = 1; +static const int shadow_only_floating = 0; +static const struct wlr_render_color shadow_color = COLOR(0x0000FFff); +static const struct wlr_render_color shadow_color_focus = COLOR(0xFF0000ff); +static const int shadow_blur_sigma = 20; +static const int shadow_blur_sigma_focus = 40; +static const char *const shadow_ignore_list[] = { "xdg-desktop-portal-gtk", "cpupower-gui", NULL }; /* list of app-id to ignore */ /* tagging - TAGCOUNT must be no greater than 31 */ #define TAGCOUNT (9) diff --git a/dwl.c b/dwl.c index ef27a1d..f2103a7 100644 --- a/dwl.c +++ b/dwl.c @@ -9,6 +9,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -37,7 +40,6 @@ #include #include #include -#include #include #include #include @@ -130,6 +132,10 @@ typedef struct { uint32_t tags; int isfloating, isurgent, isfullscreen; uint32_t resize; /* configure serial of a pending resize */ + + float opacity; + int corner_radius; + struct shadow_data shadow_data; } Client; typedef struct { @@ -327,6 +333,8 @@ static Monitor *xytomon(double x, double y); static void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc, LayerSurface **pl, double *nx, double *ny); static void zoom(const Arg *arg); +static int in_shadow_ignore_list(const char *str); +static void output_configure_scene(struct wlr_scene_node *node, Client *c); /* variables */ static const char broken[] = "broken"; @@ -440,6 +448,13 @@ applyrules(Client *c) mon = m; } } + if (shadow_only_floating) { + if (c->isfloating && !in_shadow_ignore_list(appid)) { + c->shadow_data.enabled = 1; + } else { + c->shadow_data.enabled = 0; + } + } wlr_scene_node_reparent(&c->scene->node, layers[c->isfloating ? LyrFloat : LyrTile]); setmon(c, mon, newtags); } @@ -975,6 +990,13 @@ createnotify(struct wl_listener *listener, void *data) wlr_xdg_toplevel_set_wm_capabilities(xdg_surface->toplevel, WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); + c->opacity = 1; + c->corner_radius = 0; + c->shadow_data = shadow_data_get_default(); + c->shadow_data.enabled = shadow_only_floating != 1 && !in_shadow_ignore_list(client_get_appid(c)); + c->shadow_data.blur_sigma = shadow_blur_sigma; + c->shadow_data.color = shadow_color; + LISTEN(&xdg_surface->surface->events.commit, &c->commit, commitnotify); LISTEN(&xdg_surface->surface->events.map, &c->map, mapnotify); LISTEN(&xdg_surface->surface->events.unmap, &c->unmap, unmapnotify); @@ -1204,8 +1226,11 @@ focusclient(Client *c, int lift) /* Don't change border color if there is an exclusive focus or we are * handling a drag operation */ - if (!exclusive_focus && !seat->drag) + if (!exclusive_focus && !seat->drag) { client_set_border_color(c, focuscolor); + c->shadow_data.blur_sigma = shadow_blur_sigma_focus; + c->shadow_data.color = shadow_color_focus; + } } /* Deactivate old client if focus is changing */ @@ -1223,6 +1248,8 @@ focusclient(Client *c, int lift) * and probably other clients */ } else if (old_c && !client_is_unmanaged(old_c) && (!c || !client_wants_focus(c))) { client_set_border_color(old_c, bordercolor); + old_c->shadow_data.blur_sigma = shadow_blur_sigma; + old_c->shadow_data.color = shadow_color; client_activate_surface(old, 0); } @@ -1554,6 +1581,13 @@ mapnotify(struct wl_listener *listener, void *data) /* TODO: https://github.com/djpohly/dwl/pull/334#issuecomment-1330166324 */ if (c->type == XDGShell && (p = client_get_parent(c))) { c->isfloating = 1; + if (shadow_only_floating) { + if (!in_shadow_ignore_list(client_get_appid(c))) { + c->shadow_data.enabled = 1; + } else { + c->shadow_data.enabled = 0; + } + } wlr_scene_node_reparent(&c->scene->node, layers[LyrFloat]); setmon(c, p->mon, p->tags); } else { @@ -1878,6 +1912,10 @@ rendermon(struct wl_listener *listener, void *data) if (c->resize && !c->isfloating && client_is_rendered_on_mon(c, m) && !client_is_stopped(c)) goto skip; + if (shadow) { + output_configure_scene(&m->scene_output->scene->tree.node, NULL); + } + /* * HACK: The "correct" way to set the gamma is to commit it together with * the rest of the state in one go, but to do that we would need to rewrite @@ -2048,6 +2086,13 @@ void setfloating(Client *c, int floating) { c->isfloating = floating; + if (shadow_only_floating) { + if (c->isfloating && !in_shadow_ignore_list(client_get_appid(c))) { + c->shadow_data.enabled = 1; + } else { + c->shadow_data.enabled = 0; + } + } if (!c->mon) return; wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen @@ -2196,7 +2241,7 @@ setup(void) * can also specify a renderer using the WLR_RENDERER env var. * The renderer is responsible for defining the various pixel formats it * supports for shared memory, this configures that for clients. */ - if (!(drw = wlr_renderer_autocreate(backend))) + if (!(drw = fx_renderer_create(backend))) die("couldn't create renderer"); /* Create shm, drm and linux_dmabuf interfaces by ourselves. @@ -2650,8 +2695,11 @@ urgent(struct wl_listener *listener, void *data) if (!c || c == focustop(selmon)) return; - if (client_surface(c)->mapped) + if (client_surface(c)->mapped) { client_set_border_color(c, urgentcolor); + c->shadow_data.blur_sigma = shadow_blur_sigma_focus; + c->shadow_data.color = shadow_color_focus; + } c->isurgent = 1; printstatus(); } @@ -2746,6 +2794,63 @@ zoom(const Arg *arg) arrange(selmon); } +int +in_shadow_ignore_list(const char *str) { + for (int i = 0; shadow_ignore_list[i] != NULL; i++) { + if (strcmp(shadow_ignore_list[i], str) == 0) { + return 1; + } + } + return 0; +} + +void +output_configure_scene(struct wlr_scene_node *node, Client *c) +{ + Client *_c; + + if (!node->enabled) { + return; + } + + _c = node->data; + if (_c) { + c = _c; + } + + if (node->type == WLR_SCENE_NODE_BUFFER) { + struct wlr_xdg_surface *xdg_surface; + struct wlr_scene_buffer *buffer = wlr_scene_buffer_from_node(node); + + struct wlr_scene_surface * scene_surface = + wlr_scene_surface_try_from_buffer(buffer); + if (!scene_surface) { + return; + } + + xdg_surface = wlr_xdg_surface_try_from_wlr_surface(scene_surface->surface); + + if (c && + xdg_surface && + xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) { + // TODO: Be able to set whole decoration_data instead of calling + // each individually? + wlr_scene_buffer_set_opacity(buffer, c->opacity); + + if (!wlr_subsurface_try_from_wlr_surface(xdg_surface->surface)) { + wlr_scene_buffer_set_corner_radius(buffer, c->corner_radius); + wlr_scene_buffer_set_shadow_data(buffer, c->shadow_data); + } + } + } else if (node->type == WLR_SCENE_NODE_TREE) { + struct wlr_scene_tree *tree = wl_container_of(node, tree, node); + struct wlr_scene_node *_node; + wl_list_for_each(_node, &tree->children, link) { + output_configure_scene(_node, c); + } + } +} + #ifdef XWAYLAND void activatex11(struct wl_listener *listener, void *data) -- 2.43.2