diff options
author | Havoc Pennington <hp@pobox.com> | 2001-08-06 05:12:22 +0000 |
---|---|---|
committer | rhp <rhp> | 2001-08-06 05:12:22 +0000 |
commit | d8561cb4c33d761907fb34299706729a013d06cf (patch) | |
tree | 13d48cbed96b3c8ed55bc06a45fd0a0ffcc336f7 | |
parent | 47ce823aa524d6d33b56749983f1a241232cc51a (diff) | |
download | metacity-d8561cb4c33d761907fb34299706729a013d06cf.tar.gz |
modify to be smoother (at least theoretically) by syncing to current time
2001-08-06 Havoc Pennington <hp@pobox.com>
* src/effects.c (meta_effects_draw_box_animation):
modify to be smoother (at least theoretically) by
syncing to current time and "dropping frames"
as appropriate. A precursor to flashier animations
that take more CPU to do.
* src/window.c (meta_window_shade): draw animation
for shading too
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | src/effects.c | 115 | ||||
-rw-r--r-- | src/effects.h | 10 | ||||
-rw-r--r-- | src/window.c | 6 |
4 files changed, 86 insertions, 51 deletions
@@ -1,5 +1,11 @@ 2001-08-06 Havoc Pennington <hp@pobox.com> + * src/effects.c (meta_effects_draw_box_animation): + modify to be smoother (at least theoretically) by + syncing to current time and "dropping frames" + as appropriate. A precursor to flashier animations + that take more CPU to do. + * src/window.c (meta_window_shade): draw animation for shading too diff --git a/src/effects.c b/src/effects.c index b5d7150b..bb9694fd 100644 --- a/src/effects.c +++ b/src/effects.c @@ -28,37 +28,56 @@ typedef struct GC gc; - int step; - int steps; - - double current_x, current_y; - double current_width, current_height; + double millisecs_duration; + GTimeVal start_time; + + gboolean first_time; + + MetaRectangle start_rect; + MetaRectangle end_rect; + + /* rect to erase */ + MetaRectangle last_rect; - double delta_x, delta_y; - double delta_width, delta_height; } BoxAnimationContext; static gboolean effects_draw_box_animation_timeout (BoxAnimationContext *context) { - if (context->step == 0) - { - /* It's our first time, grab the X server */ - meta_display_grab (context->screen->display); - } - else + double elapsed; + GTimeVal current_time; + MetaRectangle draw_rect; + double fraction; + + if (!context->first_time) { /* Restore the previously drawn background */ XDrawRectangle (context->screen->display->xdisplay, context->screen->xroot, context->gc, - context->current_x, context->current_y, - context->current_width, context->current_height); + context->last_rect.x, context->last_rect.y, + context->last_rect.width, context->last_rect.height); } - /* Return if we're done */ - if (context->step == context->steps) + context->first_time = FALSE; + + g_get_current_time (¤t_time); + + /* We use milliseconds for all times */ + elapsed = + ((((double)current_time.tv_sec - context->start_time.tv_sec) * G_USEC_PER_SEC + + (current_time.tv_usec - context->start_time.tv_usec))) / 1000.0; + + if (elapsed < 0) { + /* Probably the system clock was set backwards? */ + meta_warning ("System clock seemed to go backwards?\n"); + elapsed = G_MAXDOUBLE; /* definitely done. */ + } + + if (elapsed > context->millisecs_duration) + { + /* All done */ meta_display_ungrab (context->screen->display); XFreeGC (context->screen->display->xdisplay, context->gc); @@ -66,19 +85,31 @@ effects_draw_box_animation_timeout (BoxAnimationContext *context) return FALSE; } - context->current_x += context->delta_x; - context->current_y += context->delta_y; - context->current_width += context->delta_width; - context->current_height += context->delta_height; - + g_assert (context->millisecs_duration > 0.0); + fraction = elapsed / context->millisecs_duration; + + draw_rect = context->start_rect; + + /* Now add a delta proportional to elapsed time. */ + draw_rect.x += (context->end_rect.x - context->start_rect.x) * fraction; + draw_rect.y += (context->end_rect.y - context->start_rect.y) * fraction; + draw_rect.width += (context->end_rect.width - context->start_rect.width) * fraction; + draw_rect.height += (context->end_rect.height - context->start_rect.height) * fraction; + + /* don't confuse X with bogus rectangles */ + if (draw_rect.width < 1) + draw_rect.width = 1; + if (draw_rect.height < 1) + draw_rect.height = 1; + + context->last_rect = draw_rect; + /* Draw the rectangle */ XDrawRectangle (context->screen->display->xdisplay, context->screen->xroot, context->gc, - context->current_x, context->current_y, - context->current_width, context->current_height); - - context->step += 1; + draw_rect.x, draw_rect.y, + draw_rect.width, draw_rect.height); return TRUE; } @@ -87,12 +118,16 @@ void meta_effects_draw_box_animation (MetaScreen *screen, MetaRectangle *initial_rect, MetaRectangle *destination_rect, - int steps, - int delay) + double seconds_duration) { BoxAnimationContext *context; XGCValues gc_values; + g_return_if_fail (seconds_duration > 0.0); + + if (g_getenv ("METACITY_DEBUG_EFFECTS")) + seconds_duration *= 10; /* slow things down */ + /* Create the animation context */ context = g_new (BoxAnimationContext, 1); @@ -105,20 +140,20 @@ meta_effects_draw_box_animation (MetaScreen *screen, screen->xroot, GCSubwindowMode | GCFunction, &gc_values); - context->step = 0; - context->steps = steps; - context->delta_x = (destination_rect->x - initial_rect->x) / (double)steps; - context->delta_y = (destination_rect->y - initial_rect->y) / (double)steps; - context->delta_width = (destination_rect->width - initial_rect->width) / (double)steps; - context->delta_height = (destination_rect->height - initial_rect->height) / (double)steps; + + context->millisecs_duration = seconds_duration * 1000.0; + g_get_current_time (&context->start_time); + context->first_time = TRUE; + context->start_rect = *initial_rect; + context->end_rect = *destination_rect; - context->current_x = initial_rect->x; - context->current_y = initial_rect->y; - context->current_width = initial_rect->width; - context->current_height = initial_rect->height; + /* Grab the X server to avoid screen dirt */ + meta_display_grab (context->screen->display); - /* Add the timeout */ - g_timeout_add (delay, + /* Add the timeout - a short one, could even use an idle, + * but this is maybe more CPU-friendly. + */ + g_timeout_add (15, (GSourceFunc)effects_draw_box_animation_timeout, context); } diff --git a/src/effects.h b/src/effects.h index 867f6c06..9b057441 100644 --- a/src/effects.h +++ b/src/effects.h @@ -25,16 +25,12 @@ #include "util.h" #include "screen.h" -#define META_MINIMIZE_ANIMATION_STEPS 16 -#define META_MINIMIZE_ANIMATION_DELAY 20 - -#define META_SHADE_ANIMATION_STEPS 7 -#define META_SHADE_ANIMATION_DELAY 15 +#define META_MINIMIZE_ANIMATION_LENGTH 0.3 +#define META_SHADE_ANIMATION_LENGTH 0.15 void meta_effects_draw_box_animation (MetaScreen *screen, MetaRectangle *initial_rect, MetaRectangle *destination_rect, - int steps, - int delay); + double seconds_duration); #endif /* META_EFFECTS_H */ diff --git a/src/window.c b/src/window.c index 519efa39..bce536b9 100644 --- a/src/window.c +++ b/src/window.c @@ -793,8 +793,7 @@ meta_window_calc_showing (MetaWindow *window) meta_effects_draw_box_animation (window->screen, &window_rect, &icon_rect, - META_MINIMIZE_ANIMATION_STEPS, - META_MINIMIZE_ANIMATION_DELAY); + META_MINIMIZE_ANIMATION_LENGTH); } meta_window_hide (window); @@ -1078,8 +1077,7 @@ meta_window_shade (MetaWindow *window) meta_effects_draw_box_animation (window->screen, &starting_size, &titlebar_size, - META_SHADE_ANIMATION_STEPS, - META_SHADE_ANIMATION_DELAY); + META_SHADE_ANIMATION_LENGTH); } window->shaded = TRUE; |