bindings: Split out function to invoke an action signal

We want to use that in shortcuts later.
This commit is contained in:
Benjamin Otte 2018-08-04 11:01:32 +02:00 committed by Matthias Clasen
parent 5c6be5c0cd
commit fed7d3833f
2 changed files with 53 additions and 41 deletions

View File

@ -636,12 +636,12 @@ binding_compose_params (GObject *object,
return valid; return valid;
} }
static gboolean gboolean
binding_signal_activate_signal (GtkBindingSignalSignal *sig, gtk_binding_emit_signal (GObject *object,
const char *set_name, const char *signal,
guint keyval, GVariant *args,
GdkModifierType modifiers, gboolean *handled,
GObject *object) GError **error)
{ {
GSignalQuery query; GSignalQuery query;
guint signal_id; guint signal_id;
@ -649,49 +649,41 @@ binding_signal_activate_signal (GtkBindingSignalSignal *sig,
GValue return_val = G_VALUE_INIT; GValue return_val = G_VALUE_INIT;
GVariantIter args_iter; GVariantIter args_iter;
gsize n_args; gsize n_args;
gboolean handled = FALSE; guint i;
signal_id = g_signal_lookup (sig->signal_name, G_OBJECT_TYPE (object)); *handled = FALSE;
signal_id = g_signal_lookup (signal, G_OBJECT_TYPE (object));
if (!signal_id) if (!signal_id)
{ {
char *accelerator = gtk_accelerator_name (keyval, modifiers); g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
g_warning ("gtk_binding_entry_activate(): binding \"%s::%s\": " "Could not find signal \"%s\" in the '%s' class ancestry",
"could not find signal \"%s\" in the '%s' class ancestry", signal,
set_name, accelerator,
sig->signal_name,
g_type_name (G_OBJECT_TYPE (object))); g_type_name (G_OBJECT_TYPE (object)));
g_free (accelerator);
return FALSE; return FALSE;
} }
g_signal_query (signal_id, &query); g_signal_query (signal_id, &query);
if (sig->args) if (args)
n_args = g_variant_iter_init (&args_iter, sig->args); n_args = g_variant_iter_init (&args_iter, args);
else else
n_args = 0; n_args = 0;
if (query.n_params != n_args || if (query.n_params != n_args ||
(query.return_type != G_TYPE_NONE && query.return_type != G_TYPE_BOOLEAN) || (query.return_type != G_TYPE_NONE && query.return_type != G_TYPE_BOOLEAN) ||
!binding_compose_params (object, &args_iter, &query, &params)) !binding_compose_params (object, &args_iter, &query, &params))
{ {
char *accelerator = gtk_accelerator_name (keyval, modifiers); g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
g_warning ("gtk_binding_entry_activate(): binding \"%s::%s\": "
"signature mismatch for signal \"%s\" in the '%s' class ancestry", "signature mismatch for signal \"%s\" in the '%s' class ancestry",
set_name, accelerator, signal,
sig->signal_name,
g_type_name (G_OBJECT_TYPE (object))); g_type_name (G_OBJECT_TYPE (object)));
g_free (accelerator);
return FALSE; return FALSE;
} }
else if (!(query.signal_flags & G_SIGNAL_ACTION)) else if (!(query.signal_flags & G_SIGNAL_ACTION))
{ {
char *accelerator = gtk_accelerator_name (keyval, modifiers); g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
g_warning ("gtk_binding_entry_activate(): binding \"%s::%s\": "
"signal \"%s\" in the '%s' class ancestry cannot be used for action emissions", "signal \"%s\" in the '%s' class ancestry cannot be used for action emissions",
set_name, accelerator, signal,
sig->signal_name,
g_type_name (G_OBJECT_TYPE (object))); g_type_name (G_OBJECT_TYPE (object)));
g_free (accelerator);
return FALSE; return FALSE;
} }
@ -703,23 +695,21 @@ binding_signal_activate_signal (GtkBindingSignalSignal *sig,
if (query.return_type == G_TYPE_BOOLEAN) if (query.return_type == G_TYPE_BOOLEAN)
{ {
if (g_value_get_boolean (&return_val)) if (g_value_get_boolean (&return_val))
handled = TRUE; *handled = TRUE;
g_value_unset (&return_val); g_value_unset (&return_val);
} }
else else
handled = TRUE; *handled = TRUE;
if (params != NULL) if (params != NULL)
{ {
guint i;
for (i = 0; i < query.n_params + 1; i++) for (i = 0; i < query.n_params + 1; i++)
g_value_unset (&params[i]); g_value_unset (&params[i]);
g_free (params); g_free (params);
} }
return handled; return TRUE;
} }
static gboolean static gboolean
@ -796,10 +786,26 @@ gtk_binding_entry_activate (GtkBindingEntry *entry,
switch (sig->action_type) switch (sig->action_type)
{ {
case GTK_BINDING_SIGNAL: case GTK_BINDING_SIGNAL:
handled = binding_signal_activate_signal ((GtkBindingSignalSignal *) sig, {
GtkBindingSignalSignal *signal = (GtkBindingSignalSignal *) sig;
GError *error = NULL;
gboolean signal_handled = FALSE;
if (gtk_binding_emit_signal (object, signal->signal_name, signal->args, &signal_handled, &error))
{
handled |= signal_handled;
}
else
{
char *accelerator = gtk_accelerator_name (entry->keyval, entry->modifiers);
g_warning ("gtk_binding_entry_activate(): binding \"%s::%s\": %s",
entry->binding_set->set_name, entry->binding_set->set_name,
entry->keyval, entry->modifiers, accelerator,
object); error->message);
g_free (accelerator);
g_clear_error (&error);
}
}
break; break;
case GTK_BINDING_ACTION: case GTK_BINDING_ACTION:

View File

@ -25,6 +25,12 @@ G_BEGIN_DECLS
guint _gtk_binding_parse_binding (GScanner *scanner); guint _gtk_binding_parse_binding (GScanner *scanner);
void _gtk_binding_reset_parsed (void); 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 G_END_DECLS
#endif /* __GTK_BINDINGS_PRIVATE_H__ */ #endif /* __GTK_BINDINGS_PRIVATE_H__ */