summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHavoc Pennington <hp@pobox.com>2002-03-05 05:05:00 +0000
committerHavoc Pennington <hp@src.gnome.org>2002-03-05 05:05:00 +0000
commitd443d92446e40ca5ecac74f8373e56f0f616f79b (patch)
tree365c1bd187b13c19a21efbd28effb543dc856187 /src
parent5429690467bd32b1de7ba08685cd44af5fe67ae6 (diff)
downloadmetacity-d443d92446e40ca5ecac74f8373e56f0f616f79b.tar.gz
metacity-d443d92446e40ca5ecac74f8373e56f0f616f79b.tar.bz2
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.
Diffstat (limited to 'src')
-rw-r--r--src/effects.c86
-rw-r--r--src/effects.h16
-rw-r--r--src/ui.c65
-rw-r--r--src/ui.h8
-rw-r--r--src/window.c6
5 files changed, 119 insertions, 62 deletions
diff --git a/src/effects.c b/src/effects.c
index 87930d8..e486edb 100644
--- a/src/effects.c
+++ b/src/effects.c
@@ -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);
}
}
diff --git a/src/effects.h b/src/effects.h
index 801b099..51a178b 100644
--- a/src/effects.h
+++ b/src/effects.h
@@ -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 */
diff --git a/src/ui.c b/src/ui.c
index a4062aa..3df9019 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -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)
-{
- 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.
+meta_image_window_set (MetaImageWindow *iw,
+ GdkPixbuf *pixbuf,
+ int x,
+ int y)
+{
+ /* 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*
diff --git a/src/ui.h b/src/ui.h
index d123a24..1e63f66 100644
--- a/src/ui.h
+++ b/src/ui.h
@@ -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);
diff --git a/src/window.c b/src/window.c
index fd91fee..e8e58c5 100644
--- a/src/window.c
+++ b/src/window.c
@@ -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;