From 1ec71144fb8064ffdbdcb56a213cf90a77726f68 Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Sat, 18 Jan 2014 13:02:47 -0500 Subject: [PATCH] GSimpleAction: add default activate handler If the action is stateful and the user doesn't have their own activate handler then do some reasonable things for ourselves. After a lot of experience using stateful GSimpleAction it turns out that people almost always end up using it in the same ways: A boolean-typed stateful action with no parameter is most likely going to want to be toggled. Any other type of action that has the parameter type equal to the state type probably intends for activation to represent a request to change the state. This patch implements those two cases. This will let people stop writing their own trivial handlers over and over. https://bugzilla.gnome.org/show_bug.cgi?id=722503 --- gio/gsimpleaction.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/gio/gsimpleaction.c b/gio/gsimpleaction.c index 5ee9806f8..819f50ba7 100644 --- a/gio/gsimpleaction.c +++ b/gio/gsimpleaction.c @@ -205,7 +205,28 @@ g_simple_action_activate (GAction *action, g_variant_ref_sink (parameter); if (simple->enabled) - g_signal_emit (simple, g_simple_action_signals[SIGNAL_ACTIVATE], 0, parameter); + { + /* If the user connected a signal handler then they are responsible + * for handling activation. + */ + if (g_signal_has_handler_pending (action, g_simple_action_signals[SIGNAL_ACTIVATE], 0, TRUE)) + g_signal_emit (action, g_simple_action_signals[SIGNAL_CHANGE_STATE], 0, parameter); + + /* If not, do some reasonable defaults for stateful actions. */ + else if (simple->state) + { + /* If we have no parameter and this is a boolean action, toggle. */ + if (parameter == NULL && g_variant_is_of_type (simple->state, G_VARIANT_TYPE_BOOLEAN)) + { + gboolean was_enabled = g_variant_get_boolean (simple->state); + g_simple_action_change_state (action, g_variant_new_boolean (!was_enabled)); + } + + /* else, if the parameter and state type are the same, do a change-state */ + else if (g_variant_is_of_type (simple->state, g_variant_get_type (parameter))) + g_simple_action_change_state (action, parameter); + } + } if (parameter != NULL) g_variant_unref (parameter); @@ -343,6 +364,14 @@ g_simple_action_class_init (GSimpleActionClass *class) * @parameter will always be of the expected type. In the event that * an incorrect type was given, no signal will be emitted. * + * Since GLib 2.40, if no handler is connected to this signal then the + * default behaviour for boolean-stated actions with a %NULL parameter + * type is to toggle them via the #GSimpleAction::change-state signal. + * For stateful actions where the state type is equal to the parameter + * type, the default is to forward them directly to + * #GSimpleAction::change-state. This should allow almost all users + * of #GSimpleAction to connect only one handler or the other. + * * Since: 2.28 */ g_simple_action_signals[SIGNAL_ACTIVATE] =