Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: fade in and fade out animations #164

Draft
wants to merge 41 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
b5410a1
initial fade-in work
WillPower3309 May 23, 2023
3f5511d
ensured alpha isn't exceeded, added calculation for alpha_step from a…
WillPower3309 May 23, 2023
f721ef7
renamed container alpha vars
WillPower3309 May 23, 2023
2d14d1e
fixed fade in for children cons
WillPower3309 May 30, 2023
4c68263
optimized math of alpha_step
WillPower3309 May 30, 2023
5bfa2e0
added animation config
WillPower3309 May 30, 2023
6084ea4
fade-out skeleton
WillPower3309 Jul 6, 2023
e51fda4
initial fade-out groundwork
WillPower3309 Jul 20, 2023
1c3b4a1
fixed animation duration of 0 bug
WillPower3309 Aug 8, 2023
3cb407e
moved animation to timer
WillPower3309 Aug 9, 2023
0766597
fixed con kill issue
WillPower3309 Aug 9, 2023
87f33da
added fade out
WillPower3309 Aug 19, 2023
6383731
fixed fade-in delay
WillPower3309 Aug 21, 2023
f119e9e
add shadow fade in / out with animation
WillPower3309 Aug 21, 2023
1390f9d
blur texture fades in / out with con
WillPower3309 Aug 23, 2023
e20b886
blur texture fades in / out with con
WillPower3309 Aug 23, 2023
71fa52f
started the switch to a fb approach
WillPower3309 Dec 22, 2023
2c57e2a
moved to fb approach, much broken
WillPower3309 Dec 27, 2023
d7cf298
view_close now works as intended
WillPower3309 Jan 3, 2024
a27fa24
render saved buffer on fade-out
WillPower3309 Feb 1, 2024
30e18aa
fixed many segfaults
WillPower3309 Feb 2, 2024
a3ef0be
added cleanup
WillPower3309 Feb 6, 2024
9de0237
added back save buffer on fade out
WillPower3309 Feb 7, 2024
b1c8ff5
cleaned up some comments + print debug statements
WillPower3309 Feb 7, 2024
d741e24
fixed focus issues
WillPower3309 Feb 19, 2024
e558731
added animation manager
WillPower3309 Feb 25, 2024
74a7d25
improved performance
WillPower3309 Feb 25, 2024
8c7287d
update logic to damage track properly
WillPower3309 Feb 29, 2024
508df22
minor renaming and changed return val to 0
WillPower3309 Feb 29, 2024
ae1700f
added temp fix for h split
WillPower3309 Mar 1, 2024
d1fe550
made appearance of rapidly closing windows more pleasant
WillPower3309 Mar 4, 2024
f92b99a
updated comments
WillPower3309 Mar 4, 2024
bdd985c
Merge remote-tracking branch 'origin/master' into fade-animations
WillPower3309 Apr 18, 2024
f595d42
removed old import
WillPower3309 Apr 18, 2024
107bcde
removed unneeded debug lines
WillPower3309 Apr 20, 2024
819572a
logic improvements
WillPower3309 Apr 20, 2024
e8f7a90
Merge remote-tracking branch 'origin/master' into fade-animations
WillPower3309 Apr 20, 2024
ad0b917
minor perf improvements, fixed render saved view race con
WillPower3309 Apr 22, 2024
1d1b4fb
improved animation timing
WillPower3309 Apr 22, 2024
ae12a9c
Merge remote-tracking branch 'origin/master' into fade-animations
WillPower3309 May 8, 2024
6293a23
Merge remote-tracking branch 'origin/master' into fade-animations
WillPower3309 May 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ Sway is an incredible window manager, and certainly one of the most well establi

## New Configuration Options

+ Fade in / out animations: `animation_duration <val>`: specifies the length of the animation in seconds
+ Corner radius: `corner_radius <val>`
+ Smart corner radius: `smart_corner_radius enable|disable`
+ Window shadows:
- `shadows enable|disable`
- `shadows_on_csd enable|disable` (**Note**: The shadow might not fit some windows)
- `shadow_blur_radius <integer value 0 - 100>`
- `shadow_color <hex color with alpha> ex, #0000007F`
+ Window blur:
- `blur enable|disable`
- `blur_xray enable|disable`: this will set floating windows to blur based on the background, not the windows below. You probably want to set this to `disable` :)
Expand Down Expand Up @@ -64,7 +72,6 @@ Sway is an incredible window manager, and certainly one of the most well establi

## Roadmap

+ fade in / out animations
+ window movement animations

## Compiling From Source
Expand Down Expand Up @@ -137,4 +144,3 @@ We would also like to thank the talented artists in our community for contibutin
+ spooky_skeleton for the swayfx logo, and [Basil](https://basil.cafe) for making some fine adjustments to it

Lastly, we would like to thank you, the community, for enjoying and using window manager that we have spent so much time maintaining.

1 change: 1 addition & 0 deletions include/sway/commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ bool cmd_corner_radius_parse_value(char *arg, int* result);
sway_cmd cmd_exec_validate;
sway_cmd cmd_exec_process;

sway_cmd cmd_animation_duration;
sway_cmd cmd_assign;
sway_cmd cmd_bar;
sway_cmd cmd_bindcode;
Expand Down
2 changes: 2 additions & 0 deletions include/sway/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,8 @@ enum xwayland_mode {
* The configuration struct. The result of loading a config file.
*/
struct sway_config {
float animation_duration;

int corner_radius;
bool smart_corner_radius;

Expand Down
1 change: 1 addition & 0 deletions include/sway/output.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ struct sway_output {

struct timespec last_presentation;
uint32_t refresh_nsec;
float refresh_sec;
int max_render_time; // In milliseconds
struct wl_event_source *repaint_timer;
bool gamma_lut_changed;
Expand Down
3 changes: 3 additions & 0 deletions include/sway/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ struct sway_server {
// Stores the nodes that have been marked as "dirty" and will be put into
// the pending transaction.
list_t *dirty_nodes;

list_t *animated_containers;
struct wl_event_source *animation_tick;
};

extern struct sway_server server;
Expand Down
5 changes: 4 additions & 1 deletion include/sway/tree/container.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,13 @@ struct sway_container {
// Unused for non-scratchpad windows.
struct wlr_box transform;

// TODO: move alpha to state?
float alpha;
float target_alpha;
float max_alpha;

int corner_radius;

float dim;

struct wlr_texture *title_focused;
Expand Down
2 changes: 2 additions & 0 deletions include/sway/tree/view.h
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,8 @@ void view_for_each_popup_surface(struct sway_view *view,
void view_init(struct sway_view *view, enum sway_view_type type,
const struct sway_view_impl *impl);

void view_remove_container(struct sway_container *container);

void view_destroy(struct sway_view *view);

void view_begin_destroy(struct sway_view *view);
Expand Down
1 change: 1 addition & 0 deletions sway/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ struct cmd_results *checkarg(int argc, const char *name, enum expected_args type

/* Keep alphabetized */
static const struct cmd_handler handlers[] = {
{ "animation_duration", cmd_animation_duration },
{ "assign", cmd_assign },
{ "bar", cmd_bar },
{ "bindcode", cmd_bindcode },
Expand Down
21 changes: 21 additions & 0 deletions sway/commands/animation_duration.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include <string.h>
#include "sway/commands.h"
#include "sway/config.h"
#include "log.h"

struct cmd_results *cmd_animation_duration(int argc, char **argv) {
struct cmd_results *error = NULL;
if ((error = checkarg(argc, "animation_duration", EXPECTED_EQUAL_TO, 1))) {
return error;
}

char *err;
float value = strtof(argv[0], &err);
if (*err || value < 0.0f || value > 1.0f) {
return cmd_results_new(CMD_FAILURE, "animation_duration value invalid");
}

config->animation_duration = value;

return cmd_results_new(CMD_SUCCESS, NULL);
}
7 changes: 4 additions & 3 deletions sway/commands/opacity.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ struct cmd_results *cmd_opacity(int argc, char **argv) {
}

if (!strcasecmp(argv[0], "plus")) {
val = con->alpha + val;
val = con->max_alpha + val;
} else if (!strcasecmp(argv[0], "minus")) {
val = con->alpha - val;
val = con->max_alpha - val;
} else if (argc > 1 && strcasecmp(argv[0], "set")) {
return cmd_results_new(CMD_INVALID,
"Expected: set|plus|minus <0..1>: %s", argv[0]);
Expand All @@ -36,7 +36,8 @@ struct cmd_results *cmd_opacity(int argc, char **argv) {
return cmd_results_new(CMD_FAILURE, "opacity value out of bounds");
}

con->alpha = val;
con->max_alpha = val;
con->target_alpha = val;
container_damage_whole(con);
return cmd_results_new(CMD_SUCCESS, NULL);
}
2 changes: 2 additions & 0 deletions sway/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,8 @@ static void config_defaults(struct sway_config *config) {
color_to_rgba(config->border_colors.background, 0xFFFFFFFF);

// SwayFX defaults
config->animation_duration = 0;

config->corner_radius = 0;
config->smart_corner_radius = true;

Expand Down
6 changes: 5 additions & 1 deletion sway/desktop/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,7 @@ static int output_repaint_timer_handler(void *data) {

pixman_region32_t damage;
pixman_region32_init(&damage);

wlr_damage_ring_get_buffer_damage(&output->damage_ring, buffer_age, &damage);

if (debug.damage == DAMAGE_RERENDER) {
Expand Down Expand Up @@ -729,7 +730,7 @@ static void handle_frame(struct wl_listener *listener, void *user_data) {
const long NSEC_IN_SECONDS = 1000000000;
struct timespec predicted_refresh = output->last_presentation;
predicted_refresh.tv_nsec += output->refresh_nsec % NSEC_IN_SECONDS;
predicted_refresh.tv_sec += output->refresh_nsec / NSEC_IN_SECONDS;
predicted_refresh.tv_sec += output->refresh_sec;
if (predicted_refresh.tv_nsec >= NSEC_IN_SECONDS) {
predicted_refresh.tv_sec += 1;
predicted_refresh.tv_nsec -= NSEC_IN_SECONDS;
Expand Down Expand Up @@ -1030,6 +1031,9 @@ static void handle_present(struct wl_listener *listener, void *data) {

output->last_presentation = *output_event->when;
output->refresh_nsec = output_event->refresh;

const long NSEC_IN_SECONDS = 1000000000;
output->refresh_sec = (float)output_event->refresh / NSEC_IN_SECONDS;
}

static void handle_request_state(struct wl_listener *listener, void *data) {
Expand Down
24 changes: 18 additions & 6 deletions sway/desktop/render.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,14 @@ struct decoration_data get_undecorated_decoration_data() {
};
}

// TODO: don't need pointer
float get_animation_completion_percentage(struct sway_container *con) {
if (con->alpha == 1.0f) {
return 1.0f;
}
return con->alpha < con->target_alpha ? con->alpha / con->target_alpha : con->alpha / con->max_alpha;
}

/**
* Apply scale to a width or height.
*
Expand Down Expand Up @@ -375,10 +383,11 @@ static void render_surface_iterator(struct sway_output *output,

if (has_alpha) {
bool should_optimize_blur = view ?
!container_is_floating_or_child(view->container) || config->blur_xray
: false;
!container_is_floating_or_child(view->container) || config->blur_xray : false;
struct decoration_data blur_deco_data = deco_data;
blur_deco_data.alpha = view ? get_animation_completion_percentage(view->container) : 1.0f;
render_blur(data->ctx, texture, &src_box, &clip_box,
should_optimize_blur, &opaque_region, deco_data);
should_optimize_blur, &opaque_region, blur_deco_data);
}

pixman_region32_fini(&opaque_region);
Expand Down Expand Up @@ -677,9 +686,11 @@ static void render_saved_view(struct fx_render_context *ctx, struct sway_view *v
pixman_region32_union_rect(&opaque_region, &opaque_region, 0, 0, 0, 0);

bool should_optimize_blur = !container_is_floating_or_child(view->container) || config->blur_xray;
render_blur(ctx, saved_buf->buffer->texture,
&saved_buf->source_box, &clip_box, should_optimize_blur,
&opaque_region, deco_data);
struct decoration_data blur_deco_data = deco_data;
blur_deco_data.alpha = get_animation_completion_percentage(view->container);

render_blur(ctx, saved_buf->buffer->texture, &saved_buf->source_box, &clip_box,
should_optimize_blur, &opaque_region, blur_deco_data);

pixman_region32_fini(&opaque_region);
}
Expand Down Expand Up @@ -729,6 +740,7 @@ static void render_view(struct fx_render_context *ctx, struct sway_container *co
int shadow_corner_radius = corner_radius == 0 ? 0 : corner_radius + state->border_thickness;
float* shadow_color = view_is_urgent(view) || state->focused ?
config->shadow_color : config->shadow_inactive_color;
shadow_color[3] *= get_animation_completion_percentage(con);

render_box_shadow(ctx, &box, shadow_color, config->shadow_blur_sigma * output_scale,
shadow_corner_radius * output_scale, config->shadow_offset_x * output_scale,
Expand Down
5 changes: 4 additions & 1 deletion sway/desktop/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ static void apply_container_state(struct sway_container *container,

memcpy(&container->current, state, sizeof(struct sway_container_state));

if (view && !wl_list_empty(&view->saved_buffers)) {
if (view && !wl_list_empty(&view->saved_buffers) && view->surface) {
if (!container->node.destroying || container->node.ntxnrefs == 1) {
view_remove_saved_buffer(view);
}
Expand Down Expand Up @@ -365,6 +365,9 @@ static bool should_configure(struct sway_node *node,
if (!node_is_view(node)) {
return false;
}
if (!node->sway_container->view->surface) {
return false;
}
if (node->destroying) {
return false;
}
Expand Down
2 changes: 2 additions & 0 deletions sway/desktop/xdg_shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,7 @@ static void handle_map(struct wl_listener *listener, void *data) {
}

static void handle_destroy(struct wl_listener *listener, void *data) {
/*
struct sway_xdg_shell_view *xdg_shell_view =
wl_container_of(listener, xdg_shell_view, destroy);
struct sway_view *view = &xdg_shell_view->view;
Expand All @@ -539,6 +540,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
view->xdg_decoration->view = NULL;
}
view_begin_destroy(view);
*/
}

struct sway_view *view_from_wlr_xdg_surface(
Expand Down
9 changes: 6 additions & 3 deletions sway/input/seat.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ static void handle_seat_node_destroy(struct wl_listener *listener, void *data) {
while (next_focus == NULL && parent != NULL) {
struct sway_container *con =
seat_get_focus_inactive_view(seat, parent);
next_focus = con ? &con->node : NULL;
next_focus = (con && !con->node.destroying) ? &con->node : NULL;

if (next_focus == NULL && parent->type == N_WORKSPACE) {
next_focus = parent;
Expand Down Expand Up @@ -1092,6 +1092,9 @@ void seat_configure_xcursor(struct sway_seat *seat) {

bool seat_is_input_allowed(struct sway_seat *seat,
struct wlr_surface *surface) {
if (surface == NULL) {
return false;
}
if (server.session_lock.locked) {
if (server.session_lock.lock == NULL) {
return false;
Expand All @@ -1109,7 +1112,7 @@ bool seat_is_input_allowed(struct sway_seat *seat,
}

static void send_unfocus(struct sway_container *con, void *data) {
if (con->view) {
if (con->view && con->view->surface) {
view_set_activated(con->view, false);
}
}
Expand Down Expand Up @@ -1257,7 +1260,7 @@ static void seat_set_workspace_focus(struct sway_seat *seat, struct sway_node *n
}

// Close any popups on the old focus
if (last_focus && node_is_view(last_focus)) {
if (last_focus && node_is_view(last_focus) && last_focus->sway_container->view->surface) {
view_close_popups(last_focus->sway_container->view);
}

Expand Down
2 changes: 1 addition & 1 deletion sway/input/seatop_default.c
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ static void check_focus_follows_mouse(struct sway_seat *seat,

// This is where we handle the common case. We don't want to focus inactive
// tabs, hence the view_is_visible check.
if (node_is_view(hovered_node) &&
if (node_is_view(hovered_node) && hovered_node->sway_container->view->surface &&
view_is_visible(hovered_node->sway_container->view)) {
// e->previous_node is the node which the cursor was over previously.
// If focus_follows_mouse is yes and the cursor got over the view due
Expand Down
3 changes: 2 additions & 1 deletion sway/ipc-json.c
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,8 @@ static void ipc_json_describe_container(struct sway_container *c, json_object *o

json_object_object_add(object, "marks", marks);

if (c->view) {
// check if view exists and if it has not been unmapped
if (c->view && c->view->surface) {
ipc_json_describe_view(c, object);
}
}
Expand Down
1 change: 1 addition & 0 deletions sway/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ sway_sources = files(
'config/seat.c',
'config/input.c',

'commands/animation_duration.c',
'commands/assign.c',
'commands/bar.c',
'commands/bind.c',
Expand Down
Loading