diff --git a/Makefile b/Makefile index 8304245..f55e2f9 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ DWLDEVCFLAGS = -g -Wpedantic -Wall -Wextra -Wdeclaration-after-statement \ -Wfloat-conversion # CFLAGS / LDFLAGS -PKGS = wayland-server xkbcommon libinput $(XLIBS) +PKGS = scenefx-0.5 wayland-server xkbcommon libinput $(XLIBS) DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(WLR_INCS) $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CFLAGS) LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(WLR_LIBS) -lm $(LIBS) diff --git a/config.def.h b/config.def.h index a4019d3..88029d9 100644 --- a/config.def.h +++ b/config.def.h @@ -18,6 +18,9 @@ static const float fullscreen_bg[] = {0.0f, 0.0f, 0.0f, 1.0f}; /* You ca /* tagging - TAGCOUNT must be no greater than 31 */ #define TAGCOUNT (9) +#define blur_params 2, 2, 0, 0.703125, 0.4375, 0.875 // passes, radius, noise, brightness, contrast, saturation +static int blur_enabled = 1; + /* logging */ static int log_level = WLR_ERROR; @@ -123,6 +126,8 @@ static const Key keys[] = { /* modifier key function argument */ { MODKEY, XKB_KEY_p, spawn, {.v = menucmd} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn, {.v = termcmd} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_B, toggleblur, {0} }, + { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_b, toggleblurfocused,{0} }, { MODKEY, XKB_KEY_j, focusstack, {.i = +1} }, { MODKEY, XKB_KEY_k, focusstack, {.i = -1} }, { MODKEY, XKB_KEY_i, incnmaster, {.i = +1} }, diff --git a/dwl.c b/dwl.c index ca97c30..af50458 100644 --- a/dwl.c +++ b/dwl.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include #include @@ -51,7 +53,6 @@ #include #include #include -#include #include #include #include @@ -88,8 +89,7 @@ /* enums */ enum { CurNormal, CurPressed, CurMove, CurResize }; /* cursor */ enum { XDGShell, LayerShell, X11 }; /* client types */ -enum { LyrBg, LyrBottom, LyrTile, LyrFloat, LyrTop, LyrFS, LyrUnmanaged, LyrOverlay, - LyrIMPopup, LyrBlock, NUM_LAYERS }; /* scene layers */ +enum { LyrBg, LyrBlur, LyrBottom, LyrTile, LyrFloat, LyrTop, LyrFS, LyrUnmanaged, LyrOverlay, LyrIMPopup, LyrBlock, NUM_LAYERS }; /* scene layers */ enum { AxisUp, AxisRight, AxisDown, AxisLeft }; typedef union { @@ -159,6 +159,7 @@ typedef struct { unsigned int bw; uint32_t tags; int isfloating, isurgent, isfullscreen; + struct wlr_scene_blur *blur; } Client; typedef struct { @@ -226,6 +227,7 @@ struct Monitor { int nmaster; char ltsymbol[16]; int asleep; + struct wlr_scene_optimized_blur *blur; }; typedef struct { @@ -357,6 +359,8 @@ static void startdrag(struct wl_listener *listener, void *data); static void tag(const Arg *arg); static void tagmon(const Arg *arg); static void tile(Monitor *m); +static void toggleblur(const Arg *arg); +static void toggleblurfocused(const Arg *arg); static void togglefloating(const Arg *arg); static void togglefullscreen(const Arg *arg); static void toggletag(const Arg *arg); @@ -841,6 +845,8 @@ cleanupmon(struct wl_listener *listener, void *data) closemon(m); wlr_scene_node_destroy(&m->fullscreen_bg->node); + wlr_scene_node_destroy(&m->blur->node); + m->blur = NULL; free(m); } @@ -944,6 +950,7 @@ commitlayersurfacenotify(struct wl_listener *listener, void *data) } arrangelayers(l->mon); + if ((layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND) && (l->mon)) wlr_scene_optimized_blur_mark_dirty(l->mon->blur); } void @@ -990,6 +997,7 @@ commitnotify(struct wl_listener *listener, void *data) } resize(c, c->geom, (c->isfloating && !c->isfullscreen)); + wlr_scene_blur_set_size(c->blur, c->geom.width, c->geom.height); } void @@ -1211,6 +1219,11 @@ createmon(struct wl_listener *listener, void *data) m->fullscreen_bg = wlr_scene_rect_create(layers[LyrFS], 0, 0, fullscreen_bg); wlr_scene_node_set_enabled(&m->fullscreen_bg->node, 0); + m->blur = wlr_scene_optimized_blur_create(&scene->tree, m->m.width, m->m.height); + wlr_scene_node_set_position(&m->blur->node, m->m.x, m->m.y); + wlr_scene_node_reparent(&m->blur->node, layers[LyrBlur]); + wlr_scene_node_set_enabled(&m->blur->node, blur_enabled); + /* Adds this to the output layout in the order it was configured. * * The output layout utility automatically adds a wl_output global to the @@ -1955,6 +1968,11 @@ mapnotify(struct wl_listener *listener, void *data) } printstatus(); + c->blur = wlr_scene_blur_create(c->scene, c->geom.width, c->geom.height); + wlr_scene_node_lower_to_bottom(&c->blur->node); + wlr_scene_blur_set_should_only_blur_bottom_layer(c->blur, true); + wlr_scene_node_set_enabled(&c->blur->node, blur_enabled); + unset_fullscreen: m = c->mon ? c->mon : xytomon(c->geom.x, c->geom.y); wl_list_for_each(w, &clients, link) { @@ -2651,11 +2669,13 @@ setup(void) drag_icon = wlr_scene_tree_create(&scene->tree); wlr_scene_node_place_below(&drag_icon->node, &layers[LyrBlock]->node); + wlr_scene_set_blur_data(scene, blur_params); + /* Autocreates a renderer, either Pixman, GLES2 or Vulkan for us. The user * 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"); wl_signal_add(&drw->events.lost, &gpu_reset); @@ -2933,6 +2953,21 @@ tile(Monitor *m) } } +void toggleblur(const Arg *arg) { + Client *c; + Monitor *m = NULL; + blur_enabled = !blur_enabled; + wl_list_for_each(m, &mons, link) { + wlr_scene_node_set_enabled(&m->blur->node, blur_enabled); + } + wl_list_for_each(c, &clients, link) wlr_scene_node_set_enabled(&c->blur->node, blur_enabled); +} + +void toggleblurfocused(const Arg *arg) { + Client *sel = focustop(selmon); + if (sel && sel->blur) wlr_scene_node_set_enabled(&sel->blur->node, !sel->blur->node.enabled); +} + void togglefloating(const Arg *arg) { @@ -2995,6 +3030,7 @@ unmaplayersurfacenotify(struct wl_listener *listener, void *data) arrangelayers(l->mon); if (l->layer_surface->surface == seat->keyboard_state.focused_surface) focusclient(focustop(selmon), NULL, 1); + if ((l->layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND) && (l->mon)) wlr_scene_optimized_blur_mark_dirty(l->mon->blur); motionnotify(0, NULL, 0, 0, 0, 0); } @@ -3098,6 +3134,9 @@ updatemons(struct wl_listener *listener, void *data) 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_node_set_position(&m->blur->node, m->m.x, m->m.y); + wlr_scene_optimized_blur_set_size(m->blur, m->m.width, m->m.height); + if (m->lock_surface) { 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);