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>
* src/main.c (main): try ignoring SIGXFSZ, though I'm not

View File

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

View File

@ -28,9 +28,17 @@
#define META_MINIMIZE_ANIMATION_LENGTH 0.5
#define META_SHADE_ANIMATION_LENGTH 0.2
void meta_effects_draw_box_animation (MetaScreen *screen,
MetaRectangle *initial_rect,
MetaRectangle *destination_rect,
double seconds_duration);
typedef enum
{
META_BOX_ANIM_SCALE,
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 */

View File

@ -273,23 +273,25 @@ meta_ui_window_menu_free (MetaWindowMenu *menu)
struct _MetaImageWindow
{
GtkWidget *window;
GtkWidget *image;
GdkPixmap *pixmap;
};
MetaImageWindow*
meta_image_window_new (void)
meta_image_window_new (int max_width,
int max_height)
{
MetaImageWindow *iw;
iw = g_new (MetaImageWindow, 1);
iw->window = gtk_window_new (GTK_WINDOW_POPUP);
iw->image = g_object_new (GTK_TYPE_IMAGE, NULL);
gtk_container_add (GTK_CONTAINER (iw->window), iw->image);
/* Ensure we auto-shrink to fit image */
gtk_window_set_resizable (GTK_WINDOW (iw->window),
FALSE);
gtk_widget_realize (iw->window);
iw->pixmap = gdk_pixmap_new (iw->window->window,
max_width, max_height,
-1);
gtk_widget_set_size_request (iw->window, 1, 1);
gtk_widget_set_double_buffered (iw->window, FALSE);
gtk_widget_set_app_paintable (iw->window, TRUE);
return iw;
}
@ -298,6 +300,7 @@ void
meta_image_window_free (MetaImageWindow *iw)
{
gtk_widget_destroy (iw->window);
g_object_unref (G_OBJECT (iw->pixmap));
g_free (iw);
}
@ -315,28 +318,36 @@ meta_image_window_set_showing (MetaImageWindow *iw,
}
void
meta_image_window_set_image (MetaImageWindow *iw,
GdkPixbuf *pixbuf)
meta_image_window_set (MetaImageWindow *iw,
GdkPixbuf *pixbuf,
int x,
int y)
{
gtk_image_set_from_pixbuf (GTK_IMAGE (iw->image), pixbuf);
}
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.
/* 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.
*/
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,
x, y, req.width, req.height);
gdk_window_move_resize (iw->window->window,
x, y,
gdk_pixbuf_get_width (pixbuf),
gdk_pixbuf_get_height (pixbuf));
gdk_window_clear (iw->window->window);
}
static GdkColormap*

View File

@ -96,13 +96,13 @@ void meta_ui_window_menu_popup (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_set_showing (MetaImageWindow *iw,
gboolean showing);
void meta_image_window_set_image (MetaImageWindow *iw,
GdkPixbuf *pixbuf);
void meta_image_window_set_position (MetaImageWindow *iw,
void meta_image_window_set (MetaImageWindow *iw,
GdkPixbuf *pixbuf,
int x,
int y);

View File

@ -952,7 +952,8 @@ meta_window_calc_showing (MetaWindow *window)
meta_effects_draw_box_animation (window->screen,
&window_rect,
&icon_rect,
META_MINIMIZE_ANIMATION_LENGTH);
META_MINIMIZE_ANIMATION_LENGTH,
META_BOX_ANIM_SCALE);
}
meta_window_hide (window);
@ -1429,7 +1430,8 @@ meta_window_shade (MetaWindow *window)
meta_effects_draw_box_animation (window->screen,
&starting_size,
&titlebar_size,
META_SHADE_ANIMATION_LENGTH);
META_SHADE_ANIMATION_LENGTH,
META_BOX_ANIM_SLIDE_UP);
}
window->shaded = TRUE;