diff --git a/man/picom.1.asciidoc b/man/picom.1.asciidoc index a7a3d44..232bd5b 100644 --- a/man/picom.1.asciidoc +++ b/man/picom.1.asciidoc @@ -166,7 +166,7 @@ OPTIONS *--detect-client-leader*:: Use 'WM_CLIENT_LEADER' to group windows, and consider windows in the same group focused at the same time. 'WM_TRANSIENT_FOR' has higher priority if *--detect-transient* is enabled, too. -*--blur-method*, *--blur-size*, *--blur-deviation*:: +*--blur-method*, *--blur-size*, *--blur-deviation*, *--blur-strength*:: Parameters for background blurring, see the *BLUR* section for more information. *--blur-background*:: @@ -397,8 +397,8 @@ Available options of the 'blur' section are: :: *method*::: A string. Controls the blur method. Corresponds to the *--blur-method* command line option. Available choices are: - 'none' to disable blurring; 'gaussian' for gaussian blur; 'box' for box blur; 'kernel' for convolution blur with a custom kernel. - Note: 'gaussian' and 'box' blur methods are only supported by the experimental backends. + 'none' to disable blurring; 'gaussian' for gaussian blur; 'box' for box blur; 'kernel' for convolution blur with a custom kernel; 'dual_kawase' for dual-filter kawase blur. + Note: 'gaussian', 'box' and 'dual_kawase' blur methods are only supported by the experimental backends. (default: none) *size*::: @@ -407,6 +407,9 @@ Available options of the 'blur' section are: :: *deviation*::: A floating point number. The standard deviation for the 'gaussian' blur method. Corresponds to the *--blur-deviation* command line option (default: 0.84089642). + *strength*::: + An integer in the range 0-20. The strength of the 'dual_kawase' blur method. Corresponds to the *--blur-strength* command line option. If set to zero, the value requested by *--blur-size* is approximated (default: 5). + *kernel*::: A string. The kernel to use for the 'kernel' blur method, specified in the same format as the *--blur-kerns* option. Corresponds to the *--blur-kerns* command line option. diff --git a/picom.sample.conf b/picom.sample.conf index defdbee..201fa5f 100644 --- a/picom.sample.conf +++ b/picom.sample.conf @@ -143,6 +143,8 @@ focus-exclude = [ "class_g = 'Cairo-clock'" ]; # blur-size = 12 # # blur-deviation = false +# +# blur-strength = 5 # Blur background of semi-transparent / ARGB windows. # Bad in performance, with driver-dependent behavior. diff --git a/src/backend/backend.h b/src/backend/backend.h index f5d10ad..c530a1e 100644 --- a/src/backend/backend.h +++ b/src/backend/backend.h @@ -5,8 +5,8 @@ #include -#include "config.h" #include "compiler.h" +#include "config.h" #include "driver.h" #include "kernel.h" #include "region.h" @@ -65,6 +65,11 @@ struct kernel_blur_args { int kernel_count; }; +struct dual_kawase_blur_args { + int size; + int strength; +}; + struct backend_operations { // =========== Initialization =========== diff --git a/src/backend/gl/gl_common.c b/src/backend/gl/gl_common.c index 1cf366a..f75908b 100644 --- a/src/backend/gl/gl_common.c +++ b/src/backend/gl/gl_common.c @@ -977,6 +977,12 @@ void *gl_create_blur_context(backend_t *base, enum blur_method method, void *arg return ctx; } + if (method == BLUR_METHOD_DUAL_KAWASE) { + log_warn("Blur method 'dual_kawase' is not yet implemented."); + ctx->method = BLUR_METHOD_NONE; + return ctx; + } + int nkernels; ctx->method = BLUR_METHOD_KERNEL; if (method == BLUR_METHOD_KERNEL) { diff --git a/src/backend/xrender/xrender.c b/src/backend/xrender/xrender.c index fcc76b0..f9f4775 100644 --- a/src/backend/xrender/xrender.c +++ b/src/backend/xrender/xrender.c @@ -507,6 +507,12 @@ void *create_blur_context(backend_t *base attr_unused, enum blur_method method, ret->method = BLUR_METHOD_NONE; return ret; } + if (method == BLUR_METHOD_DUAL_KAWASE) { + log_warn("Blur method 'dual_kawase' is not compatible with the 'xrender' " + "backend."); + ret->method = BLUR_METHOD_NONE; + return ret; + } ret->method = BLUR_METHOD_KERNEL; struct conv **kernels; diff --git a/src/config.c b/src/config.c index 5d93f32..c8690b7 100644 --- a/src/config.c +++ b/src/config.c @@ -88,6 +88,13 @@ enum blur_method parse_blur_method(const char *src) { return BLUR_METHOD_BOX; } else if (strcmp(src, "gaussian") == 0) { return BLUR_METHOD_GAUSSIAN; + } else if (strcmp(src, "dual_kawase") == 0) { + return BLUR_METHOD_DUAL_KAWASE; + } else if (strcmp(src, "kawase") == 0) { + log_warn("Blur method 'kawase' has been renamed to 'dual_kawase'. " + "Interpreted as 'dual_kawase', but this will stop working " + "soon."); + return BLUR_METHOD_DUAL_KAWASE; } else if (strcmp(src, "none") == 0) { return BLUR_METHOD_NONE; } @@ -542,6 +549,7 @@ char *parse_config(options_t *opt, const char *config_file, bool *shadow_enable, .blur_method = BLUR_METHOD_NONE, .blur_radius = 3, .blur_deviation = 0.84089642, + .blur_strength = 5, .blur_background_frame = false, .blur_background_fixed = false, .blur_background_blacklist = NULL, diff --git a/src/config.h b/src/config.h index cd32add..267239a 100644 --- a/src/config.h +++ b/src/config.h @@ -23,8 +23,8 @@ #include "kernel.h" #include "log.h" #include "region.h" -#include "win_defs.h" #include "types.h" +#include "win_defs.h" typedef struct session session_t; @@ -60,6 +60,7 @@ enum blur_method { BLUR_METHOD_KERNEL, BLUR_METHOD_BOX, BLUR_METHOD_GAUSSIAN, + BLUR_METHOD_DUAL_KAWASE, BLUR_METHOD_INVALID, }; @@ -189,6 +190,8 @@ typedef struct options { int blur_radius; // Standard deviation for the gaussian blur double blur_deviation; + // Strength of the dual_kawase blur + int blur_strength; /// Whether to blur background when the window frame is not opaque. /// Implies blur_background. bool blur_background_frame; diff --git a/src/config_libconfig.c b/src/config_libconfig.c index 16e965f..9de0479 100644 --- a/src/config_libconfig.c +++ b/src/config_libconfig.c @@ -530,6 +530,8 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad config_lookup_int(&cfg, "blur-size", &opt->blur_radius); // --blur-deviation config_lookup_float(&cfg, "blur-deviation", &opt->blur_deviation); + // --blur-strength + config_lookup_int(&cfg, "blur-strength", &opt->blur_strength); // --blur-background if (config_lookup_bool(&cfg, "blur-background", &ival) && ival) { if (opt->blur_method == BLUR_METHOD_NONE) { @@ -640,6 +642,7 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad } config_setting_lookup_float(blur_cfg, "deviation", &opt->blur_deviation); + config_setting_lookup_int(blur_cfg, "strength", &opt->blur_strength); } // Wintype settings diff --git a/src/options.c b/src/options.c index 44c3081..953d464 100644 --- a/src/options.c +++ b/src/options.c @@ -212,6 +212,9 @@ static void usage(const char *argv0, int ret) { "--blur-deviation\n" " The standard deviation for the 'gaussian' blur method.\n" "\n" + "--blur-strength\n" + " The strength level of the 'dual_kawase' blur method.\n" + "\n" "--blur-background\n" " Blur background of semi-transparent / ARGB windows. Bad in\n" " performance. The switch name may change without prior\n" @@ -435,7 +438,8 @@ static const struct option longopts[] = { {"blur-method", required_argument, NULL, 328}, {"blur-size", required_argument, NULL, 329}, {"blur-deviation", required_argument, NULL, 330}, - {"shadow-color", required_argument, NULL, 331}, + {"blur-strength", required_argument, NULL, 331}, + {"shadow-color", required_argument, NULL, 332}, {"experimental-backends", no_argument, NULL, 733}, {"monitor-repaint", no_argument, NULL, 800}, {"diagnostics", no_argument, NULL, 801}, @@ -605,7 +609,7 @@ bool get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable, case 256: // --config break; - case 331:; + case 332:; // --shadow-color struct color rgb; rgb = hex_to_rgb(optarg); @@ -844,6 +848,10 @@ bool get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable, // --blur-deviation opt->blur_deviation = atof(optarg); break; + case 331: + // --blur-strength + opt->blur_strength = atoi(optarg); + break; P_CASEBOOL(733, experimental_backends); P_CASEBOOL(800, monitor_repaint); @@ -933,6 +941,20 @@ bool get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable, CHECK(opt->blur_kernel_count); } + // Sanitize parameters for dual-filter kawase blur + if (opt->blur_method == BLUR_METHOD_DUAL_KAWASE) { + if (opt->blur_strength <= 0 && opt->blur_radius > 500) { + log_warn("Blur radius >500 not supported by dual_kawase method, " + "capping to 500."); + opt->blur_radius = 500; + } + if (opt->blur_strength > 20) { + log_warn("Blur strength >20 not supported by dual_kawase method, " + "capping to 20."); + opt->blur_strength = 20; + } + } + if (opt->resize_damage < 0) { log_warn("Negative --resize-damage will not work correctly."); } diff --git a/src/picom.c b/src/picom.c index b4602e1..d264902 100644 --- a/src/picom.c +++ b/src/picom.c @@ -431,6 +431,7 @@ static bool initialize_blur(session_t *ps) { struct kernel_blur_args kargs; struct gaussian_blur_args gargs; struct box_blur_args bargs; + struct dual_kawase_blur_args dkargs; void *args = NULL; switch (ps->o.blur_method) { @@ -448,6 +449,11 @@ static bool initialize_blur(session_t *ps) { gargs.deviation = ps->o.blur_deviation; args = (void *)&gargs; break; + case BLUR_METHOD_DUAL_KAWASE: + dkargs.size = ps->o.blur_radius; + dkargs.strength = ps->o.blur_strength; + args = (void *)&dkargs; + break; default: return true; }