Work on opaque animations more, still suck too much to turn on. Not sure

2002-03-05  Havoc Pennington  <hp@pobox.com>

        Work on opaque animations more, still suck too much
	to turn on. Not sure how to make them good.

	* src/effects.c (meta_effects_draw_box_animation):
	add a slide-up mode for shading

	* src/ui.c (meta_image_window_set): change image window to work by
	setting back pixmap on the GtkWindow, instead of using GtkImage.
This commit is contained in:
Havoc Pennington 2002-03-05 05:05:00 +00:00 committed by Havoc Pennington
parent 5429690467
commit d443d92446
6 changed files with 129 additions and 61 deletions

View File

@ -1,3 +1,14 @@
2002-03-05 Havoc Pennington <hp@pobox.com>
Work on opaque animations more, still suck too much
to turn on. Not sure how to make them good.
* src/effects.c (meta_effects_draw_box_animation):
add a slide-up mode for shading
* src/ui.c (meta_image_window_set): change image window to work by
setting back pixmap on the GtkWindow, instead of using GtkImage.
2002-03-04 Havoc Pennington <hp@pobox.com> 2002-03-04 Havoc Pennington <hp@pobox.com>
* src/main.c (main): try ignoring SIGXFSZ, though I'm not * src/main.c (main): try ignoring SIGXFSZ, though I'm not

View File

@ -49,6 +49,8 @@ typedef struct
/* For opaque */ /* For opaque */
MetaImageWindow *image_window; MetaImageWindow *image_window;
GdkPixbuf *orig_pixbuf; GdkPixbuf *orig_pixbuf;
MetaBoxAnimType anim_type;
} BoxAnimationContext; } BoxAnimationContext;
@ -119,7 +121,7 @@ effects_draw_box_animation_timeout (BoxAnimationContext *context)
draw_rect.y += (context->end_rect.y - context->start_rect.y) * 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.width += (context->end_rect.width - context->start_rect.width) * fraction;
draw_rect.height += (context->end_rect.height - context->start_rect.height) * fraction; draw_rect.height += (context->end_rect.height - context->start_rect.height) * fraction;
/* don't confuse X or gdk-pixbuf with bogus rectangles */ /* don't confuse X or gdk-pixbuf with bogus rectangles */
if (draw_rect.width < 1) if (draw_rect.width < 1)
draw_rect.width = 1; draw_rect.width = 1;
@ -132,15 +134,45 @@ effects_draw_box_animation_timeout (BoxAnimationContext *context)
{ {
GdkPixbuf *scaled; GdkPixbuf *scaled;
scaled = gdk_pixbuf_scale_simple (context->orig_pixbuf, scaled = NULL;
draw_rect.width, switch (context->anim_type)
draw_rect.height, {
GDK_INTERP_BILINEAR); case META_BOX_ANIM_SCALE:
meta_image_window_set_image (context->image_window, scaled = gdk_pixbuf_scale_simple (context->orig_pixbuf,
scaled); draw_rect.width,
meta_image_window_set_position (context->image_window, draw_rect.height,
draw_rect.x, draw_rect.y); GDK_INTERP_BILINEAR);
g_object_unref (G_OBJECT (scaled)); break;
case META_BOX_ANIM_SLIDE_UP:
{
int x, y;
x = context->start_rect.width - draw_rect.width;
y = context->start_rect.height - draw_rect.height;
/* paranoia */
if (x < 0)
x = 0;
if (y < 0)
y = 0;
scaled = gdk_pixbuf_new_subpixbuf (context->orig_pixbuf,
x, y,
draw_rect.width,
draw_rect.height);
}
break;
}
/* handle out-of-memory */
if (scaled != NULL)
{
meta_image_window_set (context->image_window,
scaled,
draw_rect.x, draw_rect.y);
g_object_unref (G_OBJECT (scaled));
}
} }
else else
{ {
@ -159,20 +191,21 @@ effects_draw_box_animation_timeout (BoxAnimationContext *context)
} }
/* I really don't want this to be a configuration option, /* I really don't want this to be a configuration option, but I think
* but I think the wireframe is sucky from a UI standpoint * the wireframe is sucky from a UI standpoint (more confusing than
* (more confusing than opaque), but the opaque is maybe * opaque), but the opaque is definitely still too slow on some
* too slow on some systems; so perhaps we could autodetect * systems, and also doesn't look quite right due to the mapping
* system beefiness or someting, or have some global * and unmapping of windows that's going on.
* "my system is slow" config option.
*/ */
static gboolean use_opaque_animations = FALSE; static gboolean use_opaque_animations = FALSE;
void 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,
double seconds_duration) double seconds_duration,
MetaBoxAnimType anim_type)
{ {
BoxAnimationContext *context; BoxAnimationContext *context;
@ -190,13 +223,14 @@ meta_effects_draw_box_animation (MetaScreen *screen,
context->first_time = TRUE; context->first_time = TRUE;
context->start_rect = *initial_rect; context->start_rect = *initial_rect;
context->end_rect = *destination_rect; context->end_rect = *destination_rect;
context->anim_type = anim_type;
context->use_opaque = use_opaque_animations; context->use_opaque = use_opaque_animations;
if (context->use_opaque) if (context->use_opaque)
{ {
GdkPixbuf *pix; GdkPixbuf *pix;
pix = meta_gdk_pixbuf_get_from_window (NULL, pix = meta_gdk_pixbuf_get_from_window (NULL,
screen->xroot, screen->xroot,
initial_rect->x, initial_rect->x,
@ -212,11 +246,13 @@ meta_effects_draw_box_animation (MetaScreen *screen,
} }
else else
{ {
context->image_window = meta_image_window_new (); context->image_window = meta_image_window_new (initial_rect->width,
initial_rect->height);
context->orig_pixbuf = pix; context->orig_pixbuf = pix;
meta_image_window_set_position (context->image_window, meta_image_window_set (context->image_window,
initial_rect->x, context->orig_pixbuf,
initial_rect->y); initial_rect->x,
initial_rect->y);
meta_image_window_set_showing (context->image_window, TRUE); meta_image_window_set_showing (context->image_window, TRUE);
} }
} }

View File

@ -28,9 +28,17 @@
#define META_MINIMIZE_ANIMATION_LENGTH 0.5 #define META_MINIMIZE_ANIMATION_LENGTH 0.5
#define META_SHADE_ANIMATION_LENGTH 0.2 #define META_SHADE_ANIMATION_LENGTH 0.2
void meta_effects_draw_box_animation (MetaScreen *screen, typedef enum
MetaRectangle *initial_rect, {
MetaRectangle *destination_rect, META_BOX_ANIM_SCALE,
double seconds_duration); META_BOX_ANIM_SLIDE_UP
} MetaBoxAnimType;
void meta_effects_draw_box_animation (MetaScreen *screen,
MetaRectangle *initial_rect,
MetaRectangle *destination_rect,
double seconds_duration,
MetaBoxAnimType anim_type);
#endif /* META_EFFECTS_H */ #endif /* META_EFFECTS_H */

View File

@ -273,23 +273,25 @@ meta_ui_window_menu_free (MetaWindowMenu *menu)
struct _MetaImageWindow struct _MetaImageWindow
{ {
GtkWidget *window; GtkWidget *window;
GtkWidget *image; GdkPixmap *pixmap;
}; };
MetaImageWindow* MetaImageWindow*
meta_image_window_new (void) meta_image_window_new (int max_width,
int max_height)
{ {
MetaImageWindow *iw; MetaImageWindow *iw;
iw = g_new (MetaImageWindow, 1); iw = g_new (MetaImageWindow, 1);
iw->window = gtk_window_new (GTK_WINDOW_POPUP); iw->window = gtk_window_new (GTK_WINDOW_POPUP);
iw->image = g_object_new (GTK_TYPE_IMAGE, NULL); gtk_widget_realize (iw->window);
iw->pixmap = gdk_pixmap_new (iw->window->window,
gtk_container_add (GTK_CONTAINER (iw->window), iw->image); max_width, max_height,
-1);
/* Ensure we auto-shrink to fit image */
gtk_window_set_resizable (GTK_WINDOW (iw->window), gtk_widget_set_size_request (iw->window, 1, 1);
FALSE); gtk_widget_set_double_buffered (iw->window, FALSE);
gtk_widget_set_app_paintable (iw->window, TRUE);
return iw; return iw;
} }
@ -298,6 +300,7 @@ void
meta_image_window_free (MetaImageWindow *iw) meta_image_window_free (MetaImageWindow *iw)
{ {
gtk_widget_destroy (iw->window); gtk_widget_destroy (iw->window);
g_object_unref (G_OBJECT (iw->pixmap));
g_free (iw); g_free (iw);
} }
@ -315,28 +318,36 @@ meta_image_window_set_showing (MetaImageWindow *iw,
} }
void void
meta_image_window_set_image (MetaImageWindow *iw, meta_image_window_set (MetaImageWindow *iw,
GdkPixbuf *pixbuf) GdkPixbuf *pixbuf,
int x,
int y)
{ {
gtk_image_set_from_pixbuf (GTK_IMAGE (iw->image), pixbuf); /* We use a back pixmap to avoid having to handle exposes, because
} * it's really too slow for large clients being minimized, etc.
* and this way flicker is genuinely zero.
void
meta_image_window_set_position (MetaImageWindow *iw,
int x,
int y)
{
/* We want to do move/resize at the same time to avoid ugliness.
* Lame hack.
*/ */
GtkRequisition req;
g_return_if_fail (GTK_WIDGET_REALIZED (iw->window)); gdk_pixbuf_render_to_drawable (pixbuf,
iw->pixmap,
iw->window->style->black_gc,
0, 0,
0, 0,
gdk_pixbuf_get_width (pixbuf),
gdk_pixbuf_get_height (pixbuf),
GDK_RGB_DITHER_NORMAL,
0, 0);
gtk_widget_size_request (iw->window, &req); gdk_window_set_back_pixmap (iw->window->window,
iw->pixmap,
FALSE);
gdk_window_move_resize (GTK_WIDGET (iw->window)->window, gdk_window_move_resize (iw->window->window,
x, y, req.width, req.height); x, y,
gdk_pixbuf_get_width (pixbuf),
gdk_pixbuf_get_height (pixbuf));
gdk_window_clear (iw->window->window);
} }
static GdkColormap* static GdkColormap*

View File

@ -96,13 +96,13 @@ void meta_ui_window_menu_popup (MetaWindowMenu *menu,
void meta_ui_window_menu_free (MetaWindowMenu *menu); void meta_ui_window_menu_free (MetaWindowMenu *menu);
MetaImageWindow* meta_image_window_new (void); MetaImageWindow* meta_image_window_new (int max_width,
int max_height);
void meta_image_window_free (MetaImageWindow *iw); void meta_image_window_free (MetaImageWindow *iw);
void meta_image_window_set_showing (MetaImageWindow *iw, void meta_image_window_set_showing (MetaImageWindow *iw,
gboolean showing); gboolean showing);
void meta_image_window_set_image (MetaImageWindow *iw, void meta_image_window_set (MetaImageWindow *iw,
GdkPixbuf *pixbuf); GdkPixbuf *pixbuf,
void meta_image_window_set_position (MetaImageWindow *iw,
int x, int x,
int y); int y);

View File

@ -952,7 +952,8 @@ 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_LENGTH); META_MINIMIZE_ANIMATION_LENGTH,
META_BOX_ANIM_SCALE);
} }
meta_window_hide (window); meta_window_hide (window);
@ -1429,7 +1430,8 @@ 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_LENGTH); META_SHADE_ANIMATION_LENGTH,
META_BOX_ANIM_SLIDE_UP);
} }
window->shaded = TRUE; window->shaded = TRUE;