diff --git a/man/picom.1.asciidoc b/man/picom.1.asciidoc index 9e0bb206..ec45a8ac 100644 --- a/man/picom.1.asciidoc +++ b/man/picom.1.asciidoc @@ -106,6 +106,9 @@ OPTIONS *--corner-radius* 'VALUE':: Sets the radius of rounded window corners. When > 0, the compositor will round the corners of windows. (defaults to 0). +*--rounded-corners-exclude* 'CONDITION':: + Exclude conditions for rounded corners. + *--mark-wmwin-focused*:: Try to detect WM windows (a non-override-redirect window with no child that has 'WM_STATE') and mark them as active. diff --git a/src/config.c b/src/config.c index 54445328..a2963247 100644 --- a/src/config.c +++ b/src/config.c @@ -505,6 +505,7 @@ void set_default_winopts(options_t *opt, win_option_mask_t *mask, bool shadow_en char *parse_config(options_t *opt, const char *config_file, bool *shadow_enable, bool *fading_enable, bool *hasneg, win_option_mask_t *winopt_mask) { + // clang-format off *opt = (struct options){ .backend = BKEND_XRENDER, .glx_no_stencil = false, @@ -574,7 +575,10 @@ char *parse_config(options_t *opt, const char *config_file, bool *shadow_enable, .no_ewmh_fullscreen = false, .track_leader = false, + + .rounded_corners_blacklist = NULL }; + // clang-format on char *ret = NULL; #ifdef CONFIG_LIBCONFIG diff --git a/src/config.h b/src/config.h index 7c56aabb..bd3e08bf 100644 --- a/src/config.h +++ b/src/config.h @@ -219,6 +219,8 @@ typedef struct options { double max_brightness; // Radius of rounded window corners int corner_radius; + /// Rounded corners blacklist. A linked list of conditions. + c2_lptr_t *rounded_corners_blacklist; // === Focus related === /// Whether to try to detect WM windows and mark them as focused. diff --git a/src/config_libconfig.c b/src/config_libconfig.c index 3bcb8b30..1c0c6117 100644 --- a/src/config_libconfig.c +++ b/src/config_libconfig.c @@ -376,6 +376,8 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad opt->active_opacity = normalize_d(dval); // --corner-radius config_lookup_int(&cfg, "corner-radius", &opt->corner_radius); + // --rounded-corners-exclude + parse_cfg_condlst(&cfg, &opt->rounded_corners_blacklist, "rounded-corners-exclude"); // -e (frame_opacity) config_lookup_float(&cfg, "frame-opacity", &opt->frame_opacity); // -c (shadow_enable) diff --git a/src/options.c b/src/options.c index 0f88571f..6632e7d2 100644 --- a/src/options.c +++ b/src/options.c @@ -121,6 +121,9 @@ static void usage(const char *argv0, int ret) { " Sets the radius of rounded window corners. When > 0, the compositor\n" " will round the corners of windows. (defaults to 0).\n" "\n" + "--rounded-corners-exclude condition\n" + " Exclude conditions for rounded corners.\n" + "\n" "--mark-wmwin-focused\n" " Try to detect WM windows and mark them as active.\n" "\n" @@ -445,6 +448,7 @@ static const struct option longopts[] = { {"blur-strength", required_argument, NULL, 331}, {"shadow-color", required_argument, NULL, 332}, {"corner-radius", required_argument, NULL, 333}, + {"rounded-corners-exclude", required_argument, NULL, 334}, {"experimental-backends", no_argument, NULL, 733}, {"monitor-repaint", no_argument, NULL, 800}, {"diagnostics", no_argument, NULL, 801}, @@ -868,6 +872,10 @@ bool get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable, // --cornor-radius opt->corner_radius = atoi(optarg); break; + case 334: + // --rounded-corners-exclude + condlst_add(&opt->rounded_corners_blacklist, optarg); + break; P_CASEBOOL(733, experimental_backends); P_CASEBOOL(800, monitor_repaint); case 801: opt->print_diagnostics = true; break; diff --git a/src/picom.c b/src/picom.c index 7acaedc8..9234253b 100644 --- a/src/picom.c +++ b/src/picom.c @@ -669,8 +669,6 @@ static struct managed_win *paint_preprocess(session_t *ps, bool *fade_running) { w->frame_opacity = 1.0; } - w->corner_radius = ps->o.corner_radius; - // Update window mode w->mode = win_calc_mode(w); @@ -1889,6 +1887,7 @@ static session_t *session_init(int argc, char **argv, Display *dpy, c2_list_postprocess(ps, ps->o.blur_background_blacklist) && c2_list_postprocess(ps, ps->o.invert_color_list) && c2_list_postprocess(ps, ps->o.opacity_rules) && + c2_list_postprocess(ps, ps->o.rounded_corners_blacklist) && c2_list_postprocess(ps, ps->o.focus_blacklist))) { log_error("Post-processing of conditionals failed, some of your rules " "might not work"); @@ -2266,6 +2265,7 @@ static void session_destroy(session_t *ps) { free_wincondlst(&ps->o.opacity_rules); free_wincondlst(&ps->o.paint_blacklist); free_wincondlst(&ps->o.unredir_if_possible_blacklist); + free_wincondlst(&ps->o.rounded_corners_blacklist); // Free tracked atom list { diff --git a/src/render.c b/src/render.c index 16059181..58713aa5 100644 --- a/src/render.c +++ b/src/render.c @@ -358,7 +358,7 @@ paint_region(session_t *ps, const struct managed_win *w, int x, int y, int wid, const bool neg = (w && w->invert_color); render(ps, x, y, dx, dy, wid, hei, fullwid, fullhei, opacity, argb, neg, - (w ? w->corner_radius : 0), pict, + w ? w->corner_radius : 0, pict, (w ? w->paint.ptex : ps->root_tile_paint.ptex), reg_paint, #ifdef CONFIG_OPENGL w ? &ps->glx_prog_win : NULL diff --git a/src/win.c b/src/win.c index f87ef938..13cc71d0 100644 --- a/src/win.c +++ b/src/win.c @@ -1033,6 +1033,26 @@ static void win_determine_blur_background(session_t *ps, struct managed_win *w) win_set_blur_background(ps, w, blur_background_new); } +/** + * Determine if a window should have rounded corners. + */ +static void win_determine_rounded_corners(session_t *ps, struct managed_win *w) { + if (ps->o.corner_radius == 0) { + w->corner_radius = 0; + return; + } + + // Don't round full screen windows & excluded windows + if ((w && win_is_fullscreen(ps, w)) || + c2_match(ps, w, ps->o.rounded_corners_blacklist, NULL)) { + w->corner_radius = 0; + log_debug("Not rounding corners for window %#010x", w->base.id); + } else { + w->corner_radius = ps->o.corner_radius; + log_debug("Rounding corners for window %#010x", w->base.id); + } +} + /** * Update window opacity according to opacity rules. */ @@ -1067,6 +1087,7 @@ void win_on_factor_change(session_t *ps, struct managed_win *w) { win_determine_shadow(ps, w); win_determine_invert_color(ps, w); win_determine_blur_background(ps, w); + win_determine_rounded_corners(ps, w); w->mode = win_calc_mode(w); log_debug("Window mode changed to %d", w->mode); win_update_opacity_rule(ps, w);