diff --git a/src/backend/backend.h b/src/backend/backend.h index 5a18e0ac..7c36f9be 100644 --- a/src/backend/backend.h +++ b/src/backend/backend.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 b89c49e8..47697674 100644 --- a/src/backend/gl/gl_common.c +++ b/src/backend/gl/gl_common.c @@ -990,6 +990,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 a44dbc19..dd504436 100644 --- a/src/backend/xrender/xrender.c +++ b/src/backend/xrender/xrender.c @@ -505,6 +505,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 17a198b3..10802f22 100644 --- a/src/config.c +++ b/src/config.c @@ -88,6 +88,8 @@ 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, "none") == 0) { return BLUR_METHOD_NONE; } @@ -542,6 +544,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 403ea548..5dc67e01 100644 --- a/src/config.h +++ b/src/config.h @@ -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 b07155c5..57b69b2a 100644 --- a/src/config_libconfig.c +++ b/src/config_libconfig.c @@ -522,6 +522,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) { @@ -635,6 +637,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 8f44b433..112d1447 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" @@ -437,6 +440,7 @@ static const struct option longopts[] = { {"blur-method", required_argument, NULL, 328}, {"blur-size", required_argument, NULL, 329}, {"blur-deviation", required_argument, NULL, 330}, + {"blur-strength", required_argument, NULL, 331}, {"experimental-backends", no_argument, NULL, 733}, {"monitor-repaint", no_argument, NULL, 800}, {"diagnostics", no_argument, NULL, 801}, @@ -841,6 +845,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); @@ -930,6 +938,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 643d53e4..a569c6ff 100644 --- a/src/picom.c +++ b/src/picom.c @@ -704,6 +704,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) { @@ -721,6 +722,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; }