Compare commits

..

3 Commits

Author SHA1 Message Date
fauxmight
9824f0429a Cleanup/restructure the main dwl-patches README.md 2025-01-03 02:53:47 +00:00
wochap
f87556707d update scenefx patch link for 0.8
new  patch includes fixes and new options
2025-01-03 00:44:42 +00:00
wochap
72c5d436ab scenefx fixes
- fix: Remove rounded borders and shadows when toggling fullscreen mode
- feat: Add two new options: `shadow_ignore_list` and `corner_radius_only_floating`
2025-01-03 00:40:58 +00:00
3 changed files with 185 additions and 95 deletions

View File

@ -1,38 +1,29 @@
# dwl-patches # dwl-patches
* A general [dwl wiki](https://codeberg.org/dwl/dwl/wiki) is available at the main [dwl] page. * A general [dwl wiki](https://codeberg.org/dwl/dwl/wiki) is available at the main [dwl] repository.
* This repository is exclusively for dwl PATCHES. * This repository is exclusively for dwl PATCHES.
## _STALE_PATCHES *Note: All patches are user-submitted content. The authors of dwl do not continually monitor them. You are responsible for downloading and reviewing a patch before using it!*
Many patches previously in regular use do not cleanly apply to the current code base. Following the migration to Codeberg, these stale patch descriptions were relocated to [_STALE_PATCHES].
Additionally, patches that have been deprecated by their author(s)/maintainer(s) may be found in [_STALE_PATCHES]. ## Reporting Issues
- Issues with existing patches can be generated here in the dwl-patches [issues]. Please be sure to "@" reference the patch author in your issue.
If you are an original author of one of these or you have the inclination to revive one of these, please follow the same procedures outlined below for contributing new patches. ## Contributing Patches to `dwl-patches`
In your initial pull request (or in the commit that revives the stale patch if you already have write access), remove the `.md` file or the patch directory from [_STALE_PATCHES] for the patch which you have revived.
## Patching
Since dwl follows [suckless](https://suckless.org/) philosophy, it doesn't provide every feature under the sun. To broaden dwl's functionality, one needs to get familiar with the concept of patching. To get your feet wet, consult [the hacking page](https://suckless.org/hacking/) of the suckless website. Since dwl follows [suckless](https://suckless.org/) philosophy, it doesn't provide every feature under the sun. To broaden dwl's functionality, one needs to get familiar with the concept of patching. To get your feet wet, consult [the hacking page](https://suckless.org/hacking/) of the suckless website.
Patches should normally target the latest dwl [release]. Patches should normally target the latest dwl [release].
If you target an older release, specify that in the `Download` link on your `README.md` page. If you target an older release, specify that in the `Download` link on your `README.md` page.
If you target the unstable `main` branch, specify that in the `Download` link on your `README.md` page. If you target the unstable `main` branch, specify that in the `Download` link on your `README.md` page.
*Note: These external patches are user-submitted content, and the authors of dwl cannot monitor them. Please download and review a patch before using it!* 0. Starting from a local clone of [dwl] (not dwl-patches)
## Reporting Issues
- Issues with existing patches can be generated here in the dwl-patches [issues]. Please be sure to "@" reference the patch author in your issue.
## Contributing Patches to `dwl-patches`
1. If you do not have it already, add the remote for the main dwl repository in your local copy and fetch it: 1. If you do not have it already, add the remote for the main dwl repository in your local copy and fetch it:
`git remote add --fetch upstream https://codeberg.org/dwl/dwl` `git remote add --fetch upstream https://codeberg.org/dwl/dwl`
2. In your local repository of dwl, create a .patch file 2. Use git to create a branch for your new patch and hack away creating your patched version of [dwl].
3. In your local clone of dwl, create a .patch file
`git format-patch upstream/main...<branch-name> --stdout > PATCHNAME.patch` `git format-patch upstream/main...<branch-name> --stdout > PATCHNAME.patch`
3. Fork [https://codeberg.org/dwl/dwl-patches][dwl-patches] 4. Now fork [dwl-patches] (not dwl) in Codeberg and clone it locally
4. Configure your repository 5. Configure your `dwl-patches` local clone
`git config --local pull.rebase true` `git config --local pull.rebase true`
5. In your local copy, add a directory called `patches/PATCHNAME`. Place the `PATCHNAME.patch` you created in step three into the `patches/PATCHNAME` directory. 6. In your local `dwl-patches` clone, add a directory called `patches/PATCHNAME`. Place the `PATCHNAME.patch` you created in step (2) into the `patches/PATCHNAME` directory.
6. Use the Codeberg web interface to send a pull request to [dwl-patches] (NOT to [dwl]) (Codeberg nicely will generate a URL for you)
7. Add a `README.md` page to the `PATCHNAME` directory using this template (add/remove sections as you like): 7. Add a `README.md` page to the `PATCHNAME` directory using this template (add/remove sections as you like):
```markdown ```markdown
### Description ### Description
@ -54,12 +45,13 @@ If you target the unstable `main` branch, specify that in the `Download` link on
``` ```
You may choose to include screenshots (hosted in your patch's subdirectory) in your `README.md`. The process is described [here](https://docs.codeberg.org/markdown/using-images/). You may choose to include screenshots (hosted in your patch's subdirectory) in your `README.md`. The process is described [here](https://docs.codeberg.org/markdown/using-images/).
8. WHEN YOUR PULL REQUEST IS APPROVED, your Codeberg account will also be granted commit access to [dwl-patches]. Once you have write access, you can make direct modifications/upates to your patches instead of pull requests. 8. Use the Codeberg web interface to send a pull request to [dwl-patches] (NOT to [dwl])
9. WHEN YOUR PULL REQUEST IS APPROVED, your Codeberg account will also be granted commit access to [dwl-patches]. Once you have write access, you can make direct modifications/upates to your patches instead of pull requests.
## Updating/Modifying Existing Patches ## Updating/Modifying/Adopting Existing Patches
- If the existing patch is already being maintained by another author, do not make modifications to it without permission. - If the existing patch is already being maintained by another author, do not make modifications to it.
- Create an issue at [issues] @mentioning the current maintainer - Create an issue at [issues] @mentioning the current maintainer.
- If you receive no reply for seven days, you may adopt the patch. - If you receive no reply for seven days, you may assume the patch abandoned and you may adopt the patch.
- Modify the `README.md` with new links for your raw patch and for your git branch. - Modify the `README.md` with new links for your raw patch and for your git branch.
- **LEAVE PREVIOUS AUTHOR(S)' NICKS/LINKS INTACT UNDER THE "Authors" HEADING!** - **LEAVE PREVIOUS AUTHOR(S)' NICKS/LINKS INTACT UNDER THE "Authors" HEADING!**
- Add your own nick/link to the top of the "Authors" list. - Add your own nick/link to the top of the "Authors" list.
@ -73,6 +65,13 @@ If you target the unstable `main` branch, specify that in the `Download` link on
- May explain in the associated `README.md` any relevant details of the decision to deprecate the patch. - May explain in the associated `README.md` any relevant details of the decision to deprecate the patch.
- This process allows current or future users of the patch the option to adopt, modify, or integrate stale/historical code or portions thereof. - This process allows current or future users of the patch the option to adopt, modify, or integrate stale/historical code or portions thereof.
## _STALE_PATCHES
Deprecated or unmaintained patches are held in the _STALE_PATCHES directory.
Currently, this directory also contains `.md` description files from ancient patches predating the move to Codeberg.
If you have the inclination to revive one of these, please follow the same procedures outlined below for contributing new patches.
In your initial pull request (or in the commit that revives the stale patch if you already have write access), remove the corresponding `.md` file or the patch directory from [_STALE_PATCHES].
[_STALE_PATCHES]:https://codeberg.org/dwl/dwl-patches/src/branch/main/_STALE_PATCHES [_STALE_PATCHES]:https://codeberg.org/dwl/dwl-patches/src/branch/main/_STALE_PATCHES
[dwl]: https://codeberg.org/dwl/dwl [dwl]: https://codeberg.org/dwl/dwl

View File

@ -15,9 +15,11 @@ static const struct wlr_render_color shadow_color = COLOR(0x0000FFff);
static const struct wlr_render_color shadow_color_focus = COLOR(0xFF0000ff); static const struct wlr_render_color shadow_color_focus = COLOR(0xFF0000ff);
static const int shadow_blur_sigma = 20; static const int shadow_blur_sigma = 20;
static const int shadow_blur_sigma_focus = 40; static const int shadow_blur_sigma_focus = 40;
static const char *const shadow_ignore_list[] = { NULL }; /* list of app-id to ignore */
static const int corner_radius = 0; /* 0 disables corner_radius */ static const int corner_radius = 0; /* 0 disables corner_radius */
static const int corner_radius_inner = 3; /* 0 disables corner_radius */ static const int corner_radius_inner = 3; /* 0 disables corner_radius */
static const int corner_radius_only_floating = 0; /* only apply corner_radius and corner_radius_inner to floating windows */
static const int blur = 1; /* flag to enable blur */ static const int blur = 1; /* flag to enable blur */
static const int blur_optimized = 1; static const int blur_optimized = 1;
@ -49,7 +51,7 @@ static const struct blur_data blur_data = {
- [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.8-a/scenefx) - [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.8-a/scenefx)
- [0.8](https://codeberg.org/dwl/dwl-patches/raw/commit/494baec5b107114b74d243440aa8581fe6c03e48/patches/scenefx/scenefx.patch) - [0.8](https://codeberg.org/dwl/dwl-patches/raw/commit/72c5d436abef385456877f210f1d1876c88d68e3/patches/scenefx/scenefx.patch)
**NOTE:** This patch was tested with the `b2e0ac4beb85aa89d0357dc8fcf8762808650890` commit on the `main` branch of `SceneFX`. It supports rounded borders, blur, and shadows. **NOTE:** This patch was tested with the `b2e0ac4beb85aa89d0357dc8fcf8762808650890` commit on the `main` branch of `SceneFX`. It supports rounded borders, blur, and shadows.

View File

@ -1,14 +1,14 @@
From a0a4de0305a5f06431f8162d37070fffd9ad9dd8 Mon Sep 17 00:00:00 2001 From 059a0c8988967e23807e4f78920816f679dbc068 Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com> From: wochap <gean.marroquin@gmail.com>
Date: Tue, 24 Dec 2024 21:49:50 -0500 Date: Thu, 2 Jan 2025 19:06:36 -0500
Subject: [PATCH] feat: implement scenefx Subject: [PATCH] implement scenefx
--- ---
Makefile | 2 +- Makefile | 2 +-
client.h | 10 ++- client.h | 14 ++-
config.def.h | 28 +++++- config.def.h | 30 ++++-
dwl.c | 236 ++++++++++++++++++++++++++++++++++++++++++++++++++- dwl.c | 319 ++++++++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 268 insertions(+), 8 deletions(-) 4 files changed, 355 insertions(+), 10 deletions(-)
diff --git a/Makefile b/Makefile diff --git a/Makefile b/Makefile
index 3358bae..20b15bb 100644 index 3358bae..20b15bb 100644
@ -24,15 +24,19 @@ index 3358bae..20b15bb 100644
LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` -lm $(LIBS) LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` -lm $(LIBS)
diff --git a/client.h b/client.h diff --git a/client.h b/client.h
index 42f225f..12faec4 100644 index 42f225f..e3cef30 100644
--- a/client.h --- a/client.h
+++ b/client.h +++ b/client.h
@@ -138,8 +138,8 @@ client_get_clip(Client *c, struct wlr_box *clip) @@ -136,10 +136,10 @@ client_get_clip(Client *c, struct wlr_box *clip)
{
struct wlr_box xdg_geom = {0};
*clip = (struct wlr_box){ *clip = (struct wlr_box){
.x = 0, - .x = 0,
.y = 0, - .y = 0,
- .width = c->geom.width - c->bw, - .width = c->geom.width - c->bw,
- .height = c->geom.height - c->bw, - .height = c->geom.height - c->bw,
+ .x = c->bw,
+ .y = c->bw,
+ .width = c->geom.width - c->bw * 2, + .width = c->geom.width - c->bw * 2,
+ .height = c->geom.height - c->bw * 2, + .height = c->geom.height - c->bw * 2,
}; };
@ -52,10 +56,10 @@ index 42f225f..12faec4 100644
wlr_scene_rect_set_color(c->border[i], color); wlr_scene_rect_set_color(c->border[i], color);
} }
diff --git a/config.def.h b/config.def.h diff --git a/config.def.h b/config.def.h
index 22d2171..a7ebe80 100644 index 22d2171..d4e85c1 100644
--- a/config.def.h --- a/config.def.h
+++ b/config.def.h +++ b/config.def.h
@@ -12,7 +12,33 @@ static const float bordercolor[] = COLOR(0x444444ff); @@ -12,7 +12,35 @@ static const float bordercolor[] = COLOR(0x444444ff);
static const float focuscolor[] = COLOR(0x005577ff); static const float focuscolor[] = COLOR(0x005577ff);
static const float urgentcolor[] = COLOR(0xff0000ff); static const float urgentcolor[] = COLOR(0xff0000ff);
/* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */ /* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */
@ -67,14 +71,16 @@ index 22d2171..a7ebe80 100644
+static const float opacity_active = 1.0; +static const float opacity_active = 1.0;
+ +
+static const int shadow = 1; /* flag to enable shadow */ +static const int shadow = 1; /* flag to enable shadow */
+static const int shadow_only_floating = 1; /* only apply shadow to floating windows */ +static const int shadow_only_floating = 0; /* only apply shadow to floating windows */
+static const float shadow_color[4] = COLOR(0x0000FFff); +static const float shadow_color[4] = COLOR(0x0000FFff);
+static const float shadow_color_focus[4] = COLOR(0xFF0000ff); +static const float shadow_color_focus[4] = COLOR(0xFF0000ff);
+static const int shadow_blur_sigma = 20; +static const int shadow_blur_sigma = 20;
+static const int shadow_blur_sigma_focus = 40; +static const int shadow_blur_sigma_focus = 40;
+static const char *const shadow_ignore_list[] = { NULL }; /* list of app-id to ignore */
+ +
+static const int corner_radius = 8; /* 0 disables corner_radius */ +static const int corner_radius = 8; /* 0 disables corner_radius */
+static const int corner_radius_inner = 3; /* 0 disables corner_radius */ +static const int corner_radius_inner = 8; /* 0 disables corner_radius */
+static const int corner_radius_only_floating = 0; /* only apply corner_radius and corner_radius_inner to floating windows */
+ +
+static const int blur = 1; /* flag to enable blur */ +static const int blur = 1; /* flag to enable blur */
+static const int blur_optimized = 1; +static const int blur_optimized = 1;
@ -91,7 +97,7 @@ index 22d2171..a7ebe80 100644
/* tagging - TAGCOUNT must be no greater than 31 */ /* tagging - TAGCOUNT must be no greater than 31 */
#define TAGCOUNT (9) #define TAGCOUNT (9)
diff --git a/dwl.c b/dwl.c diff --git a/dwl.c b/dwl.c
index 5bf995e..a9f8277 100644 index 5bf995e..3c551dc 100644
--- a/dwl.c --- a/dwl.c
+++ b/dwl.c +++ b/dwl.c
@@ -10,8 +10,13 @@ @@ -10,8 +10,13 @@
@ -129,17 +135,19 @@ index 5bf995e..a9f8277 100644
} Client; } Client;
typedef struct { typedef struct {
@@ -355,6 +365,9 @@ static Monitor *xytomon(double x, double y); @@ -355,6 +365,11 @@ static Monitor *xytomon(double x, double y);
static void xytonode(double x, double y, struct wlr_surface **psurface, static void xytonode(double x, double y, struct wlr_surface **psurface,
Client **pc, LayerSurface **pl, double *nx, double *ny); Client **pc, LayerSurface **pl, double *nx, double *ny);
static void zoom(const Arg *arg); static void zoom(const Arg *arg);
+static void iter_xdg_scene_buffers(struct wlr_scene_buffer *buffer, int sx, int sy, void *user_data); +static void iter_xdg_scene_buffers(struct wlr_scene_buffer *buffer, int sx, int sy, void *user_data);
+static void iter_xdg_scene_buffers_opacity(struct wlr_scene_buffer *buffer, int sx, int sy, void *user_data); +static void iter_xdg_scene_buffers_opacity(struct wlr_scene_buffer *buffer, int sx, int sy, void *user_data);
+static void iter_xdg_scene_buffers_corner_radius(struct wlr_scene_buffer *buffer, int sx, int sy, void *user_data);
+static void output_configure_scene(struct wlr_scene_node *node, Client *c); +static void output_configure_scene(struct wlr_scene_node *node, Client *c);
+static int in_shadow_ignore_list(const char *str);
/* variables */ /* variables */
static const char broken[] = "broken"; static const char broken[] = "broken";
@@ -366,6 +379,8 @@ static struct wl_event_loop *event_loop; @@ -366,6 +381,8 @@ static struct wl_event_loop *event_loop;
static struct wlr_backend *backend; static struct wlr_backend *backend;
static struct wlr_scene *scene; static struct wlr_scene *scene;
static struct wlr_scene_tree *layers[NUM_LAYERS]; static struct wlr_scene_tree *layers[NUM_LAYERS];
@ -148,7 +156,7 @@ index 5bf995e..a9f8277 100644
static struct wlr_scene_tree *drag_icon; static struct wlr_scene_tree *drag_icon;
/* Map from ZWLR_LAYER_SHELL_* constants to Lyr* enum */ /* Map from ZWLR_LAYER_SHELL_* constants to Lyr* enum */
static const int layermap[] = { LyrBg, LyrBottom, LyrTop, LyrOverlay }; static const int layermap[] = { LyrBg, LyrBottom, LyrTop, LyrOverlay };
@@ -413,6 +428,8 @@ static struct wlr_box sgeom; @@ -413,6 +430,8 @@ static struct wlr_box sgeom;
static struct wl_list mons; static struct wl_list mons;
static Monitor *selmon; static Monitor *selmon;
@ -157,7 +165,7 @@ index 5bf995e..a9f8277 100644
#ifdef XWAYLAND #ifdef XWAYLAND
static void activatex11(struct wl_listener *listener, void *data); static void activatex11(struct wl_listener *listener, void *data);
static void associatex11(struct wl_listener *listener, void *data); static void associatex11(struct wl_listener *listener, void *data);
@@ -1061,6 +1078,9 @@ createnotify(struct wl_listener *listener, void *data) @@ -1061,6 +1080,9 @@ createnotify(struct wl_listener *listener, void *data)
c->surface.xdg = toplevel->base; c->surface.xdg = toplevel->base;
c->bw = borderpx; c->bw = borderpx;
@ -167,7 +175,7 @@ index 5bf995e..a9f8277 100644
LISTEN(&toplevel->base->surface->events.commit, &c->commit, commitnotify); LISTEN(&toplevel->base->surface->events.commit, &c->commit, commitnotify);
LISTEN(&toplevel->base->surface->events.map, &c->map, mapnotify); LISTEN(&toplevel->base->surface->events.map, &c->map, mapnotify);
LISTEN(&toplevel->base->surface->events.unmap, &c->unmap, unmapnotify); LISTEN(&toplevel->base->surface->events.unmap, &c->unmap, unmapnotify);
@@ -1369,8 +1389,20 @@ focusclient(Client *c, int lift) @@ -1369,8 +1391,20 @@ focusclient(Client *c, int lift)
/* Don't change border color if there is an exclusive focus or we are /* Don't change border color if there is an exclusive focus or we are
* handling a drag operation */ * handling a drag operation */
@ -189,7 +197,7 @@ index 5bf995e..a9f8277 100644
} }
/* Deactivate old client if focus is changing */ /* Deactivate old client if focus is changing */
@@ -1389,6 +1421,17 @@ focusclient(Client *c, int lift) @@ -1389,6 +1423,17 @@ focusclient(Client *c, int lift)
} else if (old_c && !client_is_unmanaged(old_c) && (!c || !client_wants_focus(c))) { } else if (old_c && !client_is_unmanaged(old_c) && (!c || !client_wants_focus(c))) {
client_set_border_color(old_c, bordercolor); client_set_border_color(old_c, bordercolor);
@ -207,33 +215,21 @@ index 5bf995e..a9f8277 100644
client_activate_surface(old, 0); client_activate_surface(old, 0);
} }
} }
@@ -1700,6 +1743,8 @@ mapnotify(struct wl_listener *listener, void *data) @@ -1718,6 +1763,21 @@ mapnotify(struct wl_listener *listener, void *data)
client_get_geometry(c, &c->geom);
+ wlr_scene_node_for_each_buffer(&c->scene_surface->node, iter_xdg_scene_buffers, c);
+
/* Handle unmanaged clients first so we can return prior create borders */
if (client_is_unmanaged(c)) {
/* Unmanaged clients always are floating */
@@ -1718,6 +1763,24 @@ mapnotify(struct wl_listener *listener, void *data)
c->border[i]->node.data = c; c->border[i]->node.data = c;
} }
+ wlr_scene_node_for_each_buffer(&c->scene_surface->node, iter_xdg_scene_buffers, c);
+
+ if (corner_radius > 0) { + if (corner_radius > 0) {
+ c->round_border = wlr_scene_rect_create(c->scene, 0, 0, c->isurgent ? urgentcolor : bordercolor); + c->round_border = wlr_scene_rect_create(c->scene, 0, 0, c->isurgent ? urgentcolor : bordercolor);
+ c->round_border->node.data = c; + c->round_border->node.data = c;
+ wlr_scene_rect_set_corner_radius(c->round_border, c->corner_radius + c->bw);
+ /* Lower the border below the XDG scene tree */ + /* Lower the border below the XDG scene tree */
+ wlr_scene_node_lower_to_bottom(&c->round_border->node); + wlr_scene_node_lower_to_bottom(&c->round_border->node);
+ } + }
+ +
+ if (shadow) { + if (shadow) {
+ c->shadow = wlr_scene_shadow_create(c->scene, 0, 0, c->corner_radius, shadow_blur_sigma, shadow_color); + c->shadow = wlr_scene_shadow_create(c->scene, 0, 0, c->corner_radius, shadow_blur_sigma, shadow_color);
+ c->has_shadow_enabled = shadow_only_floating != 1;
+ if (!c->has_shadow_enabled) {
+ wlr_scene_shadow_set_color(c->shadow, transparent);
+ }
+ /* Lower the shadow below the border */ + /* Lower the shadow below the border */
+ wlr_scene_node_lower_to_bottom(&c->shadow->node); + wlr_scene_node_lower_to_bottom(&c->shadow->node);
+ } + }
@ -241,24 +237,33 @@ index 5bf995e..a9f8277 100644
/* Initialize client geometry with room for border */ /* Initialize client geometry with room for border */
client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT); client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT);
c->geom.width += 2 * c->bw; c->geom.width += 2 * c->bw;
@@ -1739,6 +1802,16 @@ mapnotify(struct wl_listener *listener, void *data) @@ -1739,6 +1799,25 @@ mapnotify(struct wl_listener *listener, void *data)
} }
printstatus(); printstatus();
+ if (shadow && shadow_only_floating) { + if (corner_radius > 0) {
+ if (c->isfloating) { + int radius = c->corner_radius + c->bw;
+ c->has_shadow_enabled = 1; + if ((corner_radius_only_floating && !c->isfloating) || c->isfullscreen) {
+ wlr_scene_shadow_set_color(c->shadow, focustop(c->mon) == c ? shadow_color_focus : shadow_color); + radius = 0;
+ } else {
+ c->has_shadow_enabled = 0;
+ wlr_scene_shadow_set_color(c->shadow, transparent);
+ } + }
+ wlr_scene_rect_set_corner_radius(c->round_border, radius);
+ }
+
+ if (shadow) {
+ const float *color = focustop(c->mon) == c ? shadow_color_focus : shadow_color;
+ int has_shadow_enabled = 1;
+ if ((shadow_only_floating && !c->isfloating) || in_shadow_ignore_list(client_get_appid(c)) || c->isfullscreen) {
+ color = transparent;
+ has_shadow_enabled = 0;
+ }
+ wlr_scene_shadow_set_color(c->shadow, color);
+ c->has_shadow_enabled = has_shadow_enabled;
+ } + }
+ +
unset_fullscreen: unset_fullscreen:
m = c->mon ? c->mon : xytomon(c->geom.x, c->geom.y); m = c->mon ? c->mon : xytomon(c->geom.x, c->geom.y);
wl_list_for_each(w, &clients, link) { wl_list_for_each(w, &clients, link) {
@@ -2113,6 +2186,8 @@ rendermon(struct wl_listener *listener, void *data) @@ -2113,6 +2192,8 @@ rendermon(struct wl_listener *listener, void *data)
goto skip; goto skip;
} }
@ -267,7 +272,7 @@ index 5bf995e..a9f8277 100644
/* /*
* HACK: The "correct" way to set the gamma is to commit it together with * 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 * the rest of the state in one go, but to do that we would need to rewrite
@@ -2181,6 +2256,8 @@ resize(Client *c, struct wlr_box geo, int interact) @@ -2181,6 +2262,8 @@ resize(Client *c, struct wlr_box geo, int interact)
{ {
struct wlr_box *bbox; struct wlr_box *bbox;
struct wlr_box clip; struct wlr_box clip;
@ -276,7 +281,7 @@ index 5bf995e..a9f8277 100644
if (!c->mon || !c->scene) if (!c->mon || !c->scene)
return; return;
@@ -2207,6 +2284,19 @@ resize(Client *c, struct wlr_box geo, int interact) @@ -2207,6 +2290,20 @@ resize(Client *c, struct wlr_box geo, int interact)
c->geom.height - 2 * c->bw); c->geom.height - 2 * c->bw);
client_get_clip(c, &clip); client_get_clip(c, &clip);
wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip); wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip);
@ -284,6 +289,7 @@ index 5bf995e..a9f8277 100644
+ if (corner_radius > 0) { + if (corner_radius > 0) {
+ wlr_scene_node_set_position(&c->round_border->node, 0, 0); + wlr_scene_node_set_position(&c->round_border->node, 0, 0);
+ wlr_scene_rect_set_size(c->round_border, c->geom.width, c->geom.height); + wlr_scene_rect_set_size(c->round_border, c->geom.width, c->geom.height);
+ /* hide original border */
+ for (i = 0; i < 4; i++) + for (i = 0; i < 4; i++)
+ wlr_scene_rect_set_color(c->border[i], transparent); + wlr_scene_rect_set_color(c->border[i], transparent);
+ } + }
@ -296,29 +302,67 @@ index 5bf995e..a9f8277 100644
} }
void void
@@ -2307,6 +2397,21 @@ setfloating(Client *c, int floating) @@ -2307,6 +2404,29 @@ setfloating(Client *c, int floating)
{ {
Client *p = client_get_parent(c); Client *p = client_get_parent(c);
c->isfloating = floating; c->isfloating = floating;
+ +
+ if (shadow && shadow_only_floating) { + if (corner_radius > 0 && c->round_border != NULL) {
+ if (c->isfloating) { + int radius = c->corner_radius + c->bw;
+ c->has_shadow_enabled = 1; + if ((corner_radius_only_floating && !c->isfloating) || c->isfullscreen) {
+ if (c->shadow != NULL) { + radius = 0;
+ wlr_scene_shadow_set_color(c->shadow, focustop(c->mon) == c ? shadow_color_focus : shadow_color);
+ } + }
+ } else { + wlr_scene_rect_set_corner_radius(c->round_border, radius);
+ c->has_shadow_enabled = 0;
+ if (c->shadow != NULL) {
+ wlr_scene_shadow_set_color(c->shadow, transparent);
+ } + }
+ if (corner_radius_inner > 0 && c->round_border != NULL) {
+ wlr_scene_node_for_each_buffer(&c->scene_surface->node, iter_xdg_scene_buffers_corner_radius, c);
+ } + }
+
+ if (shadow && c->shadow != NULL) {
+ const float *color = focustop(c->mon) == c ? shadow_color_focus : shadow_color;
+ int has_shadow_enabled = 1;
+ if ((shadow_only_floating && !c->isfloating) || in_shadow_ignore_list(client_get_appid(c)) || c->isfullscreen) {
+ color = transparent;
+ has_shadow_enabled = 0;
+ }
+ wlr_scene_shadow_set_color(c->shadow, color);
+ c->has_shadow_enabled = has_shadow_enabled;
+ } + }
+ +
/* If in floating layout do not change the client's layer */ /* If in floating layout do not change the client's layer */
if (!c->mon || !client_surface(c)->mapped || !c->mon->lt[c->mon->sellt]->arrange) if (!c->mon || !client_surface(c)->mapped || !c->mon->lt[c->mon->sellt]->arrange)
return; return;
@@ -2457,11 +2562,17 @@ setup(void) @@ -2336,6 +2456,29 @@ setfullscreen(Client *c, int fullscreen)
* client positions are set by the user and cannot be recalculated */
resize(c, c->prev, 0);
}
+
+ if (corner_radius > 0 && c->round_border != NULL) {
+ int radius = c->corner_radius + c->bw;
+ if ((corner_radius_only_floating && !c->isfloating) || c->isfullscreen) {
+ radius = 0;
+ }
+ wlr_scene_rect_set_corner_radius(c->round_border, radius);
+ }
+ if (corner_radius_inner > 0 && c->round_border != NULL) {
+ wlr_scene_node_for_each_buffer(&c->scene_surface->node, iter_xdg_scene_buffers_corner_radius, c);
+ }
+
+ if (shadow && c->shadow != NULL) {
+ const float *color = focustop(c->mon) == c ? shadow_color_focus : shadow_color;
+ int has_shadow_enabled = 1;
+ if ((shadow_only_floating && !c->isfloating) || in_shadow_ignore_list(client_get_appid(c)) || c->isfullscreen) {
+ color = transparent;
+ has_shadow_enabled = 0;
+ }
+ wlr_scene_shadow_set_color(c->shadow, color);
+ c->has_shadow_enabled = has_shadow_enabled;
+ }
+
arrange(c->mon);
printstatus();
}
@@ -2457,11 +2600,17 @@ setup(void)
drag_icon = wlr_scene_tree_create(&scene->tree); drag_icon = wlr_scene_tree_create(&scene->tree);
wlr_scene_node_place_below(&drag_icon->node, &layers[LyrBlock]->node); wlr_scene_node_place_below(&drag_icon->node, &layers[LyrBlock]->node);
@ -337,7 +381,7 @@ index 5bf995e..a9f8277 100644
die("couldn't create renderer"); die("couldn't create renderer");
LISTEN_STATIC(&drw->events.lost, gpureset); LISTEN_STATIC(&drw->events.lost, gpureset);
@@ -2871,6 +2982,14 @@ updatemons(struct wl_listener *listener, void *data) @@ -2871,6 +3020,14 @@ updatemons(struct wl_listener *listener, void *data)
wlr_scene_node_set_position(&m->fullscreen_bg->node, m->m.x, m->m.y); wlr_scene_node_set_position(&m->fullscreen_bg->node, m->m.x, m->m.y);
wlr_scene_rect_set_size(m->fullscreen_bg, m->m.width, m->m.height); wlr_scene_rect_set_size(m->fullscreen_bg, m->m.width, m->m.height);
@ -352,7 +396,7 @@ index 5bf995e..a9f8277 100644
if (m->lock_surface) { if (m->lock_surface) {
struct wlr_scene_tree *scene_tree = m->lock_surface->surface->data; struct wlr_scene_tree *scene_tree = m->lock_surface->surface->data;
wlr_scene_node_set_position(&scene_tree->node, m->m.x, m->m.y); wlr_scene_node_set_position(&scene_tree->node, m->m.x, m->m.y);
@@ -2940,8 +3059,16 @@ urgent(struct wl_listener *listener, void *data) @@ -2940,8 +3097,16 @@ urgent(struct wl_listener *listener, void *data)
c->isurgent = 1; c->isurgent = 1;
printstatus(); printstatus();
@ -360,7 +404,7 @@ index 5bf995e..a9f8277 100644
+ if (client_surface(c)->mapped) { + if (client_surface(c)->mapped) {
client_set_border_color(c, urgentcolor); client_set_border_color(c, urgentcolor);
+ +
+ if (shadow) { + if (shadow && c->shadow != NULL) {
+ wlr_scene_shadow_set_blur_sigma(c->shadow, shadow_blur_sigma_focus); + wlr_scene_shadow_set_blur_sigma(c->shadow, shadow_blur_sigma_focus);
+ if (c->has_shadow_enabled) { + if (c->has_shadow_enabled) {
+ wlr_scene_shadow_set_color(c->shadow, shadow_color_focus); + wlr_scene_shadow_set_color(c->shadow, shadow_color_focus);
@ -370,7 +414,7 @@ index 5bf995e..a9f8277 100644
} }
void void
@@ -3053,6 +3180,107 @@ zoom(const Arg *arg) @@ -3053,6 +3218,152 @@ zoom(const Arg *arg)
arrange(selmon); arrange(selmon);
} }
@ -396,7 +440,11 @@ index 5bf995e..a9f8277 100644
+ +
+ if (!wlr_subsurface_try_from_wlr_surface(xdg_surface->surface)) { + if (!wlr_subsurface_try_from_wlr_surface(xdg_surface->surface)) {
+ if (corner_radius_inner > 0) { + if (corner_radius_inner > 0) {
+ wlr_scene_buffer_set_corner_radius(buffer, corner_radius_inner, CORNER_LOCATION_ALL); + int radius = corner_radius_inner;
+ if ((corner_radius_only_floating && !c->isfloating) || c->isfullscreen) {
+ radius = 0;
+ }
+ wlr_scene_buffer_set_corner_radius(buffer, radius, CORNER_LOCATION_ALL);
+ } + }
+ +
+ if (blur) { + if (blur) {
@ -431,6 +479,32 @@ index 5bf995e..a9f8277 100644
+} +}
+ +
+void +void
+iter_xdg_scene_buffers_corner_radius(struct wlr_scene_buffer *buffer, int sx, int sy, void *user_data)
+{
+ Client *c = user_data;
+ struct wlr_scene_surface * scene_surface = wlr_scene_surface_try_from_buffer(buffer);
+ struct wlr_xdg_surface *xdg_surface;
+
+ 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? */
+ if (corner_radius_inner > 0) {
+ int radius = corner_radius_inner;
+ if ((corner_radius_only_floating && !c->isfloating) || c->isfullscreen) {
+ radius = 0;
+ }
+ wlr_scene_buffer_set_corner_radius(buffer, radius, CORNER_LOCATION_ALL);
+ }
+ }
+}
+
+void
+output_configure_scene(struct wlr_scene_node *node, Client *c) +output_configure_scene(struct wlr_scene_node *node, Client *c)
+{ +{
+ Client *_c; + Client *_c;
@ -463,7 +537,11 @@ index 5bf995e..a9f8277 100644
+ +
+ if (!wlr_subsurface_try_from_wlr_surface(xdg_surface->surface)) { + if (!wlr_subsurface_try_from_wlr_surface(xdg_surface->surface)) {
+ if (corner_radius_inner > 0) { + if (corner_radius_inner > 0) {
+ wlr_scene_buffer_set_corner_radius(buffer, corner_radius_inner, CORNER_LOCATION_ALL); + int radius = corner_radius_inner;
+ if ((corner_radius_only_floating && !c->isfloating) || c->isfullscreen) {
+ radius = 0;
+ }
+ wlr_scene_buffer_set_corner_radius(buffer, radius, CORNER_LOCATION_ALL);
+ } + }
+ } + }
+ } + }
@ -474,6 +552,17 @@ index 5bf995e..a9f8277 100644
+ } + }
+ } + }
+} +}
+
+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;
+}
+ +
#ifdef XWAYLAND #ifdef XWAYLAND
void void