feat: layer zoom and fade animation support

This commit is contained in:
DreamMaoMao 2025-07-12 13:36:45 +08:00
parent 09d33d4412
commit 3e615fc762
5 changed files with 127 additions and 10 deletions

View file

@ -13,7 +13,8 @@ animation_type_close=slide
animation_fade_in=1 animation_fade_in=1
animation_fade_out=1 animation_fade_out=1
tag_animation_direction=1 tag_animation_direction=1
zoom_initial_ratio=0.5 zoom_initial_ratio=0.3
zoom_end_ratio=0.8
fadein_begin_opacity=0.5 fadein_begin_opacity=0.5
fadeout_begin_opacity=0.8 fadeout_begin_opacity=0.8
animation_duration_move=500 animation_duration_move=500

View file

@ -658,16 +658,16 @@ void init_fadeout_client(Client *c) {
} else { } else {
fadeout_cient->current.y = fadeout_cient->current.y =
(fadeout_cient->geom.height - (fadeout_cient->geom.height -
fadeout_cient->geom.height * zoom_initial_ratio) / fadeout_cient->geom.height * zoom_end_ratio) /
2; 2;
fadeout_cient->current.x = fadeout_cient->current.x =
(fadeout_cient->geom.width - (fadeout_cient->geom.width -
fadeout_cient->geom.width * zoom_initial_ratio) / fadeout_cient->geom.width * zoom_end_ratio) /
2; 2;
fadeout_cient->current.width = fadeout_cient->current.width =
fadeout_cient->geom.width * zoom_initial_ratio; fadeout_cient->geom.width * zoom_end_ratio;
fadeout_cient->current.height = fadeout_cient->current.height =
fadeout_cient->geom.height * zoom_initial_ratio; fadeout_cient->geom.height * zoom_end_ratio;
} }
fadeout_cient->animation.passed_frames = 0; fadeout_cient->animation.passed_frames = 0;

View file

@ -148,6 +148,43 @@ void set_layer_dir_animaiton(LayerSurface *l, struct wlr_box *geo) {
} }
} }
void layer_scene_buffer_apply_effect(struct wlr_scene_buffer *buffer, int sx,
int sy, void *data) {
animationScale *scale_data = (animationScale *)data;
struct wlr_scene_surface *scene_surface =
wlr_scene_surface_try_from_buffer(buffer);
if (scene_surface == NULL)
return;
struct wlr_surface *surface = scene_surface->surface;
if (scale_data->width_scale >= 0.99f) {
scale_data->width_scale = 1.0f;
}
if (scale_data->height_scale >= 0.99f) {
scale_data->height_scale = 1.0f;
}
unsigned int surface_width = surface->current.width;
unsigned int surface_height = surface->current.height;
surface_width = scale_data->width_scale * surface_width;
surface_height = scale_data->height_scale * surface_height;
if (surface_height > 0 && surface_width > 0) {
wlr_scene_buffer_set_dest_size(buffer, surface_width, surface_height);
}
}
void layer_fadeout_scene_buffer_apply_effect(struct wlr_scene_buffer *buffer,
int sx, int sy, void *data) {
animationScale *scale_data = (animationScale *)data;
wlr_scene_buffer_set_dest_size(buffer, scale_data->width,
scale_data->height);
}
void fadeout_layer_animation_next_tick(LayerSurface *l) { void fadeout_layer_animation_next_tick(LayerSurface *l) {
if (!l) if (!l)
return; return;
@ -170,6 +207,20 @@ void fadeout_layer_animation_next_tick(LayerSurface *l) {
wlr_scene_node_set_position(&l->scene->node, x, y); wlr_scene_node_set_position(&l->scene->node, x, y);
animationScale scale_data;
scale_data.width = width;
scale_data.height = height;
if (((!l->animation_type_close &&
strcmp(layer_animation_type_close, "zoom") == 0) ||
(l->animation_type_close &&
strcmp(l->animation_type_close, "zoom") == 0)) &&
(width != l->current.width || height != l->current.height)) {
wlr_scene_node_for_each_buffer(&l->scene->node,
layer_fadeout_scene_buffer_apply_effect,
&scale_data);
}
l->animation.current = (struct wlr_box){ l->animation.current = (struct wlr_box){
.x = x, .x = x,
.y = y, .y = y,
@ -224,6 +275,19 @@ void layer_animation_next_tick(LayerSurface *l) {
wlr_scene_node_set_position(&l->scene->node, x, y); wlr_scene_node_set_position(&l->scene->node, x, y);
animationScale scale_data;
scale_data.width_scale = (float)width / (float)l->current.width;
scale_data.height_scale = (float)height / (float)l->current.height;
if (((!l->animation_type_open &&
strcmp(layer_animation_type_open, "zoom") == 0) ||
(l->animation_type_open &&
strcmp(l->animation_type_open, "zoom") == 0)) &&
(scale_data.width_scale != 1.0 || scale_data.height_scale != 1.0)) {
wlr_scene_node_for_each_buffer(
&l->scene->node, layer_scene_buffer_apply_effect, &scale_data);
}
l->animation.current = (struct wlr_box){ l->animation.current = (struct wlr_box){
.x = x, .x = x,
.y = y, .y = y,
@ -266,6 +330,14 @@ void init_fadeout_layers(LayerSurface *l) {
LayerSurface *fadeout_layer = ecalloc(1, sizeof(*fadeout_layer)); LayerSurface *fadeout_layer = ecalloc(1, sizeof(*fadeout_layer));
const struct wlr_layer_surface_v1_state *state = &l->layer_surface->current;
struct wlr_box usable_area;
if (state->exclusive_zone > 0 || state->exclusive_zone == -1)
usable_area = l->mon->m;
else
usable_area = l->mon->w;
wlr_scene_node_set_enabled(&l->scene->node, true); wlr_scene_node_set_enabled(&l->scene->node, true);
fadeout_layer->scene = fadeout_layer->scene =
wlr_scene_tree_snapshot(&l->scene->node, layers[LyrFadeOut]); wlr_scene_tree_snapshot(&l->scene->node, layers[LyrFadeOut]);
@ -282,6 +354,8 @@ void init_fadeout_layers(LayerSurface *l) {
l->animation.current; l->animation.current;
fadeout_layer->mon = l->mon; fadeout_layer->mon = l->mon;
fadeout_layer->animation.action = CLOSE; fadeout_layer->animation.action = CLOSE;
fadeout_layer->animation_type_close = l->animation_type_close;
fadeout_layer->animation_type_open = l->animation_type_open;
// 这里snap节点的坐标设置是使用的相对坐标所以不能加上原来坐标 // 这里snap节点的坐标设置是使用的相对坐标所以不能加上原来坐标
// 这跟普通node有区别 // 这跟普通node有区别
@ -290,9 +364,26 @@ void init_fadeout_layers(LayerSurface *l) {
fadeout_layer->animation.initial.y = 0; fadeout_layer->animation.initial.y = 0;
if ((!l->animation_type_close && if ((!l->animation_type_close &&
strcmp(layer_animation_type_close, "slide") == 0) || strcmp(layer_animation_type_close, "zoom") == 0) ||
(l->animation_type_close && (l->animation_type_close &&
strcmp(l->animation_type_close, "slide") == 0)) { strcmp(l->animation_type_close, "zoom") == 0)) {
fadeout_layer->current.width = (float)l->geom.width * zoom_end_ratio;
fadeout_layer->current.height = (float)l->geom.height * zoom_end_ratio;
fadeout_layer->current.x = usable_area.x + usable_area.width / 2 -
fadeout_layer->current.width / 2;
fadeout_layer->current.y = usable_area.y + usable_area.height / 2 -
fadeout_layer->current.height / 2;
// 算出偏差
fadeout_layer->current.x = fadeout_layer->current.x - l->geom.x;
fadeout_layer->current.y = fadeout_layer->current.y - l->geom.y;
// wlr_log(WLR_ERROR,"%d %d %d
// %d",fadeout_layer->current.x,fadeout_layer->current.y,fadeout_layer->current.width,fadeout_layer->current.height);
} else if ((!l->animation_type_close &&
strcmp(layer_animation_type_close, "slide") == 0) ||
(l->animation_type_close &&
strcmp(l->animation_type_close, "slide") == 0)) {
set_layer_dir_animaiton(l, &fadeout_layer->current); set_layer_dir_animaiton(l, &fadeout_layer->current);
fadeout_layer->current.x = fadeout_layer->current.x - l->geom.x; fadeout_layer->current.x = fadeout_layer->current.x - l->geom.x;
fadeout_layer->current.y = fadeout_layer->current.y - l->geom.y; fadeout_layer->current.y = fadeout_layer->current.y - l->geom.y;
@ -319,12 +410,31 @@ void layer_set_pending_state(LayerSurface *l) {
if (!l || !l->mapped) if (!l || !l->mapped)
return; return;
const struct wlr_layer_surface_v1_state *state = &l->layer_surface->current;
struct wlr_box usable_area;
if (state->exclusive_zone > 0 || state->exclusive_zone == -1)
usable_area = l->mon->m;
else
usable_area = l->mon->w;
l->pending = l->geom; l->pending = l->geom;
if (l->animation.action == OPEN) { if (l->animation.action == OPEN) {
if ((!l->animation_type_open && if ((!l->animation_type_open &&
strcmp(layer_animation_type_open, "slide") == 0) || strcmp(layer_animation_type_open, "zoom") == 0) ||
(l->animation_type_open && (l->animation_type_open &&
strcmp(l->animation_type_open, "slide") == 0)) { strcmp(l->animation_type_open, "zoom") == 0)) {
l->animainit_geom.width = l->geom.width * zoom_initial_ratio;
l->animainit_geom.height = l->geom.height * zoom_initial_ratio;
l->animainit_geom.x = usable_area.x + usable_area.width / 2 -
l->animainit_geom.width / 2;
l->animainit_geom.y = usable_area.y + usable_area.height / 2 -
l->animainit_geom.height / 2;
} else if ((!l->animation_type_open &&
strcmp(layer_animation_type_open, "slide") == 0) ||
(l->animation_type_open &&
strcmp(l->animation_type_open, "slide") == 0)) {
set_layer_dir_animaiton(l, &l->animainit_geom); set_layer_dir_animaiton(l, &l->animainit_geom);
} else { } else {

View file

@ -144,6 +144,7 @@ typedef struct {
int animation_fade_out; int animation_fade_out;
int tag_animation_direction; int tag_animation_direction;
float zoom_initial_ratio; float zoom_initial_ratio;
float zoom_end_ratio;
float fadein_begin_opacity; float fadein_begin_opacity;
float fadeout_begin_opacity; float fadeout_begin_opacity;
uint32_t animation_duration_move; uint32_t animation_duration_move;
@ -865,6 +866,8 @@ void parse_config_line(Config *config, const char *line) {
config->tag_animation_direction = atoi(value); config->tag_animation_direction = atoi(value);
} else if (strcmp(key, "zoom_initial_ratio") == 0) { } else if (strcmp(key, "zoom_initial_ratio") == 0) {
config->zoom_initial_ratio = atof(value); config->zoom_initial_ratio = atof(value);
} else if (strcmp(key, "zoom_end_ratio") == 0) {
config->zoom_end_ratio = atof(value);
} else if (strcmp(key, "fadein_begin_opacity") == 0) { } else if (strcmp(key, "fadein_begin_opacity") == 0) {
config->fadein_begin_opacity = atof(value); config->fadein_begin_opacity = atof(value);
} else if (strcmp(key, "fadeout_begin_opacity") == 0) { } else if (strcmp(key, "fadeout_begin_opacity") == 0) {
@ -2077,6 +2080,7 @@ void override_config(void) {
animation_fade_in = CLAMP_INT(config.animation_fade_in, 0, 1); animation_fade_in = CLAMP_INT(config.animation_fade_in, 0, 1);
animation_fade_out = CLAMP_INT(config.animation_fade_out, 0, 1); animation_fade_out = CLAMP_INT(config.animation_fade_out, 0, 1);
zoom_initial_ratio = CLAMP_FLOAT(config.zoom_initial_ratio, 0.1f, 1.0f); zoom_initial_ratio = CLAMP_FLOAT(config.zoom_initial_ratio, 0.1f, 1.0f);
zoom_end_ratio = CLAMP_FLOAT(config.zoom_end_ratio, 0.1f, 1.0f);
fadein_begin_opacity = CLAMP_FLOAT(config.fadein_begin_opacity, 0.0f, 1.0f); fadein_begin_opacity = CLAMP_FLOAT(config.fadein_begin_opacity, 0.0f, 1.0f);
fadeout_begin_opacity = fadeout_begin_opacity =
CLAMP_FLOAT(config.fadeout_begin_opacity, 0.0f, 1.0f); CLAMP_FLOAT(config.fadeout_begin_opacity, 0.0f, 1.0f);
@ -2213,6 +2217,7 @@ void set_value_default() {
config.animation_fade_out = animation_fade_out; // Enable animation fade out config.animation_fade_out = animation_fade_out; // Enable animation fade out
config.tag_animation_direction = tag_animation_direction; // 标签动画方向 config.tag_animation_direction = tag_animation_direction; // 标签动画方向
config.zoom_initial_ratio = zoom_initial_ratio; // 动画起始窗口比例 config.zoom_initial_ratio = zoom_initial_ratio; // 动画起始窗口比例
config.zoom_end_ratio = zoom_end_ratio; // 动画结束窗口比例
config.fadein_begin_opacity = config.fadein_begin_opacity =
fadein_begin_opacity; // Begin opac window ratio for animations fadein_begin_opacity; // Begin opac window ratio for animations
config.fadeout_begin_opacity = fadeout_begin_opacity; config.fadeout_begin_opacity = fadeout_begin_opacity;

View file

@ -17,7 +17,8 @@ int layer_animations = 0; // 是否启用layer动画
int tag_animation_direction = HORIZONTAL; // 标签动画方向 int tag_animation_direction = HORIZONTAL; // 标签动画方向
int animation_fade_in = 1; // Enable animation fade in int animation_fade_in = 1; // Enable animation fade in
int animation_fade_out = 1; // Enable animation fade out int animation_fade_out = 1; // Enable animation fade out
float zoom_initial_ratio = 0.5; // 动画起始窗口比例 float zoom_initial_ratio = 0.3; // 动画起始窗口比例
float zoom_end_ratio = 0.8; // 动画结束窗口比例
float fadein_begin_opacity = 0.5; // Begin opac window ratio for animations float fadein_begin_opacity = 0.5; // Begin opac window ratio for animations
float fadeout_begin_opacity = 0.5; // Begin opac window ratio for animations float fadeout_begin_opacity = 0.5; // Begin opac window ratio for animations
uint32_t animation_duration_move = 500; // Animation move speed uint32_t animation_duration_move = 500; // Animation move speed