summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSøren Sandmann <sandmann@redhat.com>2006-05-23 20:38:18 +0000
committerSøren Sandmann Pedersen <ssp@src.gnome.org>2006-05-23 20:38:18 +0000
commit7592470dab8805f65ff6ab820400c13e4c2c5902 (patch)
tree99246c9e224d0c6fe81846916ecd2feb1780110e /src
parent179987132c744424f960d378e356e5826560b2c4 (diff)
downloadmetacity-7592470dab8805f65ff6ab820400c13e4c2c5902.tar.gz
Also use explode when windows close.
Tue May 23 16:36:04 2006 Søren Sandmann <sandmann@redhat.com> * src/compositor.c (do_effect): Also use explode when windows close. * src/c-window.c (meta_comp_window_explode): Add refcounting to comp window, and use it in the explosion effect * src/effects.h (struct MetaEffect): Add new MetaCloseEffect. * src/display.c (event_callback): Run it from the UnmapNotify event handler.
Diffstat (limited to 'src')
-rw-r--r--src/c-window.c95
-rw-r--r--src/compositor.c14
-rw-r--r--src/display.c3
-rw-r--r--src/effects.c44
-rw-r--r--src/effects.h12
5 files changed, 142 insertions, 26 deletions
diff --git a/src/c-window.c b/src/c-window.c
index 18ddca2c..d44aed5e 100644
--- a/src/c-window.c
+++ b/src/c-window.c
@@ -47,6 +47,10 @@ struct _MetaCompWindow
gboolean waiting_for_paint;
gint64 counter_value;
+ gint ref_count;
+
+ gboolean animation_in_progress;
+ gboolean hide_after_animation;
};
static Window
@@ -168,6 +172,29 @@ has_counter (MetaCompWindow *comp_window)
return TRUE;
}
+static void
+show_node (MetaCompWindow *comp_window)
+{
+ if (comp_window->animation_in_progress)
+ comp_window->hide_after_animation = FALSE;
+
+ cm_drawable_node_set_viewable (CM_DRAWABLE_NODE (comp_window->node), TRUE);
+ cm_drawable_node_update_pixmap (CM_DRAWABLE_NODE (comp_window->node));
+}
+
+static void
+hide_node (MetaCompWindow *comp_window)
+{
+ if (comp_window->animation_in_progress)
+ {
+ comp_window->hide_after_animation = TRUE;
+ return;
+ }
+
+ g_print ("hide %p\n", comp_window->node);
+ cm_drawable_node_set_viewable (CM_DRAWABLE_NODE (comp_window->node), FALSE);
+}
+
MetaCompWindow *
meta_comp_window_new (MetaDisplay *display,
WsDrawable *drawable)
@@ -184,20 +211,38 @@ meta_comp_window_new (MetaDisplay *display,
window->node = CM_NODE (cm_drawable_node_new (drawable, &geometry));
window->updates = TRUE;
window->counter_value = 1;
+ window->ref_count = 1;
- cm_drawable_node_set_viewable (CM_DRAWABLE_NODE (window->node), FALSE);
+ hide_node (window);
return window;
}
+static MetaCompWindow *
+comp_window_ref (MetaCompWindow *comp_window)
+{
+ comp_window->ref_count++;
+
+ return comp_window;
+}
+
+static void
+comp_window_unref (MetaCompWindow *comp_window)
+{
+ if (--comp_window->ref_count == 0)
+ {
+ g_object_unref (comp_window->drawable);
+ g_object_unref (comp_window->node);
+ if (comp_window->alarm)
+ g_object_unref (comp_window->alarm);
+ g_free (comp_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);
+ comp_window_unref (window);
}
void
@@ -344,8 +389,7 @@ on_request_alarm (WsSyncAlarm *alarm,
g_print ("alarm for %p\n", comp_window);
#endif
- cm_drawable_node_set_viewable (CM_DRAWABLE_NODE (comp_window->node), TRUE);
- cm_drawable_node_update_pixmap (CM_DRAWABLE_NODE (comp_window->node));
+ show_node (comp_window);
g_object_unref (alarm);
}
@@ -453,8 +497,7 @@ meta_comp_window_refresh_attrs (MetaCompWindow *comp_window)
#if 0
g_print ("directly showing %p\n", comp_window);
#endif
- cm_drawable_node_set_viewable (node, TRUE);
- cm_drawable_node_update_pixmap (CM_DRAWABLE_NODE (comp_window->node));
+ show_node (comp_window);
}
else
{
@@ -470,7 +513,7 @@ meta_comp_window_refresh_attrs (MetaCompWindow *comp_window)
g_print ("unmapping %p\n", node);
#endif
- cm_drawable_node_set_viewable (node, FALSE);
+ hide_node (comp_window);
}
}
@@ -524,7 +567,7 @@ transform (double in)
typedef struct
{
MetaEffect *effect;
- MetaCompWindow *window;
+ MetaCompWindow *comp_window;
gdouble level;
GTimer * timer;
} ExplodeInfo;
@@ -533,15 +576,25 @@ static gboolean
update_explosion (gpointer data)
{
ExplodeInfo *info = data;
- CmDrawableNode *node = (CmDrawableNode *)info->window->node;
+ CmDrawableNode *node = CM_DRAWABLE_NODE (info->comp_window->node);
gdouble elapsed = g_timer_elapsed (info->timer, NULL);
+ if (!cm_drawable_node_get_viewable (node))
+ {
+ g_print ("huh, how did that happen to %p?\n", node);
+ }
+
if (elapsed > EXPLODE_TIME)
{
meta_effect_end (info->effect);
+
+ info->comp_window->animation_in_progress = FALSE;
+ if (info->comp_window->hide_after_animation)
+ hide_node (info->comp_window);
- cm_drawable_node_set_viewable (node, FALSE);
cm_drawable_node_set_explosion_level (node, 0.0);
+
+ comp_window_unref (info->comp_window);
return FALSE;
}
else
@@ -560,7 +613,19 @@ meta_comp_window_explode (MetaCompWindow *comp_window,
{
ExplodeInfo *info = g_new0 (ExplodeInfo, 1);
- info->window = comp_window;
+ if (!cm_drawable_node_get_viewable (comp_window->node))
+ {
+ g_print ("%p wasn't even viewable to begin with\n", comp_window->node);
+ return;
+ }
+ else
+ {
+ g_print ("%p is viewable\n", comp_window->node);
+ }
+
+ comp_window->animation_in_progress = TRUE;
+
+ info->comp_window = comp_window_ref (comp_window);
info->effect = effect;
info->level = 0.0;
info->timer = g_timer_new ();
diff --git a/src/compositor.c b/src/compositor.c
index 2dd6ad38..aeffb294 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -121,6 +121,20 @@ do_effect (MetaEffect *effect,
meta_comp_window_explode (window, effect);
break;
}
+ case META_EFFECT_CLOSE:
+ {
+ 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);
+ g_print ("close\n");
+
+ meta_comp_window_explode (window, effect);
+#if 0
+ meta_effect_end (effect);
+#endif
+ break;
+ }
default:
{
g_assert_not_reached();
diff --git a/src/display.c b/src/display.c
index 40a79b28..63147a8b 100644
--- a/src/display.c
+++ b/src/display.c
@@ -2010,6 +2010,9 @@ event_callback (XEvent *event,
meta_topic (META_DEBUG_WINDOW_STATE,
"Window %s withdrawn\n",
window->desc);
+
+ meta_effect_run_close (window, NULL, NULL);
+
window->withdrawn = TRUE;
meta_window_free (window); /* Unmanage withdrawn window */
window = NULL;
diff --git a/src/effects.c b/src/effects.c
index e08805d2..6bd2055a 100644
--- a/src/effects.c
+++ b/src/effects.c
@@ -80,6 +80,7 @@ struct MetaEffectPriv
};
static void run_default_effect_handler (MetaEffect *effect);
+static void run_handler (MetaEffect *effect);
static MetaEffectHandler effect_handler;
static gpointer effect_handler_data;
@@ -132,16 +133,25 @@ meta_effect_run_minimize (MetaWindow *window,
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);
- }
+
+ run_handler (effect);
+}
+
+void
+meta_effect_run_close (MetaWindow *window,
+ MetaEffectFinished finished,
+ gpointer data)
+{
+ MetaEffect *effect;
+
+ g_return_if_fail (window != NULL);
+
+ effect = create_effect (META_EFFECT_CLOSE,
+ finished, data);
+
+ effect->u.close.window = window;
+
+ run_handler (effect);
}
void
@@ -723,3 +733,17 @@ run_default_effect_handler (MetaEffect *effect)
break;
}
}
+
+static void
+run_handler (MetaEffect *effect)
+{
+ if (effect_handler)
+ {
+ effect_handler (effect, effect_handler_data);
+ }
+ else
+ {
+ run_default_effect_handler (effect);
+ meta_effect_end (effect);
+ }
+}
diff --git a/src/effects.h b/src/effects.h
index aa624e4f..09774a77 100644
--- a/src/effects.h
+++ b/src/effects.h
@@ -50,6 +50,7 @@ typedef enum
META_EFFECT_TOPLEVEL_UNMAP,
META_EFFECT_ALT_TAB,
META_EFFECT_FOCUS,
+ META_EFFECT_CLOSE,
} MetaEffectType;
typedef void (* MetaEffectHandler) (MetaEffect *effect,
@@ -64,6 +65,11 @@ typedef struct
MetaRectangle icon_rect;
} MetaMinimizeEffect;
+typedef struct
+{
+ MetaWindow *window;
+} MetaCloseEffect;
+
struct MetaEffect
{
MetaEffectType type;
@@ -72,8 +78,9 @@ struct MetaEffect
union
{
MetaMinimizeEffect minimize;
+ MetaCloseEffect close;
} u;
-
+
MetaEffectPriv *priv;
};
@@ -86,6 +93,9 @@ void meta_effect_run_minimize (MetaWindow *window,
MetaRectangle *target,
MetaEffectFinished finished,
gpointer data);
+void meta_effect_run_close (MetaWindow *window,
+ MetaEffectFinished finished,
+ gpointer data);
void meta_effect_end (MetaEffect *effect);