compositor: Move fade animation out of core Weston into shell

Previously, it was impossible to override the fade in/out behavior of
Weston using a different shell, since this was implemented in core
Weston. This also led to complicated interaction between the shell and
the core when displaying lock surfaces and screensavers.

This patch starts to solve this issue by moving the fade animation out
of the core. On compositor.c, besides deleting the fade code, the idle
handler had to be changed to emit the lock signal, since it was called
from the fade_frame() function before. This causes a slight change of
behavior, since before the fade would happen with the compositor being
active, while now it is already in the idle state. That leads to the
dpms state being set when cancelling the fade with mouse movement, and
in turn, to a slight freeze with drm compositor. This problem will be
fixed in a follow up patch.

On the shell side, the fade was re-implemented in a slightly different
manner. Instead of using a custom frame function, the fade animation
from animation.c is used. The interface for starting the fade was also
changed to take the value of an enum instead of a float alpha value,
in order to improve readability.
Ander Conselvan de Oliveira 12 years ago committed by Kristian Høgsberg
parent 29f30fab27
commit 19d10ef925
  1. 77
      src/compositor.c
  2. 5
      src/compositor.h
  3. 112
      src/shell.c

@ -1052,40 +1052,6 @@ weston_output_damage(struct weston_output *output)
weston_output_schedule_repaint(output);
}
static void
fade_frame(struct weston_animation *animation,
struct weston_output *output, uint32_t msecs)
{
struct weston_compositor *compositor =
container_of(animation,
struct weston_compositor, fade.animation);
struct weston_surface *surface;
if (animation->frame_counter <= 1)
compositor->fade.spring.timestamp = msecs;
surface = compositor->fade.surface;
weston_spring_update(&compositor->fade.spring, msecs);
weston_surface_set_color(surface, 0.0, 0.0, 0.0,
compositor->fade.spring.current);
weston_surface_damage(surface);
if (weston_spring_done(&compositor->fade.spring)) {
compositor->fade.spring.current =
compositor->fade.spring.target;
wl_list_remove(&animation->link);
wl_list_init(&animation->link);
if (compositor->fade.spring.current < 0.001) {
destroy_surface(&surface->surface.resource);
compositor->fade.surface = NULL;
} else if (compositor->fade.spring.current > 0.999) {
compositor->state = WESTON_COMPOSITOR_SLEEPING;
wl_signal_emit(&compositor->lock_signal, compositor);
}
}
}
static void
surface_accumulate_damage(struct weston_surface *surface,
pixman_region32_t *opaque)
@ -1288,41 +1254,6 @@ weston_compositor_schedule_repaint(struct weston_compositor *compositor)
weston_output_schedule_repaint(output);
}
WL_EXPORT void
weston_compositor_fade(struct weston_compositor *compositor, float tint)
{
struct weston_output *output;
struct weston_surface *surface;
output = container_of(compositor->output_list.next,
struct weston_output, link);
compositor->fade.spring.target = tint;
if (weston_spring_done(&compositor->fade.spring))
return;
if (compositor->fade.surface == NULL) {
surface = weston_surface_create(compositor);
if (!surface)
return;
weston_surface_configure(surface, 0, 0, 8192, 8192);
weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1.0 - tint);
wl_list_insert(&compositor->fade_layer.surface_list,
&surface->layer_link);
weston_surface_update_transform(surface);
compositor->fade.surface = surface;
pixman_region32_init(&surface->input);
}
weston_surface_damage(compositor->fade.surface);
if (wl_list_empty(&compositor->fade.animation.link)) {
compositor->fade.animation.frame_counter = 0;
wl_list_insert(output->animation_list.prev,
&compositor->fade.animation.link);
}
}
static void
surface_destroy(struct wl_client *client, struct wl_resource *resource)
{
@ -1646,7 +1577,6 @@ WL_EXPORT void
weston_compositor_wake(struct weston_compositor *compositor)
{
compositor->state = WESTON_COMPOSITOR_ACTIVE;
weston_compositor_fade(compositor, 0.0);
wl_event_source_timer_update(compositor->idle_source,
compositor->idle_time * 1000);
@ -1695,7 +1625,8 @@ idle_handler(void *data)
if (compositor->idle_inhibit)
return 1;
weston_compositor_fade(compositor, 1.0);
compositor->state = WESTON_COMPOSITOR_IDLE;
wl_signal_emit(&compositor->lock_signal, compositor);
return 1;
}
@ -3094,7 +3025,6 @@ weston_compositor_init(struct weston_compositor *ec,
wl_list_init(&ec->button_binding_list);
wl_list_init(&ec->axis_binding_list);
wl_list_init(&ec->debug_binding_list);
wl_list_init(&ec->fade.animation.link);
weston_plane_init(&ec->primary_plane, 0, 0);
@ -3117,9 +3047,6 @@ weston_compositor_init(struct weston_compositor *ec,
ec->input_loop = wl_event_loop_create();
weston_spring_init(&ec->fade.spring, 30.0, 1.0, 1.0);
ec->fade.animation.frame = fade_frame;
weston_layer_init(&ec->fade_layer, &ec->layer_list);
weston_layer_init(&ec->cursor_layer, &ec->fade_layer.link);

@ -318,11 +318,6 @@ struct weston_compositor {
struct wl_list button_binding_list;
struct wl_list axis_binding_list;
struct wl_list debug_binding_list;
struct {
struct weston_spring spring;
struct weston_animation animation;
struct weston_surface *surface;
} fade;
uint32_t state;
struct wl_event_source *idle_source;

@ -49,6 +49,11 @@ enum animation_type {
ANIMATION_FADE
};
enum fade_type {
FADE_IN,
FADE_OUT
};
struct focus_state {
struct weston_seat *seat;
struct workspace *ws;
@ -137,6 +142,12 @@ struct desktop_shell {
struct wl_list surfaces;
} input_panel;
struct {
struct weston_surface *surface;
struct weston_surface_animation *animation;
enum fade_type type;
} fade;
uint32_t binding_modifier;
enum animation_type win_animation_type;
};
@ -2754,10 +2765,8 @@ click_to_activate_binding(struct wl_seat *seat, uint32_t time, uint32_t button,
}
static void
lock(struct wl_listener *listener, void *data)
lock(struct desktop_shell *shell)
{
struct desktop_shell *shell =
container_of(listener, struct desktop_shell, lock_listener);
struct weston_output *output;
struct workspace *ws = get_current_workspace(shell);
@ -2791,11 +2800,8 @@ lock(struct wl_listener *listener, void *data)
}
static void
unlock(struct wl_listener *listener, void *data)
unlock(struct desktop_shell *shell)
{
struct desktop_shell *shell =
container_of(listener, struct desktop_shell, unlock_listener);
if (!shell->locked || shell->lock_surface) {
weston_compositor_wake(shell->compositor);
return;
@ -2814,6 +2820,91 @@ unlock(struct wl_listener *listener, void *data)
shell->prepare_event_sent = true;
}
static void
shell_fade_done(struct weston_surface_animation *animation, void *data)
{
struct desktop_shell *shell = data;
shell->fade.animation = NULL;
switch (shell->fade.type) {
case FADE_IN:
weston_surface_destroy(shell->fade.surface);
shell->fade.surface = NULL;
break;
case FADE_OUT:
shell->compositor->state = WESTON_COMPOSITOR_SLEEPING;
lock(shell);
break;
}
}
static void
shell_fade(struct desktop_shell *shell, enum fade_type type)
{
struct weston_compositor *compositor = shell->compositor;
struct weston_surface *surface;
float tint;
switch (type) {
case FADE_IN:
tint = 0.0;
break;
case FADE_OUT:
tint = 1.0;
break;
default:
weston_log("shell: invalid fade type\n");
return;
}
shell->fade.type = type;
if (shell->fade.surface == NULL) {
surface = weston_surface_create(compositor);
if (!surface)
return;
weston_surface_configure(surface, 0, 0, 8192, 8192);
weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1.0);
surface->alpha = 1.0 - tint;
wl_list_insert(&compositor->fade_layer.surface_list,
&surface->layer_link);
weston_surface_update_transform(surface);
shell->fade.surface = surface;
pixman_region32_init(&surface->input);
}
if (shell->fade.animation)
weston_fade_update(shell->fade.animation,
shell->fade.surface->alpha, tint, 30.0);
else
shell->fade.animation =
weston_fade_run(shell->fade.surface,
1.0 - tint, tint, 30.0,
shell_fade_done, shell);
}
static void
lock_handler(struct wl_listener *listener, void *data)
{
struct desktop_shell *shell =
container_of(listener, struct desktop_shell, lock_listener);
shell_fade(shell, FADE_OUT);
/* lock() is called from shell_fade_done() */
}
static void
unlock_handler(struct wl_listener *listener, void *data)
{
struct desktop_shell *shell =
container_of(listener, struct desktop_shell, unlock_listener);
shell_fade(shell, FADE_IN);
unlock(shell);
}
static void
show_input_panels(struct wl_listener *listener, void *data)
{
@ -3216,6 +3307,7 @@ screensaver_configure(struct weston_surface *surface, int32_t sx, int32_t sy)
&surface->layer_link);
weston_surface_update_transform(surface);
shell->compositor->idle_time = shell->screensaver.duration;
shell_fade(shell, FADE_IN);
weston_compositor_wake(shell->compositor);
shell->compositor->state = WESTON_COMPOSITOR_IDLE;
}
@ -3972,9 +4064,9 @@ module_init(struct weston_compositor *ec,
shell->destroy_listener.notify = shell_destroy;
wl_signal_add(&ec->destroy_signal, &shell->destroy_listener);
shell->lock_listener.notify = lock;
shell->lock_listener.notify = lock_handler;
wl_signal_add(&ec->lock_signal, &shell->lock_listener);
shell->unlock_listener.notify = unlock;
shell->unlock_listener.notify = unlock_handler;
wl_signal_add(&ec->unlock_signal, &shell->unlock_listener);
shell->show_input_panel_listener.notify = show_input_panels;
wl_signal_add(&ec->show_input_panel_signal, &shell->show_input_panel_listener);
@ -4048,5 +4140,7 @@ module_init(struct weston_compositor *ec,
shell_add_bindings(ec, shell);
shell_fade(shell, FADE_IN);
return 0;
}

Loading…
Cancel
Save