mirror of
https://github.com/brl/mutter.git
synced 2024-11-24 17:10:40 -05:00
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:
parent
47ce823aa5
commit
d8561cb4c3
@ -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
|
||||||
|
|
||||||
|
111
src/effects.c
111
src/effects.c
@ -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 (¤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);
|
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);
|
||||||
}
|
}
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user