backend: fix rendering shadow with opacity
Shadow opacity should be multiplied with the window's opacity. Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
0bd08f4ab4
commit
9296706f7b
|
@ -134,9 +134,21 @@ void paint_all_new(session_t *ps, win *const t, bool ignore_damage) {
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(w->shadow_image);
|
assert(w->shadow_image);
|
||||||
|
if (w->opacity == 1) {
|
||||||
ps->backend_data->ops->compose(
|
ps->backend_data->ops->compose(
|
||||||
ps->backend_data, w->shadow_image, w->g.x + w->shadow_dx,
|
ps->backend_data, w->shadow_image, w->g.x + w->shadow_dx,
|
||||||
w->g.y + w->shadow_dy, ®_shadow, ®_visible);
|
w->g.y + w->shadow_dy, ®_shadow, ®_visible);
|
||||||
|
} else {
|
||||||
|
auto new_img = ps->backend_data->ops->copy(
|
||||||
|
ps->backend_data, w->shadow_image, ®_visible);
|
||||||
|
ps->backend_data->ops->image_op(
|
||||||
|
ps->backend_data, IMAGE_OP_APPLY_ALPHA_ALL, new_img,
|
||||||
|
NULL, ®_visible, (double[]){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);
|
||||||
|
}
|
||||||
pixman_region32_fini(®_shadow);
|
pixman_region32_fini(®_shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,8 +256,7 @@ void paint_all_new(session_t *ps, win *const t, bool ignore_damage) {
|
||||||
|
|
||||||
if (ps->o.monitor_repaint) {
|
if (ps->o.monitor_repaint) {
|
||||||
reg_damage = get_damage(ps, false);
|
reg_damage = get_damage(ps, false);
|
||||||
ps->backend_data->ops->fill(
|
ps->backend_data->ops->fill(ps->backend_data, 0.5, 0, 0, 0.5, ®_damage);
|
||||||
ps->backend_data, 0.5, 0, 0, 0.5, ®_damage);
|
|
||||||
pixman_region32_fini(®_damage);
|
pixman_region32_fini(®_damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -348,12 +348,10 @@ static bool image_op(backend_t *base, enum image_operations op, void *image,
|
||||||
struct _xrender_data *xd = (void *)base;
|
struct _xrender_data *xd = (void *)base;
|
||||||
struct _xrender_image_data *img = image;
|
struct _xrender_image_data *img = image;
|
||||||
region_t reg;
|
region_t reg;
|
||||||
double dim_opacity;
|
double *dargs = arg;
|
||||||
double alpha_multiplier;
|
|
||||||
int *iargs = arg;
|
int *iargs = arg;
|
||||||
if (op == IMAGE_OP_APPLY_ALPHA_ALL) {
|
if (op == IMAGE_OP_APPLY_ALPHA_ALL) {
|
||||||
alpha_multiplier = *(double *)arg;
|
img->opacity *= dargs[0];
|
||||||
img->opacity *= alpha_multiplier;
|
|
||||||
img->has_alpha = true;
|
img->has_alpha = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -388,10 +386,9 @@ static bool image_op(backend_t *base, enum image_operations op, void *image,
|
||||||
break;
|
break;
|
||||||
case IMAGE_OP_DIM_ALL:
|
case IMAGE_OP_DIM_ALL:
|
||||||
x_set_picture_clip_region(base->c, img->pict, 0, 0, reg_visible);
|
x_set_picture_clip_region(base->c, img->pict, 0, 0, reg_visible);
|
||||||
dim_opacity = *(double *)arg;
|
|
||||||
|
|
||||||
xcb_render_color_t color = {
|
xcb_render_color_t color = {
|
||||||
.red = 0, .green = 0, .blue = 0, .alpha = 0xffff * dim_opacity};
|
.red = 0, .green = 0, .blue = 0, .alpha = 0xffff * dargs[0]};
|
||||||
|
|
||||||
// Dim the actually content of window
|
// Dim the actually content of window
|
||||||
xcb_rectangle_t rect = {
|
xcb_rectangle_t rect = {
|
||||||
|
@ -411,12 +408,11 @@ static bool image_op(backend_t *base, enum image_operations op, void *image,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
alpha_multiplier = *(double *)arg;
|
if (dargs[0] == 1) {
|
||||||
if (alpha_multiplier == 1) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto alpha_pict = xd->alpha_pict[(int)(alpha_multiplier * 255)];
|
auto alpha_pict = xd->alpha_pict[(int)(dargs[0] * 255)];
|
||||||
x_set_picture_clip_region(base->c, img->pict, 0, 0, ®);
|
x_set_picture_clip_region(base->c, img->pict, 0, 0, ®);
|
||||||
xcb_render_composite(base->c, XCB_RENDER_PICT_OP_IN, img->pict, XCB_NONE,
|
xcb_render_composite(base->c, XCB_RENDER_PICT_OP_IN, img->pict, XCB_NONE,
|
||||||
alpha_pict, 0, 0, 0, 0, 0, 0, img->width, img->height);
|
alpha_pict, 0, 0, 0, 0, 0, 0, img->width, img->height);
|
||||||
|
@ -438,22 +434,21 @@ static void *copy(backend_t *base, const void *image, const region_t *reg) {
|
||||||
auto new_img = ccalloc(1, struct _xrender_image_data);
|
auto new_img = ccalloc(1, struct _xrender_image_data);
|
||||||
assert(img->visual != XCB_NONE);
|
assert(img->visual != XCB_NONE);
|
||||||
log_trace("xrender: copying %#010x visual %#x", img->pixmap, img->visual);
|
log_trace("xrender: copying %#010x visual %#x", img->pixmap, img->visual);
|
||||||
|
*new_img = *img;
|
||||||
x_set_picture_clip_region(base->c, img->pict, 0, 0, reg);
|
x_set_picture_clip_region(base->c, img->pict, 0, 0, reg);
|
||||||
new_img->has_alpha = img->has_alpha;
|
|
||||||
new_img->width = img->width;
|
|
||||||
new_img->height = img->height;
|
|
||||||
new_img->visual = img->visual;
|
|
||||||
new_img->pixmap =
|
new_img->pixmap =
|
||||||
x_create_pixmap(base->c, img->depth, base->root, img->width, img->height);
|
x_create_pixmap(base->c, img->depth, base->root, img->width, img->height);
|
||||||
new_img->opacity = 1;
|
new_img->opacity = 1;
|
||||||
new_img->owned = true;
|
new_img->owned = true;
|
||||||
if (new_img->pixmap == XCB_NONE) {
|
if (new_img->pixmap == XCB_NONE) {
|
||||||
|
log_error("Failed to create pixmap for copy");
|
||||||
free(new_img);
|
free(new_img);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
new_img->pict = x_create_picture_with_visual_and_pixmap(base->c, img->visual,
|
new_img->pict = x_create_picture_with_visual_and_pixmap(base->c, img->visual,
|
||||||
new_img->pixmap, 0, NULL);
|
new_img->pixmap, 0, NULL);
|
||||||
if (new_img->pixmap == XCB_NONE) {
|
if (new_img->pict == XCB_NONE) {
|
||||||
|
log_error("Failed to create picture for copy");
|
||||||
xcb_free_pixmap(base->c, new_img->pixmap);
|
xcb_free_pixmap(base->c, new_img->pixmap);
|
||||||
free(new_img);
|
free(new_img);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Loading…
Reference in New Issue