From bfc58b01d0ba0ebd7add0db9aa1dd24f70982769 Mon Sep 17 00:00:00 2001 From: Rajan Saini Date: Mon, 14 Sep 2020 00:57:09 -0700 Subject: [PATCH 01/12] Add foreground blurring --- src/backend/backend.c | 15 ++++++++++++++- src/win.h | 3 +++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/backend/backend.c b/src/backend/backend.c index 59ddcaf2a0..cacf56677d 100644 --- a/src/backend/backend.c +++ b/src/backend/backend.c @@ -433,7 +433,7 @@ void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) { } // Draw window on target - if (w->frame_opacity == 1) { + if (!w->blur_foreground && w->frame_opacity == 1) { ps->backend_data->ops->compose(ps->backend_data, w->win_image, window_coord, NULL, window_coord, ®_paint_in_bound, ®_visible); @@ -480,6 +480,19 @@ void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) { ps->backend_data->ops->release_image(ps->backend_data, new_img); pixman_region32_fini(®_visible_local); pixman_region32_fini(®_bound_local); + + // Blur window + if (w->blur_foreground) { + // FIXME Think more about combining blur w/ opacity + // FIXME Don't hardcode opacity + // - needs to be set when focus_mode set to true + // - don't blur background when foreground is + // getting blurred to speed it up + double blur_opacity = 1; + ps->backend_data->ops->blur( + ps->backend_data, blur_opacity, ps->backend_blur_context, + ®_paint_in_bound, ®_visible); + } } skip: pixman_region32_fini(®_bound); diff --git a/src/win.h b/src/win.h index fe733408b5..c59f9a00af 100644 --- a/src/win.h +++ b/src/win.h @@ -277,6 +277,9 @@ struct managed_win { /// Whether to blur window background. bool blur_background; + /// Whether to blur window foreground. + bool blur_foreground; + /// The custom window shader to use when rendering. struct shader_info *fg_shader; From 7562cb02a26ea4d88a93d24ae9497964f68359d1 Mon Sep 17 00:00:00 2001 From: Rajan Saini Date: Tue, 15 Sep 2020 23:47:09 -0700 Subject: [PATCH 02/12] Add an inactive-blur option --- src/config.c | 1 + src/config.h | 2 ++ src/config_libconfig.c | 6 ++++++ src/options.c | 5 +++++ 4 files changed, 14 insertions(+) diff --git a/src/config.c b/src/config.c index 1013d128fa..53123acbb9 100644 --- a/src/config.c +++ b/src/config.c @@ -781,6 +781,7 @@ char *parse_config(options_t *opt, const char *config_file, bool *shadow_enable, .blur_kernel_count = 0, .window_shader_fg = NULL, .window_shader_fg_rules = NULL, + .inactive_blur = false, .inactive_dim = 0.0, .inactive_dim_fixed = false, .invert_color_list = NULL, diff --git a/src/config.h b/src/config.h index 5ce3ba9635..38ee173681 100644 --- a/src/config.h +++ b/src/config.h @@ -213,6 +213,8 @@ typedef struct options { char *window_shader_fg; /// Rules to change custom fragment shader for painting windows. c2_lptr_t *window_shader_fg_rules; + /// Whether to blur inactive windows + bool inactive_blur; /// How much to dim an inactive window. 0.0 - 1.0, 0 to disable. double inactive_dim; /// Whether to use fixed inactive dim opacity, instead of deciding diff --git a/src/config_libconfig.c b/src/config_libconfig.c index 63f05412bf..4dddf069f2 100644 --- a/src/config_libconfig.c +++ b/src/config_libconfig.c @@ -541,6 +541,12 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad goto err; } } + // --inactive-blur + if (lcfg_lookup_bool(&cfg, "inactive-blur", &opt->inactive_blur)) { + if (opt->blur_method == BLUR_METHOD_NONE) { + opt->blur_method = BLUR_METHOD_BOX; + } + } // --resize-damage config_lookup_int(&cfg, "resize-damage", &opt->resize_damage); // --glx-no-stencil diff --git a/src/options.c b/src/options.c index 9d500b8e65..d5ab753429 100644 --- a/src/options.c +++ b/src/options.c @@ -57,6 +57,7 @@ static const struct picom_option picom_options[] = { {"shadow-blue" , required_argument, 259, NULL , "Blue color value of shadow (0.0 - 1.0, defaults to 0)."}, {"inactive-opacity-override" , no_argument , 260, NULL , "Inactive opacity set by -i overrides value of _NET_WM_WINDOW_OPACITY."}, {"inactive-dim" , required_argument, 261, NULL , "Dim inactive windows. (0.0 - 1.0, defaults to 0)"}, + {"inactive-blur" , no_argument , 341, NULL , "Blur the foreground of inactive windows."}, {"mark-wmwin-focused" , no_argument , 262, NULL , "Try to detect WM windows and mark them as active."}, {"shadow-exclude" , required_argument, 263, NULL , "Exclude conditions for shadows."}, {"mark-ovredir-focused" , no_argument , 264, NULL , "Mark windows that have no WM frame as active."}, @@ -738,6 +739,10 @@ bool get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable, // --dithered-present opt->dithered_present = true; break; + case 341: + // --inactive-blur + opt->inactive_blur = true; + break; P_CASEBOOL(733, legacy_backends); P_CASEBOOL(800, monitor_repaint); case 801: From d9929fd43949d56abd051e90d15174b1a860f797 Mon Sep 17 00:00:00 2001 From: Rajan Saini Date: Tue, 15 Sep 2020 23:47:24 -0700 Subject: [PATCH 03/12] Check for inactive_blur when drawing fg blur --- src/backend/backend.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/backend/backend.c b/src/backend/backend.c index cacf56677d..52515d1f2e 100644 --- a/src/backend/backend.c +++ b/src/backend/backend.c @@ -433,7 +433,8 @@ void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) { } // Draw window on target - if (!w->blur_foreground && w->frame_opacity == 1) { + if (!w->blur_foreground && w->frame_opacity == 1 && + !(ps->o.inactive_blur && !w->focused)) { ps->backend_data->ops->compose(ps->backend_data, w->win_image, window_coord, NULL, window_coord, ®_paint_in_bound, ®_visible); @@ -482,7 +483,8 @@ void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) { pixman_region32_fini(®_bound_local); // Blur window - if (w->blur_foreground) { + if (ps->o.inactive_blur && !w->focused) { + assert(ps->o.blur_method != BLUR_METHOD_NONE); // FIXME Think more about combining blur w/ opacity // FIXME Don't hardcode opacity // - needs to be set when focus_mode set to true From 0279bf1efa0345f81ce337c4b37cdda6b6395c57 Mon Sep 17 00:00:00 2001 From: Dave Shoreman Date: Sun, 23 Jan 2022 01:26:32 +0000 Subject: [PATCH 04/12] Add --inactive-blur-include option Adds an option to specify which windows will be blurred when inactive. --- src/backend/backend.c | 8 +++++--- src/config.c | 7 ++++--- src/config.h | 2 ++ src/config_libconfig.c | 1 + src/options.c | 7 +++++++ src/picom.c | 2 ++ 6 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/backend/backend.c b/src/backend/backend.c index 52515d1f2e..adbceb10fd 100644 --- a/src/backend/backend.c +++ b/src/backend/backend.c @@ -433,8 +433,9 @@ void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) { } // Draw window on target - if (!w->blur_foreground && w->frame_opacity == 1 && - !(ps->o.inactive_blur && !w->focused)) { + if (!w->blur_foreground && w->frame_opacity == 1 && ( + !ps->o.inactive_blur || w->focused || + !c2_match(ps, w, ps->o.inactive_blur_list, NULL))) { ps->backend_data->ops->compose(ps->backend_data, w->win_image, window_coord, NULL, window_coord, ®_paint_in_bound, ®_visible); @@ -483,7 +484,8 @@ void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) { pixman_region32_fini(®_bound_local); // Blur window - if (ps->o.inactive_blur && !w->focused) { + if (ps->o.inactive_blur && !w->focused && + c2_match(ps, w, ps->o.inactive_blur_list, NULL)) { assert(ps->o.blur_method != BLUR_METHOD_NONE); // FIXME Think more about combining blur w/ opacity // FIXME Don't hardcode opacity diff --git a/src/config.c b/src/config.c index 53123acbb9..49f1991460 100644 --- a/src/config.c +++ b/src/config.c @@ -764,6 +764,10 @@ char *parse_config(options_t *opt, const char *config_file, bool *shadow_enable, .no_fading_destroyed_argb = false, .fade_blacklist = NULL, + .inactive_blur = false, + .inactive_blur_list = NULL, + .inactive_dim = 0.0, + .inactive_dim_fixed = false, .inactive_opacity = 1.0, .inactive_opacity_override = false, .active_opacity = 1.0, @@ -781,9 +785,6 @@ char *parse_config(options_t *opt, const char *config_file, bool *shadow_enable, .blur_kernel_count = 0, .window_shader_fg = NULL, .window_shader_fg_rules = NULL, - .inactive_blur = false, - .inactive_dim = 0.0, - .inactive_dim_fixed = false, .invert_color_list = NULL, .opacity_rules = NULL, .max_brightness = 1.0, diff --git a/src/config.h b/src/config.h index 38ee173681..10574287be 100644 --- a/src/config.h +++ b/src/config.h @@ -215,6 +215,8 @@ typedef struct options { c2_lptr_t *window_shader_fg_rules; /// Whether to blur inactive windows bool inactive_blur; + /// List of windows that should be blurred out when inactive. + c2_lptr_t *inactive_blur_list; /// How much to dim an inactive window. 0.0 - 1.0, 0 to disable. double inactive_dim; /// Whether to use fixed inactive dim opacity, instead of deciding diff --git a/src/config_libconfig.c b/src/config_libconfig.c index 4dddf069f2..c6f45fc488 100644 --- a/src/config_libconfig.c +++ b/src/config_libconfig.c @@ -546,6 +546,7 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad if (opt->blur_method == BLUR_METHOD_NONE) { opt->blur_method = BLUR_METHOD_BOX; } + parse_cfg_condlst(&cfg, &opt->inactive_blur_list, "inactive-blur-include"); } // --resize-damage config_lookup_int(&cfg, "resize-damage", &opt->resize_damage); diff --git a/src/options.c b/src/options.c index d5ab753429..7a5aed2777 100644 --- a/src/options.c +++ b/src/options.c @@ -58,6 +58,9 @@ static const struct picom_option picom_options[] = { {"inactive-opacity-override" , no_argument , 260, NULL , "Inactive opacity set by -i overrides value of _NET_WM_WINDOW_OPACITY."}, {"inactive-dim" , required_argument, 261, NULL , "Dim inactive windows. (0.0 - 1.0, defaults to 0)"}, {"inactive-blur" , no_argument , 341, NULL , "Blur the foreground of inactive windows."}, + {"inactive-blur-include" , required_argument, 342, NULL , "Conditions for windows that should be fully blurred when inactive." + "When --inactive-blur is enabled without an --inactive-blur-include" + "condition, the foreground of ALL inactive windows will be blurred."}, {"mark-wmwin-focused" , no_argument , 262, NULL , "Try to detect WM windows and mark them as active."}, {"shadow-exclude" , required_argument, 263, NULL , "Exclude conditions for shadows."}, {"mark-ovredir-focused" , no_argument , 264, NULL , "Mark windows that have no WM frame as active."}, @@ -743,6 +746,10 @@ bool get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable, // --inactive-blur opt->inactive_blur = true; break; + case 342: + // --inactive-blur-include + condlst_add(&opt->inactive_blur_list, optarg); + break; P_CASEBOOL(733, legacy_backends); P_CASEBOOL(800, monitor_repaint); case 801: diff --git a/src/picom.c b/src/picom.c index 8a7a967039..1b85c55873 100644 --- a/src/picom.c +++ b/src/picom.c @@ -1940,6 +1940,7 @@ static session_t *session_init(int argc, char **argv, Display *dpy, c2_list_postprocess(ps, ps->o.shadow_clip_list) && c2_list_postprocess(ps, ps->o.fade_blacklist) && c2_list_postprocess(ps, ps->o.blur_background_blacklist) && + c2_list_postprocess(ps, ps->o.inactive_blur_list) && c2_list_postprocess(ps, ps->o.invert_color_list) && c2_list_postprocess(ps, ps->o.window_shader_fg_rules) && c2_list_postprocess(ps, ps->o.opacity_rules) && @@ -2319,6 +2320,7 @@ static void session_destroy(session_t *ps) { c2_list_free(&ps->o.shadow_clip_list, NULL); c2_list_free(&ps->o.fade_blacklist, NULL); c2_list_free(&ps->o.focus_blacklist, NULL); + c2_list_free(&ps->o.inactive_blur_list, free); c2_list_free(&ps->o.invert_color_list, NULL); c2_list_free(&ps->o.blur_background_blacklist, NULL); c2_list_free(&ps->o.opacity_rules, NULL); From ed53d280c276291bfc4fac0cd8ad976fd3e63a3f Mon Sep 17 00:00:00 2001 From: Dave Shoreman Date: Sun, 23 Jan 2022 02:00:17 +0000 Subject: [PATCH 05/12] Enable blurring all windows without a list If --inactive-blur-include isn't specified, but --inactive-blur *is*, then the sensible default would be to blur all inactive windows. This commit does exactly that. --- src/backend/backend.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backend/backend.c b/src/backend/backend.c index adbceb10fd..6269f4b5e4 100644 --- a/src/backend/backend.c +++ b/src/backend/backend.c @@ -434,8 +434,8 @@ void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) { // Draw window on target if (!w->blur_foreground && w->frame_opacity == 1 && ( - !ps->o.inactive_blur || w->focused || - !c2_match(ps, w, ps->o.inactive_blur_list, NULL))) { + !ps->o.inactive_blur || w->focused || (ps->o.inactive_blur_list && + !c2_match(ps, w, ps->o.inactive_blur_list, NULL)))) { ps->backend_data->ops->compose(ps->backend_data, w->win_image, window_coord, NULL, window_coord, ®_paint_in_bound, ®_visible); @@ -484,8 +484,8 @@ void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) { pixman_region32_fini(®_bound_local); // Blur window - if (ps->o.inactive_blur && !w->focused && - c2_match(ps, w, ps->o.inactive_blur_list, NULL)) { + if (ps->o.inactive_blur && !w->focused && (!ps->o.inactive_blur_list || + c2_match(ps, w, ps->o.inactive_blur_list, NULL))) { assert(ps->o.blur_method != BLUR_METHOD_NONE); // FIXME Think more about combining blur w/ opacity // FIXME Don't hardcode opacity From 4591de0fdd3b62630c1e5117d919fa40eb2bba6d Mon Sep 17 00:00:00 2001 From: Dave Shoreman Date: Sun, 23 Jan 2022 02:53:39 +0000 Subject: [PATCH 06/12] Use `blur_foreground` to simplify conditionals The property was already added in the first commit on this branch, but it wasn't defined so it would've had no effect. With this, the long conditional is easier to read and *should* update automatically. --- src/backend/backend.c | 7 ++----- src/win.c | 4 ++++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/backend/backend.c b/src/backend/backend.c index 6269f4b5e4..9d2a77cf2b 100644 --- a/src/backend/backend.c +++ b/src/backend/backend.c @@ -433,9 +433,7 @@ void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) { } // Draw window on target - if (!w->blur_foreground && w->frame_opacity == 1 && ( - !ps->o.inactive_blur || w->focused || (ps->o.inactive_blur_list && - !c2_match(ps, w, ps->o.inactive_blur_list, NULL)))) { + if (!w->blur_foreground && w->frame_opacity == 1) { ps->backend_data->ops->compose(ps->backend_data, w->win_image, window_coord, NULL, window_coord, ®_paint_in_bound, ®_visible); @@ -484,8 +482,7 @@ void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) { pixman_region32_fini(®_bound_local); // Blur window - if (ps->o.inactive_blur && !w->focused && (!ps->o.inactive_blur_list || - c2_match(ps, w, ps->o.inactive_blur_list, NULL))) { + if (w->blur_foreground) { assert(ps->o.blur_method != BLUR_METHOD_NONE); // FIXME Think more about combining blur w/ opacity // FIXME Don't hardcode opacity diff --git a/src/win.c b/src/win.c index a97733dbd4..f17127796c 100644 --- a/src/win.c +++ b/src/win.c @@ -1234,6 +1234,10 @@ void win_on_factor_change(session_t *ps, struct managed_win *w) { c2_match(ps, w, ps->o.unredir_if_possible_blacklist, NULL); } + if (ps->o.inactive_blur && !w->focused) { + w->blur_foreground = !ps->o.inactive_blur_list || + c2_match(ps, w, ps->o.inactive_blur_list, NULL); + } w->fade_excluded = c2_match(ps, w, ps->o.fade_blacklist, NULL); w->transparent_clipping_excluded = From dced2d40f5de0d55dadf06f54a113890c595e69c Mon Sep 17 00:00:00 2001 From: Dave Shoreman Date: Sun, 23 Jan 2022 04:18:26 +0000 Subject: [PATCH 07/12] Avoid blurring background and foreground together --- src/backend/backend.c | 4 +--- src/render.c | 4 +++- src/win.c | 5 ++++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/backend/backend.c b/src/backend/backend.c index 9d2a77cf2b..1685e912c1 100644 --- a/src/backend/backend.c +++ b/src/backend/backend.c @@ -240,7 +240,7 @@ void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) { auto real_win_mode = w->mode; coord_t window_coord = {.x = w->g.x, .y = w->g.y}; - if (w->blur_background && + if (w->blur_background && !w->blur_foreground && (ps->o.force_win_blend || real_win_mode == WMODE_TRANS || (ps->o.blur_background_frame && real_win_mode == WMODE_FRAME_TRANS))) { // Minimize the region we try to blur, if the window @@ -487,8 +487,6 @@ void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) { // FIXME Think more about combining blur w/ opacity // FIXME Don't hardcode opacity // - needs to be set when focus_mode set to true - // - don't blur background when foreground is - // getting blurred to speed it up double blur_opacity = 1; ps->backend_data->ops->blur( ps->backend_data, blur_opacity, ps->backend_blur_context, diff --git a/src/render.c b/src/render.c index afde7db82b..ac6cfc60bd 100644 --- a/src/render.c +++ b/src/render.c @@ -868,6 +868,8 @@ xr_blur_dst(session_t *ps, xcb_render_picture_t tgt_buffer, int16_t x, int16_t y static inline void win_blur_background(session_t *ps, struct managed_win *w, xcb_render_picture_t tgt_buffer, const region_t *reg_paint) { + assert(w->blur_foreground == false); + const int16_t x = w->g.x; const int16_t y = w->g.y; const auto wid = to_u16_checked(w->widthb); @@ -1157,7 +1159,7 @@ void paint_all(session_t *ps, struct managed_win *t, bool ignore_damage) { #endif // Blur window background - if (w->blur_background && + if (w->blur_background && !w->blur_foreground && (w->mode == WMODE_TRANS || (ps->o.blur_background_frame && w->mode == WMODE_FRAME_TRANS) || ps->o.force_win_blend)) { diff --git a/src/win.c b/src/win.c index f17127796c..faa8d91087 100644 --- a/src/win.c +++ b/src/win.c @@ -1115,7 +1115,10 @@ static void win_determine_blur_background(session_t *ps, struct managed_win *w) return; } - bool blur_background_new = ps->o.blur_method != BLUR_METHOD_NONE; + bool blur_background_new = false; + if (!w->blur_foreground) { + blur_background_new = ps->o.blur_method != BLUR_METHOD_NONE; + } if (blur_background_new) { if (!ps->o.wintype_option[w->window_type].blur_background) { log_debug("Blur background disabled by wintypes"); From 5426688629e99bd4bfc71c380d31a9a9f94ac832 Mon Sep 17 00:00:00 2001 From: Dave Shoreman Date: Sun, 23 Jan 2022 04:33:54 +0000 Subject: [PATCH 08/12] Fix active window also being blurred --- src/win.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/win.c b/src/win.c index faa8d91087..19801ff3f4 100644 --- a/src/win.c +++ b/src/win.c @@ -1219,6 +1219,9 @@ void win_on_factor_change(session_t *ps, struct managed_win *w) { // Focus needs to be updated first, as other rules might depend on the // focused state of the window win_update_focused(ps, w); + w->blur_foreground = + ps->o.inactive_blur && !w->focused && + (!ps->o.inactive_blur_list || c2_match(ps, w, ps->o.inactive_blur_list, NULL)); win_determine_shadow(ps, w); win_determine_clip_shadow_above(ps, w); @@ -1237,10 +1240,6 @@ void win_on_factor_change(session_t *ps, struct managed_win *w) { c2_match(ps, w, ps->o.unredir_if_possible_blacklist, NULL); } - if (ps->o.inactive_blur && !w->focused) { - w->blur_foreground = !ps->o.inactive_blur_list || - c2_match(ps, w, ps->o.inactive_blur_list, NULL); - } w->fade_excluded = c2_match(ps, w, ps->o.fade_blacklist, NULL); w->transparent_clipping_excluded = From 5ebb76209dd590a8f27deab7ca57021f01e5db29 Mon Sep 17 00:00:00 2001 From: Dave Shoreman Date: Tue, 27 Sep 2022 23:40:37 +0100 Subject: [PATCH 09/12] Patch for `mask` parameter in `blur` function --- src/backend/backend.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backend/backend.c b/src/backend/backend.c index 1685e912c1..6375e84a09 100644 --- a/src/backend/backend.c +++ b/src/backend/backend.c @@ -489,7 +489,8 @@ void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) { // - needs to be set when focus_mode set to true double blur_opacity = 1; ps->backend_data->ops->blur( - ps->backend_data, blur_opacity, ps->backend_blur_context, + ps->backend_data, blur_opacity, + ps->backend_blur_context, w->mask_image, window_coord, ®_paint_in_bound, ®_visible); } } From 4bccb482f91920ce962161c7777a7746aa7e0401 Mon Sep 17 00:00:00 2001 From: Dave Shoreman Date: Sun, 16 Apr 2023 23:13:58 +0100 Subject: [PATCH 10/12] Add damage when blur_foreground changes Moves the setting of `blur_foreground` to a new method which then calls a second to actually set the value and apply damage if it's different, similar to how the blur_background value/damage is handled. --- src/win.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/win.c b/src/win.c index 19801ff3f4..76fb69ddc1 100644 --- a/src/win.c +++ b/src/win.c @@ -1080,6 +1080,16 @@ void win_set_shadow_force(session_t *ps, struct managed_win *w, switch_t val) { } } +static void +win_set_blur_foreground(session_t *ps, struct managed_win *w, bool blur_foreground_new) { + if (w->blur_foreground == blur_foreground_new) + return; + + w->blur_foreground = blur_foreground_new; + + add_damage_from_win(ps, w); +} + static void win_set_blur_background(session_t *ps, struct managed_win *w, bool blur_background_new) { if (w->blur_background == blur_background_new) @@ -1106,6 +1116,22 @@ win_set_fg_shader(session_t *ps, struct managed_win *w, struct shader_info *shad add_damage_from_win(ps, w); } +/** + * Determine whether a window's foreground should be blurred + */ +static void win_determine_blur_foreground(session_t *ps, struct managed_win *w) { + log_debug("Determining blur-foreground of window %#010x (%s)", w->base.id, w->name); + if (w->a.map_state != XCB_MAP_STATE_VIEWABLE) { + return; + } + + bool blur_foreground_new = + ps->o.inactive_blur && !w->focused && + (!ps->o.inactive_blur_list || c2_match(ps, w, ps->o.inactive_blur_list, NULL)); + + win_set_blur_foreground(ps, w, blur_foreground_new); +} + /** * Determine if a window should have background blurred. */ @@ -1219,13 +1245,11 @@ void win_on_factor_change(session_t *ps, struct managed_win *w) { // Focus needs to be updated first, as other rules might depend on the // focused state of the window win_update_focused(ps, w); - w->blur_foreground = - ps->o.inactive_blur && !w->focused && - (!ps->o.inactive_blur_list || c2_match(ps, w, ps->o.inactive_blur_list, NULL)); win_determine_shadow(ps, w); win_determine_clip_shadow_above(ps, w); win_determine_invert_color(ps, w); + win_determine_blur_foreground(ps, w); win_determine_blur_background(ps, w); win_determine_rounded_corners(ps, w); win_determine_fg_shader(ps, w); From c5861702ba4bec1b78e99fe7aa446e9cb491e5f4 Mon Sep 17 00:00:00 2001 From: Dave Shoreman Date: Mon, 17 Apr 2023 20:41:17 +0100 Subject: [PATCH 11/12] Fix segfault, don't hijack background blur Rather than overriding the background blur method, this will only use blur_method when it's already defined, otherwise creating a whole new blur context using the 'box' blur method with default size of 3. This fixes an issue where background blur would be forced even if unwanted. By placing the fgcontext code in picom.c rather than config_libconfig.c, this also fixes a segfault when passing `--inactive-blur` on the command line without having a blur method set either in an option or in config. --- src/backend/backend.c | 3 +-- src/common.h | 1 + src/config_libconfig.c | 3 --- src/picom.c | 11 +++++++++++ 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/backend/backend.c b/src/backend/backend.c index 6375e84a09..fbc07efe6b 100644 --- a/src/backend/backend.c +++ b/src/backend/backend.c @@ -483,14 +483,13 @@ void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) { // Blur window if (w->blur_foreground) { - assert(ps->o.blur_method != BLUR_METHOD_NONE); // FIXME Think more about combining blur w/ opacity // FIXME Don't hardcode opacity // - needs to be set when focus_mode set to true double blur_opacity = 1; ps->backend_data->ops->blur( ps->backend_data, blur_opacity, - ps->backend_blur_context, w->mask_image, window_coord, + ps->backend_blur_fgcontext, w->mask_image, window_coord, ®_paint_in_bound, ®_visible); } } diff --git a/src/common.h b/src/common.h index 8f307dc9fd..b9c93557a1 100644 --- a/src/common.h +++ b/src/common.h @@ -173,6 +173,7 @@ typedef struct session { backend_t *backend_data; /// backend blur context void *backend_blur_context; + void *backend_blur_fgcontext; /// graphic drivers used enum driver drivers; /// file watch handle diff --git a/src/config_libconfig.c b/src/config_libconfig.c index c6f45fc488..bd97e4eebd 100644 --- a/src/config_libconfig.c +++ b/src/config_libconfig.c @@ -543,9 +543,6 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad } // --inactive-blur if (lcfg_lookup_bool(&cfg, "inactive-blur", &opt->inactive_blur)) { - if (opt->blur_method == BLUR_METHOD_NONE) { - opt->blur_method = BLUR_METHOD_BOX; - } parse_cfg_condlst(&cfg, &opt->inactive_blur_list, "inactive-blur-include"); } // --resize-damage diff --git a/src/picom.c b/src/picom.c index 1b85c55873..b9708df32b 100644 --- a/src/picom.c +++ b/src/picom.c @@ -507,6 +507,17 @@ static bool initialize_backend(session_t *ps) { goto err; } + if (ps->o.inactive_blur && ps->o.blur_method == BLUR_METHOD_NONE) { + log_info("No blur method set, defaulting to box for inactive blur"); + struct box_blur_args bargs; + bargs.size = 3; + void *args = (void *)&bargs; + ps->backend_blur_fgcontext = ps->backend_data->ops->create_blur_context( + ps->backend_data, BLUR_METHOD_BOX, args); + } else if (ps->o.inactive_blur) { + ps->backend_blur_fgcontext = ps->backend_blur_context; + } + // Create shaders HASH_ITER2(ps->shaders, shader) { assert(shader->backend_shader == NULL); From 45dc99550dca45731e3deb513e9618a811adc2b9 Mon Sep 17 00:00:00 2001 From: Dave Shoreman Date: Tue, 18 Apr 2023 01:07:13 +0100 Subject: [PATCH 12/12] Add option to tweak inactive window blur opacity --- src/backend/backend.c | 6 +----- src/config.c | 1 + src/config.h | 4 +++- src/config_libconfig.c | 1 + src/options.c | 5 +++++ 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/backend/backend.c b/src/backend/backend.c index fbc07efe6b..b263082d4d 100644 --- a/src/backend/backend.c +++ b/src/backend/backend.c @@ -483,12 +483,8 @@ void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) { // Blur window if (w->blur_foreground) { - // FIXME Think more about combining blur w/ opacity - // FIXME Don't hardcode opacity - // - needs to be set when focus_mode set to true - double blur_opacity = 1; ps->backend_data->ops->blur( - ps->backend_data, blur_opacity, + ps->backend_data, ps->o.inactive_blur_opacity, ps->backend_blur_fgcontext, w->mask_image, window_coord, ®_paint_in_bound, ®_visible); } diff --git a/src/config.c b/src/config.c index 49f1991460..d84f2f8226 100644 --- a/src/config.c +++ b/src/config.c @@ -766,6 +766,7 @@ char *parse_config(options_t *opt, const char *config_file, bool *shadow_enable, .inactive_blur = false, .inactive_blur_list = NULL, + .inactive_blur_opacity = 1.0, .inactive_dim = 0.0, .inactive_dim_fixed = false, .inactive_opacity = 1.0, diff --git a/src/config.h b/src/config.h index 10574287be..424009b04c 100644 --- a/src/config.h +++ b/src/config.h @@ -213,8 +213,10 @@ typedef struct options { char *window_shader_fg; /// Rules to change custom fragment shader for painting windows. c2_lptr_t *window_shader_fg_rules; - /// Whether to blur inactive windows + /// Whether to blur inactive window foregrounds bool inactive_blur; + // Opacity of inactive foreground blurs + double inactive_blur_opacity; /// List of windows that should be blurred out when inactive. c2_lptr_t *inactive_blur_list; /// How much to dim an inactive window. 0.0 - 1.0, 0 to disable. diff --git a/src/config_libconfig.c b/src/config_libconfig.c index bd97e4eebd..fa337173de 100644 --- a/src/config_libconfig.c +++ b/src/config_libconfig.c @@ -544,6 +544,7 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad // --inactive-blur if (lcfg_lookup_bool(&cfg, "inactive-blur", &opt->inactive_blur)) { parse_cfg_condlst(&cfg, &opt->inactive_blur_list, "inactive-blur-include"); + config_lookup_float(&cfg, "inactive-blur-opacity", &opt->inactive_blur_opacity); } // --resize-damage config_lookup_int(&cfg, "resize-damage", &opt->resize_damage); diff --git a/src/options.c b/src/options.c index 7a5aed2777..b11fc798c4 100644 --- a/src/options.c +++ b/src/options.c @@ -61,6 +61,7 @@ static const struct picom_option picom_options[] = { {"inactive-blur-include" , required_argument, 342, NULL , "Conditions for windows that should be fully blurred when inactive." "When --inactive-blur is enabled without an --inactive-blur-include" "condition, the foreground of ALL inactive windows will be blurred."}, + {"inactive-blur-opacity" , required_argument, 343, NULL , "Set the opacity of inactive foreground blurs"}, {"mark-wmwin-focused" , no_argument , 262, NULL , "Try to detect WM windows and mark them as active."}, {"shadow-exclude" , required_argument, 263, NULL , "Exclude conditions for shadows."}, {"mark-ovredir-focused" , no_argument , 264, NULL , "Mark windows that have no WM frame as active."}, @@ -750,6 +751,10 @@ bool get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable, // --inactive-blur-include condlst_add(&opt->inactive_blur_list, optarg); break; + case 343: + // --inactive-blur-opacity + opt->inactive_blur_opacity = normalize_d(atof(optarg)); + break; P_CASEBOOL(733, legacy_backends); P_CASEBOOL(800, monitor_repaint); case 801: