From 1c6ffc8a238e5e7de429f35f7653695d91d9d26d Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Tue, 12 Jan 2010 15:44:28 +0000 Subject: [PATCH] stage: Add the delete-event signal Using the ::event signal to match the CLUTTER_DELETE event type (and block the stage destruction) can be costly, since it means checking every single event. The ::delete-event signal is similar in spirit to any other specialized signal handler dealing with events, and retains the same semantics. --- clutter/clutter-main.c | 9 +------- clutter/clutter-stage.c | 49 ++++++++++++++++++++++++++++++++++++++++- clutter/clutter-stage.h | 6 ++++- 3 files changed, 54 insertions(+), 10 deletions(-) diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c index 7e9ae5e87..ea5e19d14 100644 --- a/clutter/clutter-main.c +++ b/clutter/clutter-main.c @@ -2375,14 +2375,7 @@ _clutter_process_event_details (ClutterActor *stage, case CLUTTER_DELETE: event->any.source = stage; /* the stage did not handle the event, so we just quit */ - if (!clutter_stage_event (CLUTTER_STAGE (stage), event)) - { - if (stage == clutter_stage_get_default()) - clutter_main_quit (); - else - clutter_actor_destroy (stage); - } - + clutter_stage_event (CLUTTER_STAGE (stage), event); break; case CLUTTER_KEY_PRESS: diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c index 66b7d0eba..518d181c7 100644 --- a/clutter/clutter-stage.c +++ b/clutter/clutter-stage.c @@ -122,6 +122,7 @@ enum UNFULLSCREEN, ACTIVATE, DEACTIVATE, + DELETE_EVENT, LAST_SIGNAL }; @@ -625,6 +626,18 @@ clutter_stage_real_queue_redraw (ClutterActor *actor, CLUTTER_CONTEXT ()->redraw_count += 1; } +static gboolean +clutter_stage_real_delete_event (ClutterStage *stage, + ClutterEvent *event) +{ + if (clutter_stage_is_default (stage)) + clutter_main_quit (); + else + clutter_actor_destroy (CLUTTER_ACTOR (stage)); + + return TRUE; +} + static void clutter_stage_set_property (GObject *object, guint prop_id, @@ -797,7 +810,6 @@ clutter_stage_finalize (GObject *object) G_OBJECT_CLASS (clutter_stage_parent_class)->finalize (object); } - static void clutter_stage_class_init (ClutterStageClass *klass) { @@ -1050,9 +1062,41 @@ clutter_stage_class_init (ClutterStageClass *klass) clutter_marshal_VOID__VOID, G_TYPE_NONE, 0); + /** + * ClutterStage::delete-event: + * @stage: the stage that received the event + * @event: a #ClutterEvent of type %CLUTTER_DELETE + * + * The ::delete-event signal is emitted when the user closes a + * #ClutterStage window using the window controls. + * + * Clutter by default will call clutter_main_quit() if @stage is + * the default stage, and clutter_actor_destroy() for any other + * stage. + * + * It is possible to override the default behaviour by connecting + * a new handler and returning %TRUE there. + * + * This signal is emitted only on Clutter backends that + * embed #ClutterStage in native windows. It is not emitted for + * backends that use a static frame buffer. + * + * Since: 1.2 + */ + stage_signals[DELETE_EVENT] = + g_signal_new (I_("delete-event"), + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ClutterStageClass, delete_event), + _clutter_boolean_handled_accumulator, NULL, + clutter_marshal_BOOLEAN__BOXED, + G_TYPE_BOOLEAN, 1, + CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); + klass->fullscreen = clutter_stage_real_fullscreen; klass->activate = clutter_stage_real_activate; klass->deactivate = clutter_stage_real_deactivate; + klass->delete_event = clutter_stage_real_delete_event; g_type_class_add_private (gobject_class, sizeof (ClutterStagePrivate)); } @@ -1531,6 +1575,9 @@ clutter_stage_event (ClutterStage *stage, g_signal_emit_by_name (stage, "event", event, &retval); + if (!retval) + g_signal_emit_by_name (stage, "delete-event", event, &retval); + return retval; } diff --git a/clutter/clutter-stage.h b/clutter/clutter-stage.h index f6fa0cdba..a4e3bfbb1 100644 --- a/clutter/clutter-stage.h +++ b/clutter/clutter-stage.h @@ -114,6 +114,7 @@ struct _ClutterStage * @unfullscreen: handler for the #ClutterStage::unfullscreen signal * @activate: handler for the #ClutterStage::activate signal * @deactivate: handler for the #ClutterStage::deactive signal + * @delete_event: handler for the #ClutterStage::delete-event signal * * The #ClutterStageClass structure contains only private data * @@ -132,9 +133,12 @@ struct _ClutterStageClass void (* activate) (ClutterStage *stage); void (* deactivate) (ClutterStage *stage); + gboolean (* delete_event) (ClutterStage *stage, + ClutterEvent *event); + /*< private >*/ /* padding for future expansion */ - gpointer _padding_dummy[32]; + gpointer _padding_dummy[31]; };