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.
This commit is contained in:
Søren Sandmann 2006-05-23 20:38:18 +00:00 committed by Søren Sandmann Pedersen
parent 179987132c
commit 7592470dab
6 changed files with 154 additions and 26 deletions

View File

@ -1,3 +1,15 @@
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.
Tue May 23 15:23:58 2006 Søren Sandmann <sandmann@redhat.com>
* src/c-window.c (send_sync_request): New function to send a sync

View File

@ -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);
cm_drawable_node_set_viewable (node, FALSE);
info->comp_window->animation_in_progress = FALSE;
if (info->comp_window->hide_after_animation)
hide_node (info->comp_window);
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 ();

View File

@ -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();

View File

@ -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;

View File

@ -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;
@ -133,15 +134,24 @@ meta_effect_run_minimize (MetaWindow *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);
}
}

View File

@ -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,6 +78,7 @@ 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);