[glib] GSimpleAction: add default activate handler



commit 1ec71144fb8064ffdbdcb56a213cf90a77726f68
Author: Ryan Lortie <desrt desrt ca>
Date:   Sat Jan 18 13:02:47 2014 -0500

    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 files changed, 30 insertions(+), 1 deletions(-)
---
diff --git a/gio/gsimpleaction.c b/gio/gsimpleaction.c
index 5ee9806..819f50b 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] =


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]