mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2025-11-21 06:59:53 -05:00
feat: add smooth focus transition animation for opacity and border
This adds animated transitions when switching focus between windows. Both window opacity and border color now fade smoothly using cubic bezier easing instead of changing instantly. Implementation: - Added animation_duration_focus config option (default 400ms) - Added animation_curve_focus for cubic bezier easing curve - Window opacity and border color animate together when focus changes - Uses existing animation infrastructure (baked bezier points) The feature is backwards compatible and can be disabled by setting animation_duration_focus=0 in config file. Changes affect 5 files with minimal additions to keep code clean.
This commit is contained in:
parent
cbfd20bff8
commit
e0f114af59
5 changed files with 86 additions and 7 deletions
|
|
@ -932,12 +932,35 @@ bool client_draw_frame(Client *c) {
|
|||
if (!c || !client_surface(c)->mapped)
|
||||
return false;
|
||||
|
||||
// Animate focus transitions (opacity + border color)
|
||||
if (c->isfullscreen) {
|
||||
client_set_opacity(c, 1);
|
||||
} else if (c == selmon->sel && !c->animation.running) {
|
||||
client_set_opacity(c, c->focused_opacity);
|
||||
} else if (!c->animation.running) {
|
||||
client_set_opacity(c, c->unfocused_opacity);
|
||||
c->current_opacity = 1;
|
||||
c->target_opacity = 1;
|
||||
} else if (c->opacity_animation_frames > 0 && c->opacity_animation_passed < c->opacity_animation_frames) {
|
||||
float linear_progress = (float)c->opacity_animation_passed / c->opacity_animation_frames;
|
||||
float eased_progress = find_animation_curve_at(linear_progress, FOCUS);
|
||||
|
||||
// Animate opacity
|
||||
float opacity_start = (c->target_opacity == c->focused_opacity) ? c->unfocused_opacity : c->focused_opacity;
|
||||
c->current_opacity = opacity_start + (c->target_opacity - opacity_start) * eased_progress;
|
||||
client_set_opacity(c, c->current_opacity);
|
||||
|
||||
// Animate border color
|
||||
bool focusing = (c->target_border_color[0] == focuscolor[0]);
|
||||
float *border_start = focusing ? bordercolor : focuscolor;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
c->current_border_color[i] = border_start[i] + (c->target_border_color[i] - border_start[i]) * eased_progress;
|
||||
}
|
||||
client_set_border_color(c, c->current_border_color);
|
||||
|
||||
c->opacity_animation_passed++;
|
||||
} else {
|
||||
// Animation complete or disabled - apply target values
|
||||
c->current_opacity = c->target_opacity;
|
||||
client_set_opacity(c, c->current_opacity);
|
||||
memcpy(c->current_border_color, c->target_border_color, sizeof(c->current_border_color));
|
||||
client_set_border_color(c, c->current_border_color);
|
||||
}
|
||||
|
||||
if (!c->need_output_flush)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ struct dvec2 calculate_animation_curve_at(double t, int type) {
|
|||
animation_curve = animation_curve_tag;
|
||||
} else if (type == CLOSE) {
|
||||
animation_curve = animation_curve_close;
|
||||
} else if (type == FOCUS) {
|
||||
animation_curve = animation_curve_focus;
|
||||
} else {
|
||||
animation_curve = animation_curve_move;
|
||||
}
|
||||
|
|
@ -28,6 +30,8 @@ void init_baked_points(void) {
|
|||
baked_points_tag = calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_tag));
|
||||
baked_points_close =
|
||||
calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_close));
|
||||
baked_points_focus =
|
||||
calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_focus));
|
||||
|
||||
for (unsigned int i = 0; i < BAKED_POINTS_COUNT; i++) {
|
||||
baked_points_move[i] = calculate_animation_curve_at(
|
||||
|
|
@ -45,6 +49,10 @@ void init_baked_points(void) {
|
|||
baked_points_close[i] = calculate_animation_curve_at(
|
||||
(double)i / (BAKED_POINTS_COUNT - 1), CLOSE);
|
||||
}
|
||||
for (unsigned int i = 0; i < BAKED_POINTS_COUNT; i++) {
|
||||
baked_points_focus[i] = calculate_animation_curve_at(
|
||||
(double)i / (BAKED_POINTS_COUNT - 1), FOCUS);
|
||||
}
|
||||
}
|
||||
|
||||
double find_animation_curve_at(double t, int type) {
|
||||
|
|
@ -61,6 +69,8 @@ double find_animation_curve_at(double t, int type) {
|
|||
baked_points = baked_points_tag;
|
||||
} else if (type == CLOSE) {
|
||||
baked_points = baked_points_close;
|
||||
} else if (type == FOCUS) {
|
||||
baked_points = baked_points_focus;
|
||||
} else {
|
||||
baked_points = baked_points_move;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue