[gtk/wip/ebassi/shortcut: 6/85] bindings: Split out function to invoke an action signal



commit 6762c711a3a05e93c2d278637c42d73ecc8442c7
Author: Benjamin Otte <otte redhat com>
Date:   Sat Aug 4 11:01:32 2018 +0200

    bindings: Split out function to invoke an action signal
    
    We want to use that in shortcuts later.

 gtk/gtkbindings.c        | 135 +++++++++++++++++++++++++++++------------------
 gtk/gtkbindingsprivate.h |   6 +++
 2 files changed, 91 insertions(+), 50 deletions(-)
---
diff --git a/gtk/gtkbindings.c b/gtk/gtkbindings.c
index 6d82d8ffed..8813b53b3f 100644
--- a/gtk/gtkbindings.c
+++ b/gtk/gtkbindings.c
@@ -588,6 +588,82 @@ binding_compose_params (GObject         *object,
   return valid;
 }
 
+gboolean
+gtk_binding_emit_signal (GObject    *object,
+                         const char *signal,
+                         GVariant   *args,
+                         gboolean   *handled,
+                         GError    **error)
+{
+  GSignalQuery query;
+  guint signal_id;
+  GValue *params = NULL;
+  GValue return_val = G_VALUE_INIT;
+  GVariantIter args_iter;
+  gsize n_args;
+  guint i;
+
+  *handled = FALSE;
+
+  signal_id = g_signal_lookup (signal, G_OBJECT_TYPE (object));
+  if (!signal_id)
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Could not find signal \"%s\" in the '%s' class ancestry",
+                   signal,
+                   g_type_name (G_OBJECT_TYPE (object)));
+      return FALSE;
+    }
+
+  g_signal_query (signal_id, &query);
+  if (args)
+    n_args = g_variant_iter_init (&args_iter, args);
+  else
+    n_args = 0;
+  if (query.n_params != n_args ||
+      (query.return_type != G_TYPE_NONE && query.return_type != G_TYPE_BOOLEAN) ||
+      !binding_compose_params (object, &args_iter, &query, &params))
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "signature mismatch for signal \"%s\" in the '%s' class ancestry",
+                   signal,
+                   g_type_name (G_OBJECT_TYPE (object)));
+      return FALSE;
+    }
+  else if (!(query.signal_flags & G_SIGNAL_ACTION))
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "signal \"%s\" in the '%s' class ancestry cannot be used for action emissions",
+                   signal,
+                   g_type_name (G_OBJECT_TYPE (object)));
+      return FALSE;
+    }
+
+  if (query.return_type == G_TYPE_BOOLEAN)
+    g_value_init (&return_val, G_TYPE_BOOLEAN);
+
+  g_signal_emitv (params, signal_id, 0, &return_val);
+
+  if (query.return_type == G_TYPE_BOOLEAN)
+    {
+      if (g_value_get_boolean (&return_val))
+        *handled = TRUE;
+      g_value_unset (&return_val);
+    }
+  else
+    *handled = TRUE;
+
+  if (params != NULL)
+    {
+      for (i = 0; i < query.n_params + 1; i++)
+        g_value_unset (&params[i]);
+
+      g_free (params);
+    }
+
+  return TRUE;
+}
+
 static gboolean
 binding_signal_activate_signal (GtkBindingSignalSignal *sig,
                                 GObject                *object)
@@ -711,62 +787,21 @@ gtk_binding_entry_activate (GtkBindingEntry *entry,
 
   for (sig = entry->signals; sig; sig = sig->next)
     {
-      GSignalQuery query;
-      guint signal_id;
-      GValue *params = NULL;
-      GValue return_val = G_VALUE_INIT;
-      gchar *accelerator = NULL;
-      GVariantIter args_iter;
-      gsize n_args;
-
-      signal_id = g_signal_lookup (sig->signal_name, G_OBJECT_TYPE (object));
-      if (!signal_id)
+      GError *error = NULL;
+      gboolean signal_handled;
+
+      if (gtk_binding_emit_signal (object, sig->signal_name, sig->args, &signal_handled, &error))
         {
-          accelerator = gtk_accelerator_name (entry->keyval, entry->modifiers);
-          g_warning ("gtk_binding_entry_activate(): binding \"%s::%s\": "
-                     "could not find signal \"%s\" in the '%s' class ancestry",
-                     entry->binding_set->set_name,
-                     accelerator,
-                     sig->signal_name,
-                     g_type_name (G_OBJECT_TYPE (object)));
-          g_free (accelerator);
-          continue;
+          handled |= signal_handled;
         }
-
-      g_signal_query (signal_id, &query);
-      if (sig->args)
-        n_args = g_variant_iter_init (&args_iter, sig->args);
       else
-        n_args = 0;
-      if (query.n_params != n_args ||
-          (query.return_type != G_TYPE_NONE && query.return_type != G_TYPE_BOOLEAN) ||
-          !binding_compose_params (object, &args_iter, &query, &params))
         {
-          accelerator = gtk_accelerator_name (entry->keyval, entry->modifiers);
-          g_warning ("gtk_binding_entry_activate(): binding \"%s::%s\": "
-                     "signature mismatch for signal \"%s\" in the '%s' class ancestry",
+          char *accelerator = gtk_accelerator_name (entry->keyval, entry->modifiers);
+          g_warning ("gtk_binding_entry_activate(): binding \"%s::%s\": %s",
                      entry->binding_set->set_name,
                      accelerator,
-                     sig->signal_name,
-                     g_type_name (G_OBJECT_TYPE (object)));
-        }
-      else if (!(query.signal_flags & G_SIGNAL_ACTION))
-        {
-        case GTK_BINDING_SIGNAL:
-          handled = binding_signal_activate_signal ((GtkBindingSignalSignal *) sig, object);
-          break;
-
-        case GTK_BINDING_ACTION:
-          handled = binding_signal_activate_action ((GtkBindingSignalAction *) sig, object);
-          break;
-
-        case GTK_BINDING_CALLBACK:
-          handled = binding_signal_activate_callback ((GtkBindingSignalCallback *) sig, object);
-          break;
-
-        default:
-          g_assert_not_reached ();
-          break;
+                     error->message);
+          g_clear_error (&error);
         }
 
       if (entry->destroyed)
diff --git a/gtk/gtkbindingsprivate.h b/gtk/gtkbindingsprivate.h
index b99126119b..8fbccd2cdd 100644
--- a/gtk/gtkbindingsprivate.h
+++ b/gtk/gtkbindingsprivate.h
@@ -25,6 +25,12 @@ G_BEGIN_DECLS
 guint _gtk_binding_parse_binding     (GScanner        *scanner);
 void  _gtk_binding_reset_parsed      (void);
 
+gboolean gtk_binding_emit_signal     (GObject         *object,
+                                      const char      *signal,
+                                      GVariant        *args,
+                                      gboolean        *handled,
+                                      GError         **error);
+
 G_END_DECLS
 
 #endif /* __GTK_BINDINGS_PRIVATE_H__ */


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