diff --git a/ChangeLog b/ChangeLog index 719971b39..973003848 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +Fri May 26 16:48:29 2006 Søren Sandmann + + * src/effects.c (meta_effect_run_unminimize): Run an unminimize effect + + * src/window.c (meta_window_unminimize): Store a "was_minimized" + boolean in the window. + + * src/window.c (meta_window_show): If the window was minimized, + run an unminimize animation. + + * src/c-window.c (meta_comp_window_run_unminimize): Add an + unminimize animation, running the minimize one in reverse. + Fri May 26 14:55:07 2006 Søren Sandmann * src/c-window.c (meta_comp_window_run_focus): Rename from diff --git a/src/c-window.c b/src/c-window.c index 1bdfc3dfc..76c1ad9b1 100644 --- a/src/c-window.c +++ b/src/c-window.c @@ -36,6 +36,8 @@ #include "frame.h" #include "spring-model.h" +typedef struct UnminimizeInfo UnminimizeInfo; + struct _MetaCompWindow { MetaDisplay *display; @@ -60,9 +62,12 @@ struct _MetaCompWindow MetaCompWindowDestroy destroy; gpointer closure; + + UnminimizeInfo *unminimize_info; }; static void cancel_fade (MetaCompWindow *comp_window); +static void start_unminimize (MetaCompWindow *comp_window); static Window find_app_window (MetaCompWindow *comp_window) @@ -145,17 +150,23 @@ has_counter (MetaCompWindow *comp_window) { ws_sync_alarm_set (alarm, value + 2); +#if 0 g_print ("wait for %lld\n", value + 2); g_print ("increasing counter\n"); +#endif ws_sync_counter_change (counter, 1); +#if 0 g_print ("counter value %lld\n", ws_sync_counter_query_value (counter)); +#endif } else { +#if 0 g_print ("wait for %lld\n", value + 1); +#endif ws_sync_alarm_set (alarm, value + 1); } @@ -431,10 +442,10 @@ interpolate_rectangle (gdouble t, 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); + result->x = interpolate (t, from->x, to->x, 1); + result->y = interpolate (t, from->y, to->y, 1); + result->width = interpolate (t, from->width, to->width, 1); + result->height = interpolate (t, from->height, to->height, 1); } static void @@ -554,8 +565,11 @@ on_request_alarm (WsSyncAlarm *alarm, MetaCompWindow *comp_window) { /* This alarm means that the window is ready to be shown on screen */ - - meta_comp_window_fade_in (comp_window); + + if (comp_window->unminimize_info) + start_unminimize (comp_window); + else + meta_comp_window_fade_in (comp_window); g_object_unref (alarm); } @@ -801,8 +815,6 @@ typedef struct MetaEffect *effect; - gdouble aspect_ratio; - Phase phases[N_PHASES]; } MiniInfo; @@ -869,7 +881,10 @@ generate_phases (WsRectangle *start, /* Shrink to a little rectangle */ end->height = icon->height; end->width = icon->height * aspect_ratio; +#if 0 end->x = icon->x + center (end->width, icon->width); +#endif + end->x = cur.x + center (end->width, cur.width); end->y = cur.y + center (icon->height, cur.height); } else if (i == 1) @@ -885,7 +900,10 @@ generate_phases (WsRectangle *start, /* Zoom back */ end->height = icon->height; end->width = icon->height * aspect_ratio; +#if 0 end->x = icon->x + center (end->width, icon->width); +#endif + end->x = cur.x + center (end->width, cur.width); end->y = cur.y + center (icon->height, cur.height); } else if (i == 3) @@ -951,6 +969,19 @@ update_minimize (gpointer data) } } +static void +meta_rect_to_ws_rect (MetaRectangle *mrect, + WsRectangle *wrect) +{ + if (!mrect || !wrect) + return; + + wrect->x = mrect->x; + wrect->y = mrect->y; + wrect->width = mrect->width; + wrect->height = mrect->height; +} + void meta_comp_window_run_minimize (MetaCompWindow *window, MetaEffect *effect) @@ -964,21 +995,183 @@ meta_comp_window_run_minimize (MetaCompWindow *window, info->effect = effect; - start.x = effect->u.minimize.window_rect.x; - start.y = effect->u.minimize.window_rect.y; - start.width = effect->u.minimize.window_rect.width; - start.height = effect->u.minimize.window_rect.height; - - end.x = effect->u.minimize.icon_rect.x; - end.y = effect->u.minimize.icon_rect.y; - end.width = effect->u.minimize.icon_rect.width; - end.height = effect->u.minimize.icon_rect.height; + meta_rect_to_ws_rect (&(effect->u.minimize.window_rect), &start); + meta_rect_to_ws_rect (&(effect->u.minimize.icon_rect), &end); generate_phases (&start, &end, info->phases); g_idle_add (update_minimize, info); } +struct UnminimizeInfo +{ + GTimer *timer; + + MetaCompWindow *comp_window; + + Phase phases[N_PHASES]; + gboolean first_time; +}; + +#define WOBBLE_FACTOR_OUT 0.7 + +static void +generate_unminimize_phases (WsRectangle *icon, + WsRectangle *full, + Phase phases[N_PHASES]) +{ + const double phase_times[5] = { + 0.350, /* fade in */ + 0.100, /* move up from icon */ + 0.225, /* scale to full size */ + 0.100, /* scale down a little */ + 0.100, /* scale to full size */ + }; + + WsRectangle cur; + gdouble aspect_ratio; + gdouble time; + int i; + + aspect_ratio = (double)full->width / (double)full->height; + cur = *icon; + time = 0.0; + for (i = 0; i < N_PHASES; ++i) + { + Phase *phase = &(phases[i]); + WsRectangle *end = &(phase->end_rect); + + phase->start_time = time; + phase->start_rect = cur; + phase->start_alpha = 1.0; + phase->end_alpha = 1.0; + phase->end_time = time + phase_times[i]; + + if (i == 0) + { + /* Fade in */ + phase->end_alpha = 1.0; + phase->start_alpha = 0.0; + end->height = icon->height; + end->width = icon->height * aspect_ratio; + end->x = icon->x + center (end->width, icon->width); + end->y = icon->y; + } + else if (i == 1) + { + /* Move up from icon */ + end->width = cur.width; + end->height = cur.height; +#if 0 + end->x = cur.x; +#endif + end->x = full->x + center (end->width, full->width); + end->y = full->y + center (icon->height, full->height); + } + else if (i == 2) + { + /* Zoom to full size */ + *end = *full; + } + else if (i == 3) + { + /* Scale down a little */ + end->x = cur.x + center (cur.width * WOBBLE_FACTOR_OUT, cur.width); + end->y = cur.y + center (cur.height * WOBBLE_FACTOR_OUT, cur.height); + end->width = cur.width * WOBBLE_FACTOR_OUT; + end->height = cur.height * WOBBLE_FACTOR_OUT; + } + else if (i == 4) + { + /* Scale up to full size again */ + *end = *full; + } + + cur = phase->end_rect; + time += phase_times[i]; + } +} + +static gboolean +update_unminimize (gpointer data) +{ + UnminimizeInfo *info = data; + Phase *current_phase; + int i; + gdouble elapsed = g_timer_elapsed (info->timer, NULL); + + current_phase = NULL; + for (i = 0; i < N_PHASES; ++i) + { + Phase *p = &(info->phases[i]); + + if (p->start_time < elapsed && p->end_time >= elapsed) + { + current_phase = p; + break; + } + } + + if (current_phase) + { + if (info->first_time) + { + meta_comp_window_show (info->comp_window); + info->first_time = FALSE; + } + + set_geometry (info->comp_window, current_phase, elapsed); + return TRUE; + } + else + { + cm_drawable_node_set_alpha (info->comp_window->node, 1.0); + cm_drawable_node_unset_patch (info->comp_window->node); + comp_window_unref (info->comp_window); +#if 0 + g_print ("done\n"); +#endif + + return FALSE; + } + +} + +static void +start_unminimize (MetaCompWindow *comp_window) +{ + UnminimizeInfo *info = comp_window->unminimize_info; + + if (!info) + return; + + comp_window->unminimize_info = NULL; + + info->timer = g_timer_new (); + info->first_time = TRUE; + + g_idle_add (update_unminimize, info); +} + +void +meta_comp_window_run_unminimize (MetaCompWindow *comp_window, + MetaEffect *effect) +{ + WsRectangle start, end; + UnminimizeInfo *info = g_new0 (UnminimizeInfo, 1); + + meta_rect_to_ws_rect (&(effect->u.unminimize.icon_rect), &start); + meta_rect_to_ws_rect (&(effect->u.unminimize.window_rect), &end); + + generate_unminimize_phases (&start, &end, info->phases); + + info->comp_window = comp_window_ref (comp_window); + + comp_window->unminimize_info = info; + + meta_effect_end (effect); +} + /* bounce effect */ typedef struct @@ -1045,13 +1238,6 @@ meta_comp_window_run_focus (MetaCompWindow *comp_window, g_idle_add (update_focus, info); } -void -meta_comp_window_run_restore (MetaCompWindow *comp_window, - MetaEffect *effect) -{ - meta_effect_end (effect); -} - void meta_comp_window_freeze_stack (MetaCompWindow *comp_window) { diff --git a/src/c-window.h b/src/c-window.h index b25cdfcfc..571497b94 100644 --- a/src/c-window.h +++ b/src/c-window.h @@ -50,8 +50,8 @@ void meta_comp_window_shrink (MetaCompWindow *comp_window, MetaEffect *effect); void meta_comp_window_unshrink (MetaCompWindow *comp_window, MetaEffect *effect); -void meta_comp_window_focus (MetaCompWindow *comp_window, - MetaEffect *effect); +void meta_comp_window_run_focus (MetaCompWindow *comp_window, + MetaEffect *effect); void meta_comp_window_restack (MetaCompWindow *comp_window, MetaCompWindow *above); void meta_comp_window_freeze_stack (MetaCompWindow *comp_window); @@ -59,8 +59,8 @@ void meta_comp_window_thaw_stack (MetaCompWindow *comp_window); gboolean meta_comp_window_stack_frozen (MetaCompWindow *comp_window); void meta_comp_window_run_minimize (MetaCompWindow *window, MetaEffect *effect); -void meta_comp_window_run_restore (MetaCompWindow *comp_window, - MetaEffect *effect); +void meta_comp_window_run_unminimize (MetaCompWindow *comp_window, + MetaEffect *effect); #if 0 void meta_comp_window_set_explode (MetaCompWindow *comp_window, diff --git a/src/compositor.c b/src/compositor.c index e914c67b7..22d7cefa9 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -130,8 +130,9 @@ do_effect (MetaEffect *effect, meta_comp_window_run_minimize (window, effect); break; - case META_EFFECT_RESTORE: - meta_comp_window_run_restore (window, effect); + + case META_EFFECT_UNMINIMIZE: + meta_comp_window_run_unminimize (window, effect); break; case META_EFFECT_FOCUS: diff --git a/src/effects.c b/src/effects.c index 56b6f0bcd..f2ef7d146 100644 --- a/src/effects.c +++ b/src/effects.c @@ -162,21 +162,21 @@ meta_effect_run_minimize (MetaWindow *window, } void -meta_effect_run_restore (MetaWindow *window, - MetaRectangle *window_rect, - MetaRectangle *icon_rect, - MetaEffectFinished finished, - gpointer data) +meta_effect_run_unminimize (MetaWindow *window, + MetaRectangle *window_rect, + MetaRectangle *icon_rect, + MetaEffectFinished finished, + gpointer data) { MetaEffect *effect; g_return_if_fail (window != NULL); g_return_if_fail (icon_rect != NULL); - effect = create_effect (META_EFFECT_RESTORE, window, finished, data); + effect = create_effect (META_EFFECT_UNMINIMIZE, window, finished, data); - effect->u.restore.window_rect = *window_rect; - effect->u.restore.icon_rect = *icon_rect; + effect->u.minimize.window_rect = *window_rect; + effect->u.minimize.icon_rect = *icon_rect; run_handler (effect); } diff --git a/src/effects.h b/src/effects.h index b43e3aeec..23a9c2dac 100644 --- a/src/effects.h +++ b/src/effects.h @@ -41,7 +41,7 @@ typedef enum typedef enum { META_EFFECT_MINIMIZE, - META_EFFECT_RESTORE, + META_EFFECT_UNMINIMIZE, META_EFFECT_MENU_MAP, META_EFFECT_MENU_UNMAP, META_EFFECT_DIALOG_MAP, @@ -65,7 +65,7 @@ typedef struct { MetaRectangle window_rect; MetaRectangle icon_rect; -} MetaMinimizeEffect, MetaRestoreEffect; +} MetaMinimizeEffect, MetaUnminimizeEffect; typedef struct { @@ -85,7 +85,7 @@ struct MetaEffect union { MetaMinimizeEffect minimize; - MetaRestoreEffect restore; + MetaUnminimizeEffect unminimize; MetaCloseEffect close; MetaFocusEffect focus; } u; @@ -102,11 +102,11 @@ void meta_effect_run_minimize (MetaWindow *window, MetaRectangle *target, MetaEffectFinished finished, gpointer data); -void meta_effect_run_restore (MetaWindow *window, - MetaRectangle *window_rect, - MetaRectangle *icon_rect, - MetaEffectFinished finished, - gpointer data); +void meta_effect_run_unminimize (MetaWindow *window, + MetaRectangle *window_rect, + MetaRectangle *icon_rect, + MetaEffectFinished finished, + gpointer data); void meta_effect_run_close (MetaWindow *window, MetaEffectFinished finished, gpointer data); diff --git a/src/window.c b/src/window.c index 6d5f8edc2..71f1d3c1b 100644 --- a/src/window.c +++ b/src/window.c @@ -452,6 +452,7 @@ meta_window_new_with_attrs (MetaDisplay *display, window->shaded = FALSE; window->initially_iconic = FALSE; window->minimized = FALSE; + window->was_minimized = FALSE; window->tab_unminimized = FALSE; window->iconic = FALSE; window->mapped = attrs->map_state != IsUnmapped; @@ -1944,6 +1945,24 @@ meta_window_show (MetaWindow *window) XMapWindow (window->display->xdisplay, window->xwindow); meta_error_trap_pop (window->display, FALSE); did_show = TRUE; + + if (window->was_minimized) + { + MetaRectangle window_rect; + MetaRectangle icon_rect; + + window->was_minimized = FALSE; + + if (meta_window_get_icon_geometry (window, &icon_rect)) + { + meta_window_get_outer_rect (window, &window_rect); + + meta_effect_run_unminimize (window, + &window_rect, + &icon_rect, + NULL, NULL); + } + } } if (window->iconic) @@ -2124,6 +2143,7 @@ meta_window_unminimize (MetaWindow *window) if (window->minimized) { window->minimized = FALSE; + window->was_minimized = TRUE; meta_window_queue_calc_showing (window); meta_window_foreach_transient (window, diff --git a/src/window.h b/src/window.h index 6c6489782..e1d93d662 100644 --- a/src/window.h +++ b/src/window.h @@ -146,6 +146,7 @@ struct _MetaWindow /* Minimize is the state controlled by the minimize button */ guint minimized : 1; + guint was_minimized : 1; guint tab_unminimized : 1; /* Whether the window is mapped; actual server-side state