fix: Avoid animation ghosting

This commit is contained in:
DreamMaoMao 2025-06-14 10:21:30 +08:00
parent d5c8a7bd91
commit 33947c30f2

View file

@ -1108,13 +1108,12 @@ bool check_hit_no_border(Client *c) {
return hit_no_border;
}
void
client_draw_shadow(Client *c) {
void client_draw_shadow(Client *c) {
if (c->iskilling || !client_surface(c)->mapped)
return;
if(!shadows || !c->isfloating) {
if (!shadows || !c->isfloating) {
wlr_scene_shadow_set_size(c->shadow, 0, 0);
return;
}
@ -1141,7 +1140,8 @@ client_draw_shadow(Client *c) {
struct wlr_box intersection_box;
wlr_box_intersection(&intersection_box, &client_box, &shadow_box);
/* clipped region takes shadow relative coords, so we translate everything by its position */
/* clipped region takes shadow relative coords, so we translate everything
* by its position */
intersection_box.x -= shadows_position_x;
intersection_box.y -= shadows_position_y;
@ -1157,8 +1157,8 @@ client_draw_shadow(Client *c) {
wlr_scene_shadow_set_clipped_region(c->shadow, clipped_region);
}
void apply_border(Client *c, struct wlr_box clip_box, int offsetx,
int offsety, enum corner_location border_radius_location) {
void apply_border(Client *c, struct wlr_box clip_box, int offsetx, int offsety,
enum corner_location border_radius_location) {
bool hit_no_border = false;
if (c->iskilling || !client_surface(c)->mapped)
@ -1172,7 +1172,7 @@ void apply_border(Client *c, struct wlr_box clip_box, int offsetx,
clip_box.height = c->animation.current.height;
}
hit_no_border = check_hit_no_border(c);
hit_no_border = check_hit_no_border(c);
if (hit_no_border && smartgaps) {
c->bw = 0;
@ -1190,11 +1190,11 @@ hit_no_border = check_hit_no_border(c);
int clip_box_width = clip_box.width - 2 * c->bw;
int clip_box_height = clip_box.height - 2 * c->bw;
if(clip_box_width < 0) {
if (clip_box_width < 0) {
clip_box_width = 0;
}
if(clip_box_height < 0) {
if (clip_box_height < 0) {
clip_box_height = 0;
}
@ -1205,30 +1205,35 @@ hit_no_border = check_hit_no_border(c);
clip_y = clip_y < 0 ? 0 : clip_y;
struct clipped_region clipped_region = {
.area = { clip_x, clip_y, clip_box_width, clip_box_height },
.area = {clip_x, clip_y, clip_box_width, clip_box_height},
.corner_radius = border_radius,
.corners = border_radius_location,
};
int right_offset = GEZERO(c->animation.current.x + c->animation.current.width - c->mon->m.x - c->mon->m.width);
int bottom_offset = GEZERO(c->animation.current.y + c->animation.current.height - c->mon->m.y - c->mon->m.height);
int right_offset =
GEZERO(c->animation.current.x + c->animation.current.width -
c->mon->m.x - c->mon->m.width);
int bottom_offset =
GEZERO(c->animation.current.y + c->animation.current.height -
c->mon->m.y - c->mon->m.height);
int rect_width = clip_box.width;
int rect_height = clip_box.height;
if(right_offset > 0) {
clipped_region.area.width = MIN(clip_box.width,clipped_region.area.width + right_offset);
if (right_offset > 0) {
clipped_region.area.width =
MIN(clip_box.width, clipped_region.area.width + right_offset);
}
if(bottom_offset > 0) {
clipped_region.area.height = MIN(clip_box.height,clipped_region.area.height + bottom_offset);
if (bottom_offset > 0) {
clipped_region.area.height =
MIN(clip_box.height, clipped_region.area.height + bottom_offset);
}
if(rect_width < 0) {
if (rect_width < 0) {
rect_width = 0;
}
if(rect_height < 0) {
if (rect_height < 0) {
rect_height = 0;
}
@ -1238,7 +1243,8 @@ hit_no_border = check_hit_no_border(c);
wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw);
wlr_scene_rect_set_size(c->border, rect_width, rect_height);
wlr_scene_node_set_position(&c->border->node, node_x, node_y);
wlr_scene_rect_set_corner_radius(c->border, border_radius, border_radius_location);
wlr_scene_rect_set_corner_radius(c->border, border_radius,
border_radius_location);
wlr_scene_rect_set_clipped_region(c->border, clipped_region);
}
@ -1283,7 +1289,8 @@ struct uvec2 clip_to_hide(Client *c, struct wlr_box *clip_box) {
clip_box->width = clip_box->width - offsetx;
} else if (c->animation.current.x + c->animation.current.width >
c->mon->m.x + c->mon->m.width) {
clip_box->width = clip_box->width -
clip_box->width =
clip_box->width -
(c->animation.current.x + c->animation.current.width -
c->mon->m.x - c->mon->m.width) +
c->bw;
@ -1296,7 +1303,8 @@ struct uvec2 clip_to_hide(Client *c, struct wlr_box *clip_box) {
clip_box->height = clip_box->height - offsety;
} else if (c->animation.current.y + c->animation.current.height >
c->mon->m.y + c->mon->m.height) {
clip_box->height = clip_box->height -
clip_box->height =
clip_box->height -
(c->animation.current.y + c->animation.current.height -
c->mon->m.y - c->mon->m.height) +
c->bw;
@ -1332,9 +1340,11 @@ void client_apply_clip(Client *c) {
return;
struct wlr_box clip_box;
struct uvec2 offset;
bool should_render_client_surface = false;
animationScale scale_data;
struct wlr_box surface_clip;
enum corner_location current_corner_location = set_client_corner_location(c);
enum corner_location current_corner_location =
set_client_corner_location(c);
if (!animations) {
c->animation.running = false;
@ -1352,12 +1362,14 @@ void client_apply_clip(Client *c) {
surface_clip.width = surface_clip.width - 2 * c->bw;
surface_clip.height = surface_clip.height - 2 * c->bw;
if(surface_clip.width <= 0 || surface_clip.height <= 0) {
if (surface_clip.width <= 0 || surface_clip.height <= 0) {
return;
}
wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &surface_clip);
buffer_set_effect(c, (animationScale){0, 0, 0, 0, current_corner_location,false});
wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node,
&surface_clip);
buffer_set_effect(
c, (animationScale){0, 0, 0, 0, current_corner_location, false});
return;
}
@ -1379,26 +1391,43 @@ void client_apply_clip(Client *c) {
}
offset = clip_to_hide(c, &clip_box);
apply_border(c, clip_box, offset.x, offset.y, current_corner_location);
client_draw_shadow(c);
surface_clip = clip_box;
surface_clip.width = surface_clip.width - 2 * c->bw;
surface_clip.height = surface_clip.height - 2 * c->bw;
if(surface_clip.width <= 0 || surface_clip.height <= 0) {
if (surface_clip.width <= 0 || surface_clip.height <= 0) {
should_render_client_surface = false;
wlr_scene_node_set_enabled(&c->scene_surface->node, false);
} else {
should_render_client_surface = true;
wlr_scene_node_set_enabled(&c->scene_surface->node, true);
}
apply_border(c, clip_box, offset.x, offset.y, current_corner_location);
client_draw_shadow(c);
if (!should_render_client_surface) {
return;
}
wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &surface_clip);
scale_data.should_scale = true;
scale_data.width = clip_box.width - 2 * c->bw;
scale_data.height = clip_box.height - 2 * c->bw;
scale_data.width_scale = (float)scale_data.width / (geometry.width - offset.x);
scale_data.height_scale = (float)scale_data.height / (geometry.height - offset.y);
scale_data.width_scale =
(float)scale_data.width / (geometry.width - offset.x);
scale_data.height_scale =
(float)scale_data.height / (geometry.height - offset.y);
scale_data.corner_location = current_corner_location;
scale_data.percent = c->animation.action == OPEN && animation_fade_in && !c->nofadein ? (double)c->animation.passed_frames / c->animation.total_frames : 1.0;
scale_data.opacity = c->isfullscreen ? 1 : c == selmon->sel ? c->focused_opacity : c->unfocused_opacity;
scale_data.percent =
c->animation.action == OPEN && animation_fade_in && !c->nofadein
? (double)c->animation.passed_frames / c->animation.total_frames
: 1.0;
scale_data.opacity = c->isfullscreen ? 1
: c == selmon->sel ? c->focused_opacity
: c->unfocused_opacity;
buffer_set_effect(c, scale_data);
}
@ -4713,14 +4742,16 @@ static void iter_xdg_scene_buffers(struct wlr_scene_buffer *buffer, int sx,
int sy, void *user_data) {
Client *c = user_data;
struct wlr_scene_surface * scene_surface = wlr_scene_surface_try_from_buffer(buffer);
struct wlr_scene_surface *scene_surface =
wlr_scene_surface_try_from_buffer(buffer);
if (!scene_surface) {
return;
}
struct wlr_surface *surface = scene_surface->surface;
/* we dont blur subsurfaces */
if(wlr_subsurface_try_from_wlr_surface(surface) != NULL) return;
if (wlr_subsurface_try_from_wlr_surface(surface) != NULL)
return;
if (blur && c) {
wlr_scene_buffer_set_backdrop_blur(buffer, true);