diff --git a/src/backend/backend.c b/src/backend/backend.c index 39de345e..faf24431 100644 --- a/src/backend/backend.c +++ b/src/backend/backend.c @@ -301,107 +301,103 @@ void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) { } assert(w->shadow_image); - if (w->opacity == 1) { - ps->backend_data->ops->compose( - ps->backend_data, w->shadow_image, w->g.x + w->shadow_dx, - w->g.y + w->shadow_dy, ®_shadow, ®_visible); - } else { - auto new_img = ps->backend_data->ops->clone_image( - ps->backend_data, w->shadow_image, ®_visible); - ps->backend_data->ops->set_image_property( - ps->backend_data, IMAGE_PROPERTY_OPACITY, new_img, - &w->opacity); - ps->backend_data->ops->compose( - ps->backend_data, new_img, w->g.x + w->shadow_dx, - w->g.y + w->shadow_dy, ®_shadow, ®_visible); - ps->backend_data->ops->release_image(ps->backend_data, new_img); - } + ps->backend_data->ops->set_image_property( + ps->backend_data, IMAGE_PROPERTY_OPACITY, w->shadow_image, + &w->opacity); + ps->backend_data->ops->compose( + ps->backend_data, w->shadow_image, w->g.x + w->shadow_dx, + w->g.y + w->shadow_dy, ®_shadow, ®_visible); pixman_region32_fini(®_shadow); } - // Set max brightness - ps->backend_data->ops->set_image_property( - ps->backend_data, IMAGE_PROPERTY_MAX_BRIGHTNESS, w->win_image, - &ps->o.max_brightness); + // Update image properties + { + double dim_opacity = 0.0; + if (w->dim) { + dim_opacity = ps->o.inactive_dim; + if (!ps->o.inactive_dim_fixed) { + dim_opacity *= w->opacity; + } + } + + ps->backend_data->ops->set_image_property( + ps->backend_data, IMAGE_PROPERTY_MAX_BRIGHTNESS, w->win_image, + &ps->o.max_brightness); + ps->backend_data->ops->set_image_property( + ps->backend_data, IMAGE_PROPERTY_INVERTED, w->win_image, + &w->invert_color); + ps->backend_data->ops->set_image_property( + ps->backend_data, IMAGE_PROPERTY_DIM_LEVEL, w->win_image, + &dim_opacity); + ps->backend_data->ops->set_image_property( + ps->backend_data, IMAGE_PROPERTY_OPACITY, w->win_image, &w->opacity); + } + + if (w->opacity * MAX_ALPHA < 1) { + // We don't need to paint the window body itself if it's + // completely transparent. + goto skip; + } // Draw window on target - if (!w->invert_color && !w->dim && w->frame_opacity == 1 && w->opacity == 1) { + if (w->frame_opacity == 1) { ps->backend_data->ops->compose(ps->backend_data, w->win_image, w->g.x, w->g.y, ®_paint_in_bound, ®_visible); - } else if (w->opacity * MAX_ALPHA >= 1) { - // We don't need to paint the window body itself if it's - // completely transparent. - + } else { // For window image processing, we don't have to limit the process // region to damage for correctness. (see for // details) - // The bounding shape, in window local coordinates - region_t reg_bound_local; - pixman_region32_init(®_bound_local); - pixman_region32_copy(®_bound_local, ®_bound); - pixman_region32_translate(®_bound_local, -w->g.x, -w->g.y); - - // The visible region, in window local coordinates - // Although we don't limit process region to damage, we provide - // that info in reg_visible as a hint. Since window image data - // outside of the damage region won't be painted onto target + // The visible region, in window local coordinates Although we + // don't limit process region to damage, we provide that info in + // reg_visible as a hint. Since window image data outside of the + // damage region won't be painted onto target region_t reg_visible_local; - pixman_region32_init(®_visible_local); - pixman_region32_intersect(®_visible_local, ®_visible, ®_paint); - pixman_region32_translate(®_visible_local, -w->g.x, -w->g.y); - // Data outside of the bounding shape won't be visible, but it is - // not necessary to limit the image operations to the bounding - // shape yet. So pass that as the visible region, not the clip - // region. - pixman_region32_intersect(®_visible_local, ®_visible_local, - ®_bound_local); + { + // The bounding shape, in window local coordinates + region_t reg_bound_local; + pixman_region32_init(®_bound_local); + pixman_region32_copy(®_bound_local, ®_bound); + pixman_region32_translate(®_bound_local, -w->g.x, -w->g.y); + + pixman_region32_init(®_visible_local); + pixman_region32_intersect(®_visible_local, + ®_visible, ®_paint); + pixman_region32_translate(®_visible_local, -w->g.x, + -w->g.y); + // Data outside of the bounding shape won't be visible, + // but it is not necessary to limit the image operations + // to the bounding shape yet. So pass that as the visible + // region, not the clip region. + pixman_region32_intersect( + ®_visible_local, ®_visible_local, ®_bound_local); + pixman_region32_fini(®_bound_local); + } auto new_img = ps->backend_data->ops->clone_image( ps->backend_data, w->win_image, ®_visible_local); - if (w->invert_color) { - ps->backend_data->ops->set_image_property( - ps->backend_data, IMAGE_PROPERTY_INVERTED, new_img, - &w->invert_color); - } - if (w->dim) { - double dim_opacity = ps->o.inactive_dim; - if (!ps->o.inactive_dim_fixed) { - dim_opacity *= w->opacity; - } - ps->backend_data->ops->set_image_property( - ps->backend_data, IMAGE_PROPERTY_DIM_LEVEL, new_img, - &dim_opacity); - } - if (w->frame_opacity != 1) { - auto reg_frame = win_get_region_frame_local_by_val(w); - ps->backend_data->ops->image_op( - ps->backend_data, IMAGE_OP_APPLY_ALPHA, new_img, ®_frame, - ®_visible_local, (double[]){w->frame_opacity}); - pixman_region32_fini(®_frame); - } - if (w->opacity != 1) { - ps->backend_data->ops->set_image_property( - ps->backend_data, IMAGE_PROPERTY_OPACITY, new_img, - &w->opacity); - } + auto reg_frame = win_get_region_frame_local_by_val(w); + ps->backend_data->ops->image_op( + ps->backend_data, IMAGE_OP_APPLY_ALPHA, new_img, ®_frame, + ®_visible_local, (double[]){w->frame_opacity}); + pixman_region32_fini(®_frame); ps->backend_data->ops->compose(ps->backend_data, new_img, w->g.x, w->g.y, ®_paint_in_bound, ®_visible); ps->backend_data->ops->release_image(ps->backend_data, new_img); pixman_region32_fini(®_visible_local); - pixman_region32_fini(®_bound_local); } + skip: pixman_region32_fini(®_bound); pixman_region32_fini(®_paint_in_bound); } pixman_region32_fini(®_paint); if (ps->o.monitor_repaint) { + const struct color DEBUG_COLOR = {0.5, 0, 0, 0.5}; auto reg_damage_debug = get_damage(ps, false); - ps->backend_data->ops->fill( - ps->backend_data, (struct color){0.5, 0, 0, 0.5}, ®_damage_debug); + ps->backend_data->ops->fill(ps->backend_data, DEBUG_COLOR, ®_damage_debug); pixman_region32_fini(®_damage_debug); }