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
This commit is contained in:
Havoc Pennington 2001-08-06 05:12:22 +00:00 committed by rhp
parent 47ce823aa5
commit d8561cb4c3
4 changed files with 86 additions and 51 deletions

View File

@ -1,5 +1,11 @@
2001-08-06 Havoc Pennington <hp@pobox.com> 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 * src/window.c (meta_window_shade): draw animation
for shading too for shading too

View File

@ -28,37 +28,56 @@ typedef struct
GC gc; GC gc;
int step; double millisecs_duration;
int steps; GTimeVal start_time;
double current_x, current_y; gboolean first_time;
double current_width, current_height;
MetaRectangle start_rect;
MetaRectangle end_rect;
/* rect to erase */
MetaRectangle last_rect;
double delta_x, delta_y;
double delta_width, delta_height;
} BoxAnimationContext; } BoxAnimationContext;
static gboolean static gboolean
effects_draw_box_animation_timeout (BoxAnimationContext *context) effects_draw_box_animation_timeout (BoxAnimationContext *context)
{ {
if (context->step == 0) double elapsed;
{ GTimeVal current_time;
/* It's our first time, grab the X server */ MetaRectangle draw_rect;
meta_display_grab (context->screen->display); double fraction;
}
else if (!context->first_time)
{ {
/* Restore the previously drawn background */ /* Restore the previously drawn background */
XDrawRectangle (context->screen->display->xdisplay, XDrawRectangle (context->screen->display->xdisplay,
context->screen->xroot, context->screen->xroot,
context->gc, context->gc,
context->current_x, context->current_y, context->last_rect.x, context->last_rect.y,
context->current_width, context->current_height); context->last_rect.width, context->last_rect.height);
} }
/* Return if we're done */ context->first_time = FALSE;
if (context->step == context->steps)
g_get_current_time (&current_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); meta_display_ungrab (context->screen->display);
XFreeGC (context->screen->display->xdisplay, XFreeGC (context->screen->display->xdisplay,
context->gc); context->gc);
@ -66,19 +85,31 @@ effects_draw_box_animation_timeout (BoxAnimationContext *context)
return FALSE; return FALSE;
} }
context->current_x += context->delta_x; g_assert (context->millisecs_duration > 0.0);
context->current_y += context->delta_y; fraction = elapsed / context->millisecs_duration;
context->current_width += context->delta_width;
context->current_height += context->delta_height; 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 */ /* Draw the rectangle */
XDrawRectangle (context->screen->display->xdisplay, XDrawRectangle (context->screen->display->xdisplay,
context->screen->xroot, context->screen->xroot,
context->gc, context->gc,
context->current_x, context->current_y, draw_rect.x, draw_rect.y,
context->current_width, context->current_height); draw_rect.width, draw_rect.height);
context->step += 1;
return TRUE; return TRUE;
} }
@ -87,12 +118,16 @@ void
meta_effects_draw_box_animation (MetaScreen *screen, meta_effects_draw_box_animation (MetaScreen *screen,
MetaRectangle *initial_rect, MetaRectangle *initial_rect,
MetaRectangle *destination_rect, MetaRectangle *destination_rect,
int steps, double seconds_duration)
int delay)
{ {
BoxAnimationContext *context; BoxAnimationContext *context;
XGCValues gc_values; 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 */ /* Create the animation context */
context = g_new (BoxAnimationContext, 1); context = g_new (BoxAnimationContext, 1);
@ -105,20 +140,20 @@ meta_effects_draw_box_animation (MetaScreen *screen,
screen->xroot, screen->xroot,
GCSubwindowMode | GCFunction, GCSubwindowMode | GCFunction,
&gc_values); &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->current_x = initial_rect->x; context->millisecs_duration = seconds_duration * 1000.0;
context->current_y = initial_rect->y; g_get_current_time (&context->start_time);
context->current_width = initial_rect->width; context->first_time = TRUE;
context->current_height = initial_rect->height; context->start_rect = *initial_rect;
context->end_rect = *destination_rect;
/* Add the timeout */ /* Grab the X server to avoid screen dirt */
g_timeout_add (delay, meta_display_grab (context->screen->display);
/* 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, (GSourceFunc)effects_draw_box_animation_timeout,
context); context);
} }

View File

@ -25,16 +25,12 @@
#include "util.h" #include "util.h"
#include "screen.h" #include "screen.h"
#define META_MINIMIZE_ANIMATION_STEPS 16 #define META_MINIMIZE_ANIMATION_LENGTH 0.3
#define META_MINIMIZE_ANIMATION_DELAY 20 #define META_SHADE_ANIMATION_LENGTH 0.15
#define META_SHADE_ANIMATION_STEPS 7
#define META_SHADE_ANIMATION_DELAY 15
void meta_effects_draw_box_animation (MetaScreen *screen, void meta_effects_draw_box_animation (MetaScreen *screen,
MetaRectangle *initial_rect, MetaRectangle *initial_rect,
MetaRectangle *destination_rect, MetaRectangle *destination_rect,
int steps, double seconds_duration);
int delay);
#endif /* META_EFFECTS_H */ #endif /* META_EFFECTS_H */

View File

@ -793,8 +793,7 @@ meta_window_calc_showing (MetaWindow *window)
meta_effects_draw_box_animation (window->screen, meta_effects_draw_box_animation (window->screen,
&window_rect, &window_rect,
&icon_rect, &icon_rect,
META_MINIMIZE_ANIMATION_STEPS, META_MINIMIZE_ANIMATION_LENGTH);
META_MINIMIZE_ANIMATION_DELAY);
} }
meta_window_hide (window); meta_window_hide (window);
@ -1078,8 +1077,7 @@ meta_window_shade (MetaWindow *window)
meta_effects_draw_box_animation (window->screen, meta_effects_draw_box_animation (window->screen,
&starting_size, &starting_size,
&titlebar_size, &titlebar_size,
META_SHADE_ANIMATION_STEPS, META_SHADE_ANIMATION_LENGTH);
META_SHADE_ANIMATION_DELAY);
} }
window->shaded = TRUE; window->shaded = TRUE;