summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann <sandmann@redhat.com>2006-05-22 21:46:14 +0000
committerSøren Sandmann Pedersen <ssp@src.gnome.org>2006-05-22 21:46:14 +0000
commit3e5b9776c6044d397981fcf45d6476325145286b (patch)
tree1f1e763f3de58a2f22054b02f43eb016dad39f54
parentcdb94d7e576605d2c9e158a1c20de0d028f270ca (diff)
downloadmetacity-3e5b9776c6044d397981fcf45d6476325145286b.tar.gz
Beginning of new layer that abstracts transition effects.
Mon May 22 17:35:52 2006 Søren Sandmann <sandmann@redhat.com> * src/effects.[ch]: Beginning of new layer that abstracts transition effects. New functions: (meta_push_effect_handler): Install an effect handler (meta_pop_effect_handler): Remove last effect handler (meta_effect_run_minimize): Create a minimize effect and pass it to the handler. (meta_effect_end): Called by handler when the effect is finished. * src/compositor.c: Move explosion code form there to src/c-window.c. * src/c-screen.c: Delete explosion related code.
-rw-r--r--ChangeLog16
-rw-r--r--src/c-screen.c24
-rw-r--r--src/c-screen.h4
-rw-r--r--src/c-window.c308
-rw-r--r--src/c-window.h15
-rw-r--r--src/compositor.c114
-rw-r--r--src/compositor.h2
-rw-r--r--src/effects.c101
-rw-r--r--src/effects.h48
-rw-r--r--src/window.c32
10 files changed, 430 insertions, 234 deletions
diff --git a/ChangeLog b/ChangeLog
index cd41490c..4e80710a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+Mon May 22 17:35:52 2006 Søren Sandmann <sandmann@redhat.com>
+
+ * src/effects.[ch]: Beginning of new layer that abstracts
+ transition effects.
+
+ New functions:
+ (meta_push_effect_handler): Install an effect handler
+ (meta_pop_effect_handler): Remove last effect handler
+ (meta_effect_run_minimize): Create a minimize effect and pass it
+ to the handler.
+ (meta_effect_end): Called by handler when the effect is finished.
+
+ * src/compositor.c: Move explosion code form there to src/c-window.c.
+
+ * src/c-screen.c: Delete explosion related code.
+
2006-05-22 Björn Lindqvist <bjourne@gmail.com>
* common.h (enum MetaCursor):
diff --git a/src/c-screen.c b/src/c-screen.c
index 245b7aed..8d2b60ad 100644
--- a/src/c-screen.c
+++ b/src/c-screen.c
@@ -64,6 +64,13 @@ meta_comp_window_lookup (MetaCompScreen *info,
return window;
}
+MetaCompWindow *
+meta_comp_screen_lookup_window (MetaCompScreen *info,
+ Window xwindow)
+{
+ return meta_comp_window_lookup (info, xwindow);
+}
+
#if 0
static void
update_frame_counter (void)
@@ -651,23 +658,6 @@ meta_comp_screen_set_target_rect (MetaCompScreen *info,
}
void
-meta_comp_screen_set_explode (MetaCompScreen *info,
- Window xwindow,
- gdouble level)
-{
- CmDrawableNode *node = CM_DRAWABLE_NODE (find_node (info, xwindow));
-
- if (node)
- {
-#if 0
- g_print ("level: %f\n", level);
-#endif
-
- cm_drawable_node_set_explosion_level (node, level);
- }
-}
-
-void
meta_comp_screen_hide_window (MetaCompScreen *info,
Window xwindow)
{
diff --git a/src/c-screen.h b/src/c-screen.h
index 0b8b5757..a37c8cd1 100644
--- a/src/c-screen.h
+++ b/src/c-screen.h
@@ -1,4 +1,5 @@
#include "screen.h"
+#include "c-window.h"
typedef struct MetaCompScreen MetaCompScreen;
@@ -48,4 +49,5 @@ void meta_comp_screen_hide_window (MetaCompScreen *info,
Window xwindow);
void meta_comp_screen_unmap (MetaCompScreen *info,
Window xwindow);
-
+MetaCompWindow *meta_comp_screen_lookup_window (MetaCompScreen *info,
+ Window xwindow);
diff --git a/src/c-window.c b/src/c-window.c
index 40d9e256..8398f11c 100644
--- a/src/c-window.c
+++ b/src/c-window.c
@@ -28,7 +28,9 @@
#include <cm/node.h>
#include <cm/drawable-node.h>
#include <string.h>
+#include <math.h>
+#include "effects.h"
#include "c-window.h"
#include "window.h"
@@ -42,109 +44,16 @@ struct _MetaCompWindow
WsSyncAlarm *alarm;
WsRectangle size;
+ gboolean waiting_for_paint;
};
-MetaCompWindow *
-meta_comp_window_new (MetaDisplay *display,
- WsDrawable *drawable)
-{
- MetaCompWindow *window;
- WsRectangle geometry;
-
- ws_drawable_query_geometry (drawable, &geometry);
-
- window = g_new0 (MetaCompWindow, 1);
-
- window->display = display;
- window->drawable = g_object_ref (drawable);
- window->node = CM_NODE (cm_drawable_node_new (drawable, &geometry));
- window->updates = TRUE;
-
- return window;
-}
-
-void
-meta_comp_window_free (MetaCompWindow *window)
-{
- g_object_unref (window->drawable);
- g_object_unref (window->node);
- g_free (window);
-}
-
-void
-meta_comp_window_set_size (MetaCompWindow *comp_window,
- WsRectangle *rect)
-{
- if (comp_window->updates)
- {
- WsWindow *window = WS_WINDOW (comp_window->drawable);
- WsDisplay *display = WS_RESOURCE (window)->display;
- CmDrawableNode *dnode = CM_DRAWABLE_NODE (comp_window->node);
- WsRegion *shape;
-
- ws_display_begin_error_trap (display);
-
- cm_drawable_node_set_geometry (dnode, rect);
- shape = ws_window_get_output_shape (window);
- cm_drawable_node_set_shape (dnode, shape);
- ws_region_destroy (shape);
-
- if (rect->width != comp_window->size.width ||
- rect->height != comp_window->size.height)
- {
- cm_drawable_node_update_pixmap (dnode);
- }
-
- comp_window->size = *rect;
-
- ws_display_end_error_trap (display);
- }
-}
-
-static gboolean
-has_type (WsWindow *window, const char *check_type)
-{
- gchar **types = ws_window_get_property_atom_list (window, "_NET_WM_WINDOW_TYPE");
- int i;
- gboolean result;
-
- if (!types)
- return FALSE;
-
- result = FALSE;
-
- for (i = 0; types[i] != NULL; ++i)
- {
- gchar *type = types[i];
-
- if (strcmp (type, check_type) == 0)
- {
- result = TRUE;
- break;
- }
- }
-
- g_strfreev (types);
- return result;
-}
-
-static MetaWindow *
-find_meta_window (MetaCompWindow *comp_window)
-{
- Window xwindow = WS_RESOURCE_XID (comp_window->drawable);
- MetaWindow *window =
- meta_display_lookup_x_window (comp_window->display, xwindow);
-
- return window;
-}
-
static Window
find_app_window (MetaCompWindow *comp_window)
{
Window xwindow = WS_RESOURCE_XID (comp_window->drawable);
MetaWindow *meta_window =
meta_display_lookup_x_window (comp_window->display, xwindow);
-
+
if (meta_window)
return meta_window->xwindow;
else
@@ -159,9 +68,9 @@ take_snapshot (WsDrawable *drawable)
WsPixmap *pixmap;
ws_display_begin_error_trap (display);
-
+
ws_drawable_query_geometry (drawable, &geometry);
-
+
pixmap = ws_pixmap_new (drawable, geometry.width, geometry.height);
ws_drawable_copy_area (drawable, 0, 0, geometry.width, geometry.height,
@@ -169,7 +78,7 @@ take_snapshot (WsDrawable *drawable)
NULL);
ws_display_end_error_trap (display);
-
+
return pixmap;
}
@@ -178,11 +87,9 @@ on_alarm (WsSyncAlarm *alarm,
WsAlarmNotifyEvent *event,
MetaCompWindow *window)
{
- g_print ("received alarm\n");
-
if (window->pixmap)
g_object_unref (window->pixmap);
-
+
window->pixmap = take_snapshot (window->drawable);
ws_sync_alarm_set (window->alarm, event->counter_value + 2);
@@ -196,12 +103,12 @@ has_counter (MetaCompWindow *comp_window)
WsDisplay *display = WS_RESOURCE (comp_window->drawable)->display;
WsWindow *window = ws_window_lookup (display, xwindow);
WsSyncCounter *counter;
-
+
ws_display_init_sync (display);
counter = ws_window_get_property_sync_counter (
window, "_NET_WM_FINISH_FRAME_COUNTER");
-
+
if (counter)
{
WsSyncAlarm *alarm;
@@ -209,19 +116,19 @@ has_counter (MetaCompWindow *comp_window)
g_print ("counter value %lld\n", ws_sync_counter_query_value (counter));
alarm = ws_sync_alarm_new (display, counter);
-
+
g_signal_connect (alarm, "alarm_notify_event",
G_CALLBACK (on_alarm), comp_window);
-
+
if (value % 2 == 1)
{
ws_sync_alarm_set (alarm, value + 2);
-
+
g_print ("wait for %lld\n", value + 2);
g_print ("increasing counter\n");
ws_sync_counter_change (counter, 1);
-
+
g_print ("counter value %lld\n", ws_sync_counter_query_value (counter));
}
else
@@ -229,11 +136,16 @@ has_counter (MetaCompWindow *comp_window)
g_print ("wait for %lld\n", value + 1);
ws_sync_alarm_set (alarm, value + 1);
}
-
+
comp_window->alarm = alarm;
}
+ if (counter)
+ return TRUE;
+ else
+ return FALSE;
+
#if 0
if (counter)
{
@@ -246,10 +158,106 @@ has_counter (MetaCompWindow *comp_window)
g_print ("no counter found for %lx\n", WS_RESOURCE_XID (window));
}
#endif
-
+
return TRUE;
}
+MetaCompWindow *
+meta_comp_window_new (MetaDisplay *display,
+ WsDrawable *drawable)
+{
+ MetaCompWindow *window;
+ WsRectangle geometry;
+
+ ws_drawable_query_geometry (drawable, &geometry);
+
+ window = g_new0 (MetaCompWindow, 1);
+
+ window->display = display;
+ window->drawable = g_object_ref (drawable);
+ window->node = CM_NODE (cm_drawable_node_new (drawable, &geometry));
+ window->updates = TRUE;
+
+ return window;
+}
+
+void
+meta_comp_window_free (MetaCompWindow *window)
+{
+ g_object_unref (window->drawable);
+ g_object_unref (window->node);
+ if (window->alarm)
+ g_object_unref (window->alarm);
+ g_free (window);
+}
+
+void
+meta_comp_window_set_size (MetaCompWindow *comp_window,
+ WsRectangle *rect)
+{
+ if (comp_window->updates)
+ {
+ WsWindow *window = WS_WINDOW (comp_window->drawable);
+ WsDisplay *display = WS_RESOURCE (window)->display;
+ CmDrawableNode *dnode = CM_DRAWABLE_NODE (comp_window->node);
+ WsRegion *shape;
+
+ ws_display_begin_error_trap (display);
+
+ cm_drawable_node_set_geometry (dnode, rect);
+ shape = ws_window_get_output_shape (window);
+ cm_drawable_node_set_shape (dnode, shape);
+ ws_region_destroy (shape);
+
+ if (rect->width != comp_window->size.width ||
+ rect->height != comp_window->size.height)
+ {
+ cm_drawable_node_update_pixmap (dnode);
+ }
+
+ comp_window->size = *rect;
+
+ ws_display_end_error_trap (display);
+ }
+}
+
+static gboolean
+has_type (WsWindow *window, const char *check_type)
+{
+ gchar **types = ws_window_get_property_atom_list (window, "_NET_WM_WINDOW_TYPE");
+ int i;
+ gboolean result;
+
+ if (!types)
+ return FALSE;
+
+ result = FALSE;
+
+ for (i = 0; types[i] != NULL; ++i)
+ {
+ gchar *type = types[i];
+
+ if (strcmp (type, check_type) == 0)
+ {
+ result = TRUE;
+ break;
+ }
+ }
+
+ g_strfreev (types);
+ return result;
+}
+
+static MetaWindow *
+find_meta_window (MetaCompWindow *comp_window)
+{
+ Window xwindow = WS_RESOURCE_XID (comp_window->drawable);
+ MetaWindow *window =
+ meta_display_lookup_x_window (comp_window->display, xwindow);
+
+ return window;
+}
+
void
meta_comp_window_refresh_attrs (MetaCompWindow *comp_window)
{
@@ -260,19 +268,18 @@ meta_comp_window_refresh_attrs (MetaCompWindow *comp_window)
double alpha = 1.0;
CmDrawableNode *node = CM_DRAWABLE_NODE (comp_window->node);
- if (ws_window_query_mapped (WS_WINDOW (comp_window->drawable)))
+ if (ws_window_query_mapped (WS_WINDOW (comp_window->drawable)) &&
+ !comp_window->waiting_for_paint)
{
WsWindow *window = WS_WINDOW (comp_window->drawable);
cm_drawable_node_unset_patch (CM_DRAWABLE_NODE (node));
-
+
find_meta_window (comp_window);
-
- has_counter (comp_window);
if (has_type (window, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"))
{
- alpha = 0.3;
+ alpha = 0.9;
}
else if (has_type (window, "_NET_WM_WINDOW_TYPE_POPUP_MENU"))
{
@@ -284,7 +291,14 @@ meta_comp_window_refresh_attrs (MetaCompWindow *comp_window)
}
cm_drawable_node_set_alpha (node, alpha);
+
+#if 0
+ if (cm_drawable_node_get_viewable (node))
+ g_print ("mapping new window\n");
+#endif
+
cm_drawable_node_set_viewable (node, TRUE);
+
cm_drawable_node_update_pixmap (node);
}
else
@@ -298,9 +312,9 @@ meta_comp_window_set_updates (MetaCompWindow *comp_window,
gboolean updates)
{
CmDrawableNode *node = CM_DRAWABLE_NODE (comp_window->node);
-
+
comp_window->updates = updates;
-
+
cm_drawable_node_set_updates (node, updates);
if (updates)
@@ -326,4 +340,66 @@ meta_comp_window_get_node (MetaCompWindow *comp_window)
return comp_window->node;
}
+
+/*
+ * Explosion effect
+ */
+#define EXPLODE_TIME 1.0
+
+#define BASE 0.5
+
+static double
+transform (double in)
+{
+ return (pow (BASE, in) - 1) / (BASE - 1);
+}
+
+typedef struct
+{
+ MetaEffect *effect;
+ MetaCompWindow *window;
+ gdouble level;
+ GTimer * timer;
+} ExplodeInfo;
+
+static gboolean
+update_explosion (gpointer data)
+{
+ ExplodeInfo *info = data;
+ CmDrawableNode *node = (CmDrawableNode *)info->window->node;
+ gdouble elapsed = g_timer_elapsed (info->timer, NULL);
+
+ if (elapsed > EXPLODE_TIME)
+ {
+ meta_effect_end (info->effect);
+
+ cm_drawable_node_set_viewable (node, FALSE);
+ cm_drawable_node_set_explosion_level (node, 0.0);
+ return FALSE;
+ }
+ else
+ {
+ gdouble t = elapsed / EXPLODE_TIME;
+
+ cm_drawable_node_set_explosion_level (node,
+ transform (t));
+ return TRUE;
+ }
+}
+
+void
+meta_comp_window_explode (MetaCompWindow *comp_window,
+ MetaEffect *effect)
+{
+ ExplodeInfo *info = g_new0 (ExplodeInfo, 1);
+
+ info->window = comp_window;
+ info->effect = effect;
+ info->level = 0.0;
+ info->timer = g_timer_new ();
+
+ g_idle_add (update_explosion, info);
+}
+
#endif
+
diff --git a/src/c-window.h b/src/c-window.h
index 838c1bb8..a5a526ce 100644
--- a/src/c-window.h
+++ b/src/c-window.h
@@ -19,6 +19,10 @@
#include <cm/node.h>
#include "display.h"
+#include "effects.h"
+
+#ifndef C_WINDOW_H
+#define C_WINDOW_H
typedef struct _MetaCompWindow MetaCompWindow;
@@ -32,3 +36,14 @@ void meta_comp_window_set_size (MetaCompWindow *window,
void meta_comp_window_refresh_attrs (MetaCompWindow *comp_window);
void meta_comp_window_set_updates (MetaCompWindow *comp_window,
gboolean updates);
+
+void meta_comp_window_explode (MetaCompWindow *comp_window,
+ MetaEffect *effect);
+
+#if 0
+void meta_comp_window_set_explode (MetaCompWindow *comp_window,
+ double level);
+#endif
+
+#endif
+
diff --git a/src/compositor.c b/src/compositor.c
index f0a7b2a5..2dd6ad38 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -50,6 +50,8 @@
#include "spring-model.h"
#include <cm/state.h>
+#include "effects.h"
+
#include "c-screen.h"
#endif /* HAVE_COMPOSITE_EXTENSIONS */
@@ -94,6 +96,39 @@ handle_error (Display *dpy, XErrorEvent *ev, gpointer data)
}
#endif
+static Window
+get_xid (MetaWindow *window)
+{
+ if (window->frame)
+ return window->frame->xwindow;
+ else
+ return window->xwindow;
+}
+
+static void
+do_effect (MetaEffect *effect,
+ gpointer data)
+{
+ switch (effect->type)
+ {
+ case META_EFFECT_MINIMIZE:
+ {
+ MetaCompScreen *screen = meta_comp_screen_get_by_xwindow (
+ get_xid (effect->u.minimize.window));
+ MetaCompWindow *window =
+ meta_comp_screen_lookup_window (screen, effect->u.minimize.window->frame->xwindow);
+
+ meta_comp_window_explode (window, effect);
+ break;
+ }
+ default:
+ {
+ g_assert_not_reached();
+ break;
+ }
+ }
+}
+
MetaCompositor *
meta_compositor_new (MetaDisplay *display)
{
@@ -138,6 +173,8 @@ meta_compositor_new (MetaDisplay *display)
compositor->enabled = TRUE;
+ meta_push_effect_handler (do_effect, compositor);
+
return compositor;
#else /* HAVE_COMPOSITE_EXTENSIONS */
return NULL;
@@ -673,6 +710,7 @@ interpolate_rectangle (gdouble t,
#if MINIMIZE_STYLE == 0
+#if 0
void
meta_compositor_minimize (MetaCompositor *compositor,
MetaWindow *window,
@@ -684,6 +722,7 @@ meta_compositor_minimize (MetaCompositor *compositor,
gpointer data)
{
}
+#endif
#elif MINIMIZE_STYLE == 1
@@ -718,15 +757,6 @@ typedef struct
gboolean phase_5_started;
} MiniInfo;
-static Window
-get_xid (MetaWindow *window)
-{
- if (window->frame)
- return window->frame->xwindow;
- else
- return window->xwindow;
-}
-
static void
set_geometry (MiniInfo *info, gdouble elapsed)
{
@@ -923,72 +953,6 @@ run_animation_01 (gpointer data)
return TRUE;
}
-#define EXPLODE_TIME 1.0
-
-#define BASE 0.5
-
-static double
-transform (double in)
-{
- return (pow (BASE, in) - 1) / (BASE - 1);
-}
-
-typedef struct
-{
- MetaWindow * window;
- gdouble level;
- GTimer * timer;
- MetaAnimationFinishedFunc func;
- gpointer data;
- MetaCompScreen * minfo;
-} ExplodeInfo;
-
-static gboolean
-update_explosion (gpointer data)
-{
- ExplodeInfo *info = data;
- gdouble elapsed = g_timer_elapsed (info->timer, NULL);
- gdouble t = elapsed / EXPLODE_TIME;
-
- meta_comp_screen_set_explode (info->minfo, get_xid (info->window), transform (t));
-
- if (elapsed > EXPLODE_TIME)
- {
- if (info->func)
- info->func (info->data);
-
- meta_comp_screen_hide_window (info->minfo, get_xid (info->window));
- meta_comp_screen_set_explode (info->minfo, get_xid (info->window), 0.0);
- return FALSE;
- }
- else
- {
- return TRUE;
- }
-}
-
-void
-meta_compositor_minimize (MetaCompositor *compositor,
- MetaWindow *window,
- int x,
- int y,
- int width,
- int height,
- MetaAnimationFinishedFunc finished,
- gpointer data)
-{
- ExplodeInfo *info = g_new0 (ExplodeInfo, 1);
-
- info->window = window;
- info->level = 0.0;
- info->timer = g_timer_new ();
- info->func = finished;
- info->data = data;
- info->minfo = meta_comp_screen_get_by_xwindow (get_xid (window));
-
- g_idle_add (update_explosion, info);
-}
-
#if 0
void
meta_compositor_minimize (MetaCompositor *compositor,
diff --git a/src/compositor.h b/src/compositor.h
index 82f6284f..5fac333d 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -45,6 +45,7 @@ void meta_compositor_manage_screen (MetaCompositor *compositor,
void meta_compositor_unmanage_screen (MetaCompositor *compositor,
MetaScreen *screen);
+#if 0
void meta_compositor_minimize (MetaCompositor *compositor,
MetaWindow *window,
int x,
@@ -53,6 +54,7 @@ void meta_compositor_minimize (MetaCompositor *compositor,
int height,
MetaAnimationFinishedFunc finished_cb,
gpointer finished_data);
+#endif
void
meta_compositor_set_updates (MetaCompositor *compositor,
diff --git a/src/effects.c b/src/effects.c
index d48b8bdd..e08805d2 100644
--- a/src/effects.c
+++ b/src/effects.c
@@ -23,6 +23,7 @@
#include "effects.h"
#include "display.h"
#include "ui.h"
+#include "window.h"
#ifdef HAVE_SHAPE
#include <X11/extensions/shape.h>
@@ -72,6 +73,87 @@ typedef struct
} BoxAnimationContext;
+struct MetaEffectPriv
+{
+ MetaEffectFinished finished;
+ gpointer finished_data;
+};
+
+static void run_default_effect_handler (MetaEffect *effect);
+
+static MetaEffectHandler effect_handler;
+static gpointer effect_handler_data;
+
+void
+meta_push_effect_handler (MetaEffectHandler handler,
+ gpointer data)
+{
+ effect_handler = handler;
+ effect_handler_data = data;
+}
+
+void
+meta_pop_effect_handler (void)
+{
+ /* FIXME: not implemented yet */
+ g_assert_not_reached ();
+}
+
+static MetaEffect *
+create_effect (MetaEffectType type,
+ MetaEffectFinished finished,
+ gpointer finished_data)
+{
+ MetaEffect *effect = g_new (MetaEffect, 1);
+
+ effect->type = type;
+ effect->priv = g_new (MetaEffectPriv, 1);
+ effect->priv->finished = finished;
+ effect->priv->finished_data = finished_data;
+
+ return effect;
+}
+
+void
+meta_effect_run_minimize (MetaWindow *window,
+ MetaRectangle *window_rect,
+ MetaRectangle *icon_rect,
+ MetaEffectFinished finished,
+ gpointer data)
+{
+ MetaEffect *effect;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (icon_rect != NULL);
+
+ effect = create_effect (META_EFFECT_MINIMIZE,
+ finished, data);
+
+ effect->u.minimize.window = window;
+ effect->u.minimize.window_rect = *window_rect;
+ effect->u.minimize.icon_rect = *icon_rect;
+
+ if (effect_handler)
+ {
+ effect_handler (effect, effect_handler_data);
+ }
+ else
+ {
+ run_default_effect_handler (effect);
+ meta_effect_end (effect);
+ }
+}
+
+void
+meta_effect_end (MetaEffect *effect)
+{
+ if (effect->priv->finished)
+ effect->priv->finished (effect, effect->priv->finished_data);
+
+ g_free (effect->priv);
+ g_free (effect);
+}
+
static void
update_wireframe_window (MetaDisplay *display,
Window xwindow,
@@ -374,7 +456,7 @@ meta_effects_draw_box_animation (MetaScreen *screen,
attrs.override_redirect = True;
attrs.background_pixel = BlackPixel (screen->display->xdisplay,
screen->number);
-
+
context->wireframe_xwindow = XCreateWindow (screen->display->xdisplay,
screen->xroot,
initial_rect->x,
@@ -624,3 +706,20 @@ meta_effects_end_wireframe (MetaScreen *screen,
meta_ui_pop_delay_exposes (screen->ui);
}
+static void
+run_default_effect_handler (MetaEffect *effect)
+{
+ switch (effect->type)
+ {
+ case META_EFFECT_MINIMIZE:
+ meta_effects_draw_box_animation (effect->u.minimize.window->screen,
+ &(effect->u.minimize.window_rect),
+ &(effect->u.minimize.icon_rect),
+ META_MINIMIZE_ANIMATION_LENGTH,
+ META_BOX_ANIM_SCALE);
+ break;
+
+ default:
+ break;
+ }
+}
diff --git a/src/effects.h b/src/effects.h
index eb312cb8..847d6c52 100644
--- a/src/effects.h
+++ b/src/effects.h
@@ -25,6 +25,9 @@
#include "util.h"
#include "screen.h"
+typedef struct MetaEffect MetaEffect;
+typedef struct MetaEffectPriv MetaEffectPriv;
+
#define META_MINIMIZE_ANIMATION_LENGTH 0.25
#define META_SHADE_ANIMATION_LENGTH 0.2
@@ -35,6 +38,51 @@ typedef enum
} MetaBoxAnimType;
+typedef enum
+{
+ META_EFFECT_MINIMIZE
+} MetaEffectType;
+
+typedef void (* MetaEffectHandler) (MetaEffect *effect,
+ gpointer data);
+typedef void (* MetaEffectFinished) (const MetaEffect *effect,
+ gpointer data);
+
+typedef struct
+{
+ MetaWindow *window;
+ MetaRectangle window_rect;
+ MetaRectangle icon_rect;
+} MetaMinimizeEffect;
+
+struct MetaEffect
+{
+ MetaEffectType type;
+ gpointer info; /* effect handler can hang data here */
+
+ union
+ {
+ MetaMinimizeEffect minimize;
+ } u;
+
+ MetaEffectPriv *priv;
+};
+
+void meta_push_effect_handler (MetaEffectHandler handler,
+ gpointer data);
+void meta_pop_effect_handler (void);
+
+void meta_effect_run_minimize (MetaWindow *window,
+ MetaRectangle *window_rect,
+ MetaRectangle *target,
+ MetaEffectFinished finished,
+ gpointer data);
+void meta_effect_end (MetaEffect *effect);
+
+
+
+/* Stuff that should become static functions */
+
void meta_effects_draw_box_animation (MetaScreen *screen,
MetaRectangle *initial_rect,
MetaRectangle *destination_rect,
diff --git a/src/window.c b/src/window.c
index ba6981a3..bc922c5e 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1324,7 +1324,8 @@ meta_window_should_be_showing (MetaWindow *window)
}
static void
-finish_minimize (gpointer data)
+finish_minimize (const MetaEffect *effect,
+ gpointer data)
{
MetaWindow *window = data;
@@ -1381,32 +1382,15 @@ implement_showing (MetaWindow *window,
meta_window_get_outer_rect (window, &window_rect);
- if (window->display->compositor)
- {
- /* Draw a nice cool animation */
- meta_compositor_minimize (window->display->compositor,
- window,
- icon_rect.x,
- icon_rect.y,
- icon_rect.width,
- icon_rect.height,
- finish_minimize,
- window);
- }
- else
- {
- meta_effects_draw_box_animation (window->screen,
- &window_rect,
- &icon_rect,
- META_MINIMIZE_ANIMATION_LENGTH,
- META_BOX_ANIM_SCALE);
-
- finish_minimize (window);
- }
+ meta_effect_run_minimize (window,
+ &window_rect,
+ &icon_rect,
+ finish_minimize,
+ window);
}
else
{
- finish_minimize (window);
+ finish_minimize (NULL, window);
}
}
else