From 3ae4e25162fafa26f62f7cac2cf3fb80f0322d4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Sandmann?= Date: Wed, 24 May 2006 23:16:31 +0000 Subject: [PATCH] Add a fade-in animation when windows are mapped. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wed May 24 19:15:45 2006 Søren Sandmann * src/c-window.c (cancel_fade): Add a fade-in animation when windows are mapped. --- src/c-window.c | 176 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 145 insertions(+), 31 deletions(-) diff --git a/src/c-window.c b/src/c-window.c index d56c39820..df09ee55e 100644 --- a/src/c-window.c +++ b/src/c-window.c @@ -41,7 +41,7 @@ struct _MetaCompWindow MetaScreen *screen; WsDrawable *drawable; WsPixmap *pixmap; - CmNode *node; + CmDrawableNode *node; gboolean updates; WsSyncAlarm *alarm; @@ -55,8 +55,11 @@ struct _MetaCompWindow gboolean hide_after_animation; int stack_freeze_count; + int fade_in_idle_id; }; +static void cancel_fade (MetaCompWindow *comp_window); + static Window find_app_window (MetaCompWindow *comp_window) { @@ -195,7 +198,10 @@ meta_comp_window_hide (MetaCompWindow *comp_window) 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 * @@ -213,7 +219,7 @@ meta_comp_window_new (MetaScreen *screen, window->screen = screen; window->display = display; 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->counter_value = 1; window->ref_count = 1; @@ -397,18 +403,146 @@ frameless_managed (MetaCompWindow *comp_window) 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 on_request_alarm (WsSyncAlarm *alarm, WsAlarmNotifyEvent *event, MetaCompWindow *comp_window) { /* This alarm means that the window is ready to be shown on screen */ - -#if 0 - g_print ("alarm for %p\n", comp_window); -#endif - - meta_comp_window_show (comp_window); + + meta_comp_window_fade_in (comp_window); g_object_unref (alarm); } @@ -559,10 +693,9 @@ meta_comp_window_set_updates (MetaCompWindow *comp_window, CmNode * meta_comp_window_get_node (MetaCompWindow *comp_window) { - return comp_window->node; + return CM_NODE (comp_window->node); } - /* * Explosion effect */ @@ -696,26 +829,6 @@ meta_comp_window_shrink (MetaCompWindow *comp_window, #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 @@ -1007,3 +1120,4 @@ meta_comp_window_stack_frozen (MetaCompWindow *comp_window) { return comp_window->stack_freeze_count > 0; } +