[gtk/widget-class-actions: 10/12] widget: Add api to bind accels to actions



commit 725867a72ed3b9299623bce163cd16a00cf3e5f0
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Jun 17 12:50:25 2019 +0000

    widget: Add api to bind accels to actions
    
    This is meant to be used at class-init time,
    and will replace bindings, eventually.
    
    We are reusing GtkApplicationAccels here.
    It should probably be renamed.

 gtk/gtkwidget.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gtk/gtkwidget.h |  9 +++++++
 2 files changed, 90 insertions(+)
---
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 2d29fe1f46..4c8c180974 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -73,6 +73,7 @@
 #include "gtkwindowgroup.h"
 #include "gtkwindowprivate.h"
 #include "gtknativeprivate.h"
+#include "gtkapplicationaccelsprivate.h"
 
 #include "a11y/gtkwidgetaccessible.h"
 #include "inspector/window.h"
@@ -502,6 +503,7 @@ struct _GtkWidgetClassPrivate
   const char *css_name;
   GType layout_manager_type;
   GPtrArray *actions;
+  GtkApplicationAccels *accels;
 };
 
 enum {
@@ -713,6 +715,9 @@ static gboolean gtk_widget_class_get_visible_by_default (GtkWidgetClass *widget_
 static void remove_parent_surface_transform_changed_listener (GtkWidget *widget);
 static void add_parent_surface_transform_changed_listener (GtkWidget *widget);
 
+static gboolean gtk_widget_activate_accels (GtkWidget      *widget,
+                                            const GdkEvent *event);
+
 
 /* --- variables --- */
 static gint             GtkWidget_private_offset = 0;
@@ -5360,6 +5365,11 @@ gtk_widget_event_internal (GtkWidget      *widget,
        event->any.type == GDK_KEY_RELEASE))
     return_val |= gtk_bindings_activate_event (G_OBJECT (widget), (GdkEventKey *) event);
 
+  if (return_val == FALSE &&
+      (event->any.type == GDK_KEY_PRESS ||
+       event->any.type == GDK_KEY_RELEASE))
+    return_val = gtk_widget_activate_accels (widget, event);
+
   return return_val;
 }
 
@@ -13572,3 +13582,74 @@ gtk_widget_notify_class_action_state (GtkWidget  *widget,
   muxer = _gtk_widget_get_action_muxer (widget, TRUE);
   gtk_action_muxer_action_state_changed (muxer, action_name, state);
 }
+
+void
+gtk_widget_class_set_accels_for_actionv (GtkWidgetClass     *widget_class,
+                                         const char         *detailed_action_name,
+                                         const char * const *accelerators)
+{
+  GtkWidgetClassPrivate *priv = widget_class->priv;
+
+  if (priv->accels == NULL)
+    priv->accels = gtk_application_accels_new ();
+
+  gtk_application_accels_set_accels_for_action (priv->accels,
+                                                detailed_action_name,
+                                                accelerators);
+}
+
+void
+gtk_widget_class_set_accels_for_action (GtkWidgetClass *widget_class,
+                                        const char     *detailed_action_name,
+                                        ...)
+{
+  va_list var_args;
+  GPtrArray *accels;
+
+  accels = g_ptr_array_sized_new (4);
+
+  va_start (var_args, detailed_action_name);
+  while (TRUE)
+    {
+      char *arg = va_arg (var_args, char *);
+
+      if (arg == NULL)
+        break;
+
+      g_ptr_array_add (accels, arg);
+    }
+  va_end (var_args);
+  g_ptr_array_add (accels, NULL);
+
+  gtk_widget_class_set_accels_for_actionv (widget_class,
+                                           detailed_action_name,
+                                           (const char * const *)accels->pdata);
+
+  g_ptr_array_free (accels, TRUE);
+}
+
+static gboolean
+gtk_widget_activate_accels (GtkWidget      *widget,
+                            const GdkEvent *event)
+{
+  GtkWidgetClass *class = GTK_WIDGET_GET_CLASS (widget);
+  GtkWidgetClassPrivate *priv = class->priv;
+  GtkApplicationAccels *accels = priv->accels;
+  GtkActionMuxer *muxer;
+  guint keyval;
+  GdkModifierType modifiers;
+
+  if (!accels)
+    return FALSE;
+
+  muxer = _gtk_widget_get_action_muxer (widget, FALSE);
+  if (!muxer)
+    return FALSE;
+
+  gdk_event_get_keyval ((GdkEvent *)event, &keyval);
+  gdk_event_get_state ((GdkEvent *)event, &modifiers);
+
+  return gtk_application_accels_activate (accels,
+                                          G_ACTION_GROUP (muxer),
+                                          keyval, modifiers);
+}
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index 618aeca883..854ce2b52e 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -1092,6 +1092,15 @@ void                    gtk_widget_notify_class_action_state (GtkWidget  *widget
                                                               const char *action_name,
                                                               GVariant   *state);
 
+GDK_AVAILABLE_IN_ALL
+void                    gtk_widget_class_set_accels_for_actionv (GtkWidgetClass     *widget_class,
+                                                                 const char         *detailed_action_name,
+                                                                 const char * const *accelerators);
+
+GDK_AVAILABLE_IN_ALL
+void                    gtk_widget_class_set_accels_for_action (GtkWidgetClass     *widget_class,
+                                                                const char         *detailed_action_name,
+                                                                ...);
 
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkWidget, g_object_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRequisition, gtk_requisition_free)


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