diff --git a/src/backend/backend.c b/src/backend/backend.c index bfdd02b0..146c9726 100644 --- a/src/backend/backend.c +++ b/src/backend/backend.c @@ -2,7 +2,7 @@ // Copyright (c) Yuxuan Shui #include -#include "backend.h" +#include "backend/backend.h" #include "common.h" #include "compiler.h" #include "config.h" @@ -17,11 +17,18 @@ backend_init_fn backend_list[NUM_BKEND] = { #endif }; -region_t get_damage(session_t *ps) { +/** + * @param all_damage if true ignore damage and repaint the whole screen + */ +region_t get_damage(session_t *ps, bool all_damage) { region_t region; auto buffer_age_fn = ps->backend_data->ops->buffer_age; int buffer_age = buffer_age_fn ? buffer_age_fn(ps->backend_data) : -1; + if (all_damage) { + buffer_age = -1; + } + pixman_region32_init(®ion); if (buffer_age == -1 || buffer_age > ps->ndamage) { pixman_region32_copy(®ion, &ps->screen_reg); @@ -42,7 +49,7 @@ void paint_all_new(session_t *ps, win *const t, bool ignore_damage) { // part of the image we want to reuse region_t reg_damage; if (!ignore_damage) { - reg_damage = get_damage(ps); + reg_damage = get_damage(ps, ps->o.monitor_repaint); } else { pixman_region32_init(®_damage); pixman_region32_copy(®_damage, &ps->screen_reg); @@ -149,7 +156,8 @@ void paint_all_new(session_t *ps, win *const t, bool ignore_damage) { ps->backend_data->ops->blur(ps->backend_data, w->opacity, ®_paint, ®_visible); } else if (frame_transparent && ps->o.blur_background_frame) { - // Window itself is solid, we only need to blur the frame region + // Window itself is solid, we only need to blur the frame + // region auto reg_blur = win_get_region_frame_local_by_val(w); pixman_region32_translate(®_blur, w->g.x, w->g.y); // make sure reg_blur \in reg_damage @@ -165,8 +173,8 @@ void paint_all_new(session_t *ps, win *const t, bool ignore_damage) { w->g.y, ®_paint, ®_visible); } else { // For window image processing, we don't need to limit the process - // region to damage, since the window image data is independent from - // the target image data, which we want to protect. + // region to damage, since the window image data is independent + // from the target image data, which we want to protect. // The bounding shape, in window local coordinates region_t reg_bound_local; @@ -183,8 +191,9 @@ void paint_all_new(session_t *ps, win *const t, bool ignore_damage) { pixman_region32_intersect(®_visible_local, ®_visible, ®_damage); 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. + // 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); @@ -231,6 +240,15 @@ void paint_all_new(session_t *ps, win *const t, bool ignore_damage) { } pixman_region32_fini(®_damage); + if (ps->o.monitor_repaint) { + reg_damage = get_damage(ps, false); + auto extent = pixman_region32_extents(®_damage); + ps->backend_data->ops->fill_rectangle( + ps->backend_data, 0.5, 0, 0, 0.5, extent->x1, extent->y1, + extent->x2 - extent->x1, extent->y2 - extent->y1, ®_damage); + pixman_region32_fini(®_damage); + } + // Move the head of the damage ring ps->damage = ps->damage - 1; if (ps->damage < ps->damage_ring) { diff --git a/src/backend/backend.h b/src/backend/backend.h index 03edbf5d..899afc85 100644 --- a/src/backend/backend.h +++ b/src/backend/backend.h @@ -83,6 +83,10 @@ struct backend_operations { void (*compose)(backend_t *backend_data, void *image_data, int dst_x, int dst_y, const region_t *reg_paint, const region_t *reg_visible); + /// Fill rectangle of target, mostly for debug purposes, optional. + void (*fill_rectangle)(backend_t *backend_data, double r, double g, double b, double a, + int x, int y, int width, int height, const region_t *clip); + /// Blur a given region on of the target. bool (*blur)(backend_t *backend_data, double opacity, const region_t *reg_blur, const region_t *reg_visible) attr_nonnull(1, 3, 4); diff --git a/src/backend/backend_common.c b/src/backend/backend_common.c index 1b3ef193..644dbe9d 100644 --- a/src/backend/backend_common.c +++ b/src/backend/backend_common.c @@ -267,7 +267,8 @@ void *default_backend_render_shadow(backend_t *backend_data, int width, int heig shadow_pixel, &shadow, &pict); auto visual = x_get_visual_for_standard(backend_data->c, XCB_PICT_STANDARD_ARGB_32); - void *ret = backend_data->ops->bind_pixmap(backend_data, shadow, x_get_visual_info(backend_data->c, visual), true); + void *ret = backend_data->ops->bind_pixmap( + backend_data, shadow, x_get_visual_info(backend_data->c, visual), true); xcb_render_free_picture(backend_data->c, pict); return ret; } diff --git a/src/backend/xrender.c b/src/backend/xrender.c index 51382b31..16b18082 100644 --- a/src/backend/xrender.c +++ b/src/backend/xrender.c @@ -103,6 +103,18 @@ static void compose(backend_t *base, void *img_data, int dst_x, int dst_y, pixman_region32_fini(®); } +static void fill_rectangle(backend_t *base, double r, double g, double b, double a, int x, + int y, int width, int height, const region_t *clip) { + struct _xrender_data *xd = (void *)base; + x_set_picture_clip_region(base->c, xd->back[xd->curr_back], 0, 0, clip); + // color is in X fixed point representation + xcb_render_fill_rectangles( + base->c, XCB_RENDER_PICT_OP_OVER, xd->back[xd->curr_back], + (xcb_render_color_t){ + .red = r * 0xffff, .green = g * 0xffff, .blue = b * 0xffff, .alpha = a * 0xffff}, + 1, (xcb_rectangle_t[]){{.x = x, .y = y, .width = width, .height = height}}); +} + static bool blur(backend_t *backend_data, double opacity, const region_t *reg_blur, const region_t *reg_visible) { struct _xrender_data *xd = (void *)backend_data; @@ -192,8 +204,8 @@ static bool blur(backend_t *backend_data, double opacity, const region_t *reg_bl // There is only 1 pass if (i == 1) { xcb_render_composite(c, XCB_RENDER_PICT_OP_OVER, src_pict, alpha_pict, - xd->back[xd->curr_back], 0, 0, 0, 0, extent->x1, extent->y1, - width, height); + xd->back[xd->curr_back], 0, 0, 0, 0, extent->x1, + extent->y1, width, height); } xcb_render_free_picture(c, tmp_picture[0]); @@ -446,6 +458,7 @@ static struct backend_operations xrender_ops = { .blur = blur, .present = present, .compose = compose, + .fill_rectangle = fill_rectangle, .bind_pixmap = bind_pixmap, .release_image = release_image, .render_shadow = default_backend_render_shadow,