Add a fade-in animation when windows are mapped.

Wed May 24 19:15:45 2006  Søren Sandmann  <sandmann@redhat.com>

        * src/c-window.c (cancel_fade): Add a fade-in animation when
        windows are mapped.
This commit is contained in:
Søren Sandmann 2006-05-24 23:16:31 +00:00 committed by Søren Sandmann Pedersen
parent 7535f0f58a
commit 3ae4e25162

View File

@ -41,7 +41,7 @@ struct _MetaCompWindow
MetaScreen *screen; MetaScreen *screen;
WsDrawable *drawable; WsDrawable *drawable;
WsPixmap *pixmap; WsPixmap *pixmap;
CmNode *node; CmDrawableNode *node;
gboolean updates; gboolean updates;
WsSyncAlarm *alarm; WsSyncAlarm *alarm;
@ -55,8 +55,11 @@ struct _MetaCompWindow
gboolean hide_after_animation; gboolean hide_after_animation;
int stack_freeze_count; int stack_freeze_count;
int fade_in_idle_id;
}; };
static void cancel_fade (MetaCompWindow *comp_window);
static Window static Window
find_app_window (MetaCompWindow *comp_window) find_app_window (MetaCompWindow *comp_window)
{ {
@ -195,7 +198,10 @@ meta_comp_window_hide (MetaCompWindow *comp_window)
return; return;
} }
cm_drawable_node_set_viewable (CM_DRAWABLE_NODE (comp_window->node), FALSE); cancel_fade (comp_window);
cm_drawable_node_set_viewable (CM_DRAWABLE_NODE (comp_window->node),
FALSE);
} }
MetaCompWindow * MetaCompWindow *
@ -213,7 +219,7 @@ meta_comp_window_new (MetaScreen *screen,
window->screen = screen; window->screen = screen;
window->display = display; window->display = display;
window->drawable = g_object_ref (drawable); window->drawable = g_object_ref (drawable);
window->node = CM_NODE (cm_drawable_node_new (drawable, &geometry)); window->node = cm_drawable_node_new (drawable, &geometry);
window->updates = TRUE; window->updates = TRUE;
window->counter_value = 1; window->counter_value = 1;
window->ref_count = 1; window->ref_count = 1;
@ -397,18 +403,146 @@ frameless_managed (MetaCompWindow *comp_window)
return mw && !mw->frame; return mw && !mw->frame;
} }
static gdouble
interpolate (gdouble t, gdouble begin, gdouble end, double power)
{
return (begin + (end - begin) * pow (t, power));
}
static void
interpolate_rectangle (gdouble t,
WsRectangle * from,
WsRectangle * to,
WsRectangle * result)
{
if (!result)
return;
result->x = interpolate (t, from->x, to->x, 2);
result->y = interpolate (t, from->y, to->y, 0.5);
result->width = interpolate (t, from->width, to->width, 0.7);
result->height = interpolate (t, from->height, to->height, 0.7);
}
static void
comp_window_set_target_rect (MetaCompWindow *window,
WsRectangle *rect)
{
cm_drawable_node_set_scale_rect (window->node, rect);
}
static void
comp_window_get_real_size (MetaCompWindow *window,
WsRectangle *size)
{
if (!size)
return;
cm_drawable_node_get_clipbox (window->node, size);
}
#define FADE_TIME 0.225
typedef struct
{
MetaEffect *effect;
MetaCompWindow *window;
GTimer * timer;
WsRectangle from;
WsRectangle to;
gboolean first_time;
gdouble start_alpha;
gdouble end_alpha;
} FadeInfo;
static gboolean
update_fade (gpointer data)
{
FadeInfo *info = data;
gdouble elapsed = g_timer_elapsed (info->timer, NULL);
gdouble t = elapsed / FADE_TIME;
if (elapsed >= FADE_TIME)
{
comp_window_set_target_rect (info->window, &info->to);
cm_drawable_node_set_alpha (info->window->node, 1.0);
cm_drawable_node_unset_patch (info->window->node);
comp_window_unref (info->window);
return FALSE;
}
else
{
gdouble alpha = interpolate (t, info->start_alpha, info->end_alpha, 1.0);
WsRectangle cur;
if (info->first_time)
{
meta_comp_window_show (info->window);
info->first_time = FALSE;
}
interpolate_rectangle (t, &info->from, &info->to, &cur);
comp_window_set_target_rect (info->window, &cur);
cm_drawable_node_set_alpha (info->window->node, alpha);
return TRUE;
}
}
static void
cancel_fade (MetaCompWindow *comp_window)
{
if (comp_window->fade_in_idle_id)
{
g_source_remove (comp_window->fade_in_idle_id);
comp_window->fade_in_idle_id = 0;
}
}
static void
meta_comp_window_fade_in (MetaCompWindow *comp_window)
{
FadeInfo *info = g_new0 (FadeInfo, 1);
WsWindow *window = find_client_window (comp_window);
if (comp_window->fade_in_idle_id)
return;
info->window = comp_window_ref (comp_window);
info->timer = g_timer_new ();
comp_window_get_real_size (info->window, &info->to);
info->from = info->to;
info->start_alpha = 0.1;
info->first_time = TRUE;
if (has_type (window, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU") ||
has_type (window, "_NET_WM_WINDOW_TYPE_POPUP_MENU"))
{
info->end_alpha = 0.9;
info->from.width *= 0.6;
info->from.height *= 0.4;
}
else if (has_type (window, "_NET_WM_WINDOW_TYPE_DIALOG"))
{
info->end_alpha = 0.7;
}
else
{
info->end_alpha = 1.0;
}
comp_window->fade_in_idle_id = g_idle_add (update_fade, info);
}
static void static void
on_request_alarm (WsSyncAlarm *alarm, on_request_alarm (WsSyncAlarm *alarm,
WsAlarmNotifyEvent *event, WsAlarmNotifyEvent *event,
MetaCompWindow *comp_window) MetaCompWindow *comp_window)
{ {
/* This alarm means that the window is ready to be shown on screen */ /* This alarm means that the window is ready to be shown on screen */
#if 0 meta_comp_window_fade_in (comp_window);
g_print ("alarm for %p\n", comp_window);
#endif
meta_comp_window_show (comp_window);
g_object_unref (alarm); g_object_unref (alarm);
} }
@ -559,10 +693,9 @@ meta_comp_window_set_updates (MetaCompWindow *comp_window,
CmNode * CmNode *
meta_comp_window_get_node (MetaCompWindow *comp_window) meta_comp_window_get_node (MetaCompWindow *comp_window)
{ {
return comp_window->node; return CM_NODE (comp_window->node);
} }
/* /*
* Explosion effect * Explosion effect
*/ */
@ -696,26 +829,6 @@ meta_comp_window_shrink (MetaCompWindow *comp_window,
#ifdef HAVE_COMPOSITE_EXTENSIONS #ifdef HAVE_COMPOSITE_EXTENSIONS
static gdouble
interpolate (gdouble t, gdouble begin, gdouble end, double power)
{
return (begin + (end - begin) * pow (t, power));
}
static void
interpolate_rectangle (gdouble t,
WsRectangle * from,
WsRectangle * to,
WsRectangle * result)
{
if (!result)
return;
result->x = interpolate (t, from->x, to->x, 2);
result->y = interpolate (t, from->y, to->y, 0.5);
result->width = interpolate (t, from->width, to->width, 0.7);
result->height = interpolate (t, from->height, to->height, 0.7);
}
#endif #endif
@ -1007,3 +1120,4 @@ meta_comp_window_stack_frozen (MetaCompWindow *comp_window)
{ {
return comp_window->stack_freeze_count > 0; return comp_window->stack_freeze_count > 0;
} }