From 2a855e62824653f7634617a2c19d88ba1c650911 Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 30 Jan 2018 12:01:10 +0100 Subject: [PATCH] rootston: fix urxvt damage on HiDPI outputs util/region: add wlr_region_expand --- include/wlr/util/region.h | 7 +++++++ rootston/output.c | 6 ++++++ util/region.c | 27 +++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/include/wlr/util/region.h b/include/wlr/util/region.h index 5d2b37e1..7883af97 100644 --- a/include/wlr/util/region.h +++ b/include/wlr/util/region.h @@ -19,4 +19,11 @@ void wlr_region_scale(pixman_region32_t *dst, pixman_region32_t *src, void wlr_region_transform(pixman_region32_t *dst, pixman_region32_t *src, enum wl_output_transform transform, int width, int height); +/** + * Expands the region of `distance`. If `distance` is negative, it shrinks the + * region. + */ +void wlr_region_expand(pixman_region32_t *dst, pixman_region32_t *src, + int distance); + #endif diff --git a/rootston/output.c b/rootston/output.c index e90f0491..de4922ba 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -600,6 +600,12 @@ static void damage_from_surface(struct wlr_surface *surface, pixman_region32_init(&damage); pixman_region32_copy(&damage, &surface->current->surface_damage); wlr_region_scale(&damage, &damage, output->wlr_output->scale); + if (ceil(output->wlr_output->scale) > surface->current->scale) { + // When scaling up a surface, it'll become blurry so we need to expand + // the damage region + wlr_region_expand(&damage, &damage, + ceil(output->wlr_output->scale) - surface->current->scale); + } pixman_region32_translate(&damage, box.x, box.y); pixman_region32_union(&output->damage, &output->damage, &damage); pixman_region32_fini(&damage); diff --git a/util/region.c b/util/region.c index 9c4712f9..1bde0cb8 100644 --- a/util/region.c +++ b/util/region.c @@ -101,3 +101,30 @@ void wlr_region_transform(pixman_region32_t *dst, pixman_region32_t *src, pixman_region32_init_rects(dst, dst_rects, nrects); free(dst_rects); } + +void wlr_region_expand(pixman_region32_t *dst, pixman_region32_t *src, + int distance) { + if (distance == 0) { + pixman_region32_copy(dst, src); + return; + } + + int nrects; + pixman_box32_t *src_rects = pixman_region32_rectangles(src, &nrects); + + pixman_box32_t *dst_rects = malloc(nrects * sizeof(pixman_box32_t)); + if (dst_rects == NULL) { + return; + } + + for (int i = 0; i < nrects; ++i) { + dst_rects[i].x1 = src_rects[i].x1 - distance; + dst_rects[i].x2 = src_rects[i].x2 + distance; + dst_rects[i].y1 = src_rects[i].y1 - distance; + dst_rects[i].y2 = src_rects[i].y2 + distance; + } + + pixman_region32_fini(dst); + pixman_region32_init_rects(dst, dst_rects, nrects); + free(dst_rects); +}