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.
This commit is contained in:
Emmanuele Bassi 2010-01-12 15:44:28 +00:00
parent 8b950bdc87
commit 1c6ffc8a23
3 changed files with 54 additions and 10 deletions

View File

@ -2375,14 +2375,7 @@ _clutter_process_event_details (ClutterActor *stage,
case CLUTTER_DELETE: case CLUTTER_DELETE:
event->any.source = stage; event->any.source = stage;
/* the stage did not handle the event, so we just quit */ /* the stage did not handle the event, so we just quit */
if (!clutter_stage_event (CLUTTER_STAGE (stage), event)) clutter_stage_event (CLUTTER_STAGE (stage), event);
{
if (stage == clutter_stage_get_default())
clutter_main_quit ();
else
clutter_actor_destroy (stage);
}
break; break;
case CLUTTER_KEY_PRESS: case CLUTTER_KEY_PRESS:

View File

@ -122,6 +122,7 @@ enum
UNFULLSCREEN, UNFULLSCREEN,
ACTIVATE, ACTIVATE,
DEACTIVATE, DEACTIVATE,
DELETE_EVENT,
LAST_SIGNAL LAST_SIGNAL
}; };
@ -625,6 +626,18 @@ clutter_stage_real_queue_redraw (ClutterActor *actor,
CLUTTER_CONTEXT ()->redraw_count += 1; 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 static void
clutter_stage_set_property (GObject *object, clutter_stage_set_property (GObject *object,
guint prop_id, guint prop_id,
@ -797,7 +810,6 @@ clutter_stage_finalize (GObject *object)
G_OBJECT_CLASS (clutter_stage_parent_class)->finalize (object); G_OBJECT_CLASS (clutter_stage_parent_class)->finalize (object);
} }
static void static void
clutter_stage_class_init (ClutterStageClass *klass) clutter_stage_class_init (ClutterStageClass *klass)
{ {
@ -1050,9 +1062,41 @@ clutter_stage_class_init (ClutterStageClass *klass)
clutter_marshal_VOID__VOID, clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0); 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.
*
* <note>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.</note>
*
* 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->fullscreen = clutter_stage_real_fullscreen;
klass->activate = clutter_stage_real_activate; klass->activate = clutter_stage_real_activate;
klass->deactivate = clutter_stage_real_deactivate; klass->deactivate = clutter_stage_real_deactivate;
klass->delete_event = clutter_stage_real_delete_event;
g_type_class_add_private (gobject_class, sizeof (ClutterStagePrivate)); 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); g_signal_emit_by_name (stage, "event", event, &retval);
if (!retval)
g_signal_emit_by_name (stage, "delete-event", event, &retval);
return retval; return retval;
} }

View File

@ -114,6 +114,7 @@ struct _ClutterStage
* @unfullscreen: handler for the #ClutterStage::unfullscreen signal * @unfullscreen: handler for the #ClutterStage::unfullscreen signal
* @activate: handler for the #ClutterStage::activate signal * @activate: handler for the #ClutterStage::activate signal
* @deactivate: handler for the #ClutterStage::deactive signal * @deactivate: handler for the #ClutterStage::deactive signal
* @delete_event: handler for the #ClutterStage::delete-event signal
* *
* The #ClutterStageClass structure contains only private data * The #ClutterStageClass structure contains only private data
* *
@ -132,9 +133,12 @@ struct _ClutterStageClass
void (* activate) (ClutterStage *stage); void (* activate) (ClutterStage *stage);
void (* deactivate) (ClutterStage *stage); void (* deactivate) (ClutterStage *stage);
gboolean (* delete_event) (ClutterStage *stage,
ClutterEvent *event);
/*< private >*/ /*< private >*/
/* padding for future expansion */ /* padding for future expansion */
gpointer _padding_dummy[32]; gpointer _padding_dummy[31];
}; };