[gtk+/composite-templates] GtkAccelLabel: add manual accel API



commit 34c54ca34d71d9dc398a90c29abfb21fdf4a52fc
Author: Ryan Lortie <desrt desrt ca>
Date:   Mon Sep 10 14:36:23 2012 -0400

    GtkAccelLabel: add manual accel API
    
    Add an API to GtkAccelLabel for hardcoding the accel key to be displayed
    (ie: allowing us to bypass the GtkAccelGroup lookup).
    
    Use that from the GMenuModel-based GtkMenu construction code instead of
    passing around the accel group.
    
    This makes accel labels work in bloatpad again.
    
    This patch effectively removes any hope of automatic runtime accel
    changes in GMenuModel-based menus without additional application
    support but it leaves the door open for this to be supported again in
    the future (if we decide that it's important).
    
    https://bugzilla.gnome.org/show_bug.cgi?id=683738

 gtk/gtk.symbols            |    1 +
 gtk/gtkaccellabel.c        |   54 +++++++++++++++++++++++++++++++++++++++-----
 gtk/gtkaccellabel.h        |    4 +++
 gtk/gtkapplicationwindow.c |    2 +-
 gtk/gtkmodelmenu.c         |   24 ++++++-------------
 gtk/gtkmodelmenu.h         |    6 +---
 gtk/gtkmodelmenuitem.c     |   33 +++++++++++++++++++++-----
 gtk/gtkmodelmenuitem.h     |    3 +-
 8 files changed, 91 insertions(+), 36 deletions(-)
---
diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols
index 614f528..40d3a31 100644
--- a/gtk/gtk.symbols
+++ b/gtk/gtk.symbols
@@ -65,6 +65,7 @@ gtk_accel_label_get_accel_width
 gtk_accel_label_get_type
 gtk_accel_label_new
 gtk_accel_label_refetch
+gtk_accel_label_set_accel
 gtk_accel_label_set_accel_closure
 gtk_accel_label_set_accel_widget
 gtk_accel_map_add_entry
diff --git a/gtk/gtkaccellabel.c b/gtk/gtkaccellabel.c
index 452f43c..d374faa 100644
--- a/gtk/gtkaccellabel.c
+++ b/gtk/gtkaccellabel.c
@@ -104,6 +104,9 @@ struct _GtkAccelLabelPrivate
   gchar         *accel_string;       /* has set function */
   guint          accel_padding;      /* should be style property? */
   guint16        accel_string_width; /* seems to be private */
+
+  guint           accel_key;         /* manual accel key specification if != 0 */
+  GdkModifierType accel_mods;
 };
 
 static void         gtk_accel_label_set_property (GObject            *object,
@@ -903,19 +906,31 @@ gtk_accel_label_refetch (GtkAccelLabel *accel_label)
                 "gtk-enable-accels", &enable_accels,
                 NULL);
 
-  if (enable_accels && accel_label->priv->accel_closure)
+  if (enable_accels && (accel_label->priv->accel_closure || accel_label->priv->accel_key))
     {
-      GtkAccelKey *key = gtk_accel_group_find (accel_label->priv->accel_group, find_accel, accel_label->priv->accel_closure);
+      guint accel_key = accel_label->priv->accel_key;
+      GdkModifierType accel_mods = accel_label->priv->accel_mods;
+
+      /* If we don't have a hardcoded value, check the accel group */
+      if (!accel_key)
+        {
+          GtkAccelKey *key = gtk_accel_group_find (accel_label->priv->accel_group, find_accel, accel_label->priv->accel_closure);
+
+          if (key && key->accel_flags & GTK_ACCEL_VISIBLE)
+            {
+              accel_key = key->accel_key;
+              accel_mods = key->accel_mods;
+            }
+        }
 
-      if (key && key->accel_flags & GTK_ACCEL_VISIBLE)
+      /* If we found a key using either method, set it */
+      if (accel_key)
 	{
 	  GtkAccelLabelClass *klass;
 	  gchar *tmp;
 
 	  klass = GTK_ACCEL_LABEL_GET_CLASS (accel_label);
-	  tmp = _gtk_accel_label_class_get_accelerator_label (klass,
-							      key->accel_key,
-							      key->accel_mods);
+	  tmp = _gtk_accel_label_class_get_accelerator_label (klass, accel_key, accel_mods);
 	  accel_label->priv->accel_string = g_strconcat ("   ", tmp, NULL);
 	  g_free (tmp);
 	}
@@ -930,3 +945,30 @@ gtk_accel_label_refetch (GtkAccelLabel *accel_label)
 
   return FALSE;
 }
+
+/**
+ * gtk_accel_label_set_accel:
+ * @accel_label: a #GtkAccelLabel
+ * @accelerator_key: a keyval, or 0
+ * @accelerator_mods: the modifier mask for the accel
+ *
+ * Manually sets a keyval and modifier mask as the accelerator rendered
+ * by @accel_label.
+ *
+ * If a keyval and modifier are explicitly set then these values are
+ * used regardless of any associated accel closure or widget.
+ *
+ * Providing an @accelerator_key of 0 removes the manual setting.
+ *
+ * Since: 3.6
+ */
+void
+gtk_accel_label_set_accel (GtkAccelLabel   *accel_label,
+                           guint            accelerator_key,
+                           GdkModifierType  accelerator_mods)
+{
+  accel_label->priv->accel_key = accelerator_key;
+  accel_label->priv->accel_mods = accelerator_mods;
+
+  gtk_accel_label_reset (accel_label);
+}
diff --git a/gtk/gtkaccellabel.h b/gtk/gtkaccellabel.h
index a1a9e02..bf247f1 100644
--- a/gtk/gtkaccellabel.h
+++ b/gtk/gtkaccellabel.h
@@ -90,6 +90,10 @@ void	   gtk_accel_label_set_accel_widget  (GtkAccelLabel *accel_label,
 void	   gtk_accel_label_set_accel_closure (GtkAccelLabel *accel_label,
 					      GClosure	    *accel_closure);
 gboolean   gtk_accel_label_refetch           (GtkAccelLabel *accel_label);
+GDK_AVAILABLE_IN_3_6
+void       gtk_accel_label_set_accel         (GtkAccelLabel   *accel_label,
+                                              guint            accelerator_key,
+                                              GdkModifierType  accelerator_mods);
 
 /* private */
 gchar *    _gtk_accel_label_class_get_accelerator_label (GtkAccelLabelClass *klass,
diff --git a/gtk/gtkapplicationwindow.c b/gtk/gtkapplicationwindow.c
index 4c4eadc..0632bed 100644
--- a/gtk/gtkapplicationwindow.c
+++ b/gtk/gtkapplicationwindow.c
@@ -256,7 +256,7 @@ gtk_application_window_update_menubar (GtkApplicationWindow *window)
       g_menu_append_section (combined, NULL, G_MENU_MODEL (window->priv->app_menu_section));
       g_menu_append_section (combined, NULL, G_MENU_MODEL (window->priv->menubar_section));
 
-      window->priv->menubar = gtk_model_menu_create_menu_bar (G_MENU_MODEL (combined), window->priv->accels);
+      window->priv->menubar = gtk_model_menu_create_menu_bar (G_MENU_MODEL (combined));
       gtk_widget_set_parent (window->priv->menubar, GTK_WIDGET (window));
       gtk_widget_show_all (window->priv->menubar);
       g_object_unref (combined);
diff --git a/gtk/gtkmodelmenu.c b/gtk/gtkmodelmenu.c
index bb6a711..f2174dd 100644
--- a/gtk/gtkmodelmenu.c
+++ b/gtk/gtkmodelmenu.c
@@ -33,7 +33,6 @@
 
 typedef struct {
   GMenuModel        *model;
-  GtkAccelGroup     *accels;
   GtkMenuShell      *shell;
   guint              update_idle;
   GSList            *connected;
@@ -107,7 +106,7 @@ gtk_model_menu_binding_append_item (GtkModelMenuBinding  *binding,
     {
       GtkMenuItem *item;
 
-      item = gtk_model_menu_item_new (model, item_index, action_namespace, binding->accels);
+      item = gtk_model_menu_item_new (model, item_index, action_namespace);
       gtk_menu_shell_append (binding->shell, GTK_WIDGET (item));
       gtk_widget_show (GTK_WIDGET (item));
       binding->n_items++;
@@ -254,7 +253,6 @@ gtk_model_menu_bind (GtkMenuShell *shell,
 
   binding = g_slice_new (GtkModelMenuBinding);
   binding->model = g_object_ref (model);
-  binding->accels = NULL;
   binding->shell = shell;
   binding->update_idle = 0;
   binding->connected = NULL;
@@ -266,30 +264,25 @@ gtk_model_menu_bind (GtkMenuShell *shell,
 
 
 static void
-gtk_model_menu_populate (GtkMenuShell  *shell,
-                         GtkAccelGroup *accels)
+gtk_model_menu_populate (GtkMenuShell *shell)
 {
   GtkModelMenuBinding *binding;
 
   binding = (GtkModelMenuBinding*) g_object_get_data (G_OBJECT (shell), "gtk-model-menu-binding");
 
-  binding->accels = accels;
-
   gtk_model_menu_binding_populate (binding);
 }
 
 GtkWidget *
 gtk_model_menu_create_menu (GMenuModel    *model,
-                            const gchar   *action_namespace,
-                            GtkAccelGroup *accels)
+                            const gchar   *action_namespace)
 {
   GtkWidget *menu;
 
   menu = gtk_menu_new ();
-  gtk_menu_set_accel_group (GTK_MENU (menu), accels);
 
   gtk_model_menu_bind (GTK_MENU_SHELL (menu), model, action_namespace, TRUE);
-  gtk_model_menu_populate (GTK_MENU_SHELL (menu), accels);
+  gtk_model_menu_populate (GTK_MENU_SHELL (menu));
 
   return menu;
 }
@@ -317,21 +310,20 @@ gtk_menu_new_from_model (GMenuModel *model)
 
   menu = gtk_menu_new ();
   gtk_model_menu_bind (GTK_MENU_SHELL (menu), model, NULL, TRUE);
-  gtk_model_menu_populate (GTK_MENU_SHELL (menu), NULL);
+  gtk_model_menu_populate (GTK_MENU_SHELL (menu));
 
   return menu;
 }
 
 GtkWidget *
-gtk_model_menu_create_menu_bar (GMenuModel    *model,
-                                GtkAccelGroup *accels)
+gtk_model_menu_create_menu_bar (GMenuModel *model)
 {
   GtkWidget *menubar;
 
   menubar = gtk_menu_bar_new ();
 
   gtk_model_menu_bind (GTK_MENU_SHELL (menubar), model, NULL, FALSE);
-  gtk_model_menu_populate (GTK_MENU_SHELL (menubar), accels);
+  gtk_model_menu_populate (GTK_MENU_SHELL (menubar));
 
   return menubar;
 }
@@ -360,7 +352,7 @@ gtk_menu_bar_new_from_model (GMenuModel *model)
   menubar = gtk_menu_bar_new ();
 
   gtk_model_menu_bind (GTK_MENU_SHELL (menubar), model, NULL, FALSE);
-  gtk_model_menu_populate (GTK_MENU_SHELL (menubar), NULL);
+  gtk_model_menu_populate (GTK_MENU_SHELL (menubar));
 
   return menubar;
 }
diff --git a/gtk/gtkmodelmenu.h b/gtk/gtkmodelmenu.h
index 1bc27be..a27c7bd 100644
--- a/gtk/gtkmodelmenu.h
+++ b/gtk/gtkmodelmenu.h
@@ -25,12 +25,10 @@
 #include <gio/gio.h>
 
 G_GNUC_INTERNAL
-GtkWidget * gtk_model_menu_create_menu_bar (GMenuModel        *model,
-                                            GtkAccelGroup     *accels);
+GtkWidget * gtk_model_menu_create_menu_bar (GMenuModel        *model);
 
 G_GNUC_INTERNAL
 GtkWidget * gtk_model_menu_create_menu     (GMenuModel        *model,
-                                            const gchar       *action_namespace,
-                                            GtkAccelGroup     *accels);
+                                            const gchar       *action_namespace);
 
 #endif /* __GTK_MODEL_MENU_H__ */
diff --git a/gtk/gtkmodelmenuitem.c b/gtk/gtkmodelmenuitem.c
index 450cd9a..61e10e5 100644
--- a/gtk/gtkmodelmenuitem.c
+++ b/gtk/gtkmodelmenuitem.c
@@ -25,6 +25,7 @@
 #include "gtkactionhelper.h"
 #include "gtkmodelmenu.h"
 #include "gtkwidgetprivate.h"
+#include "gtkaccellabel.h"
 
 struct _GtkModelMenuItem
 {
@@ -107,8 +108,7 @@ static void
 gtk_model_menu_item_setup (GtkModelMenuItem  *item,
                            GMenuModel        *model,
                            gint               item_index,
-                           const gchar       *action_namespace,
-                           GtkAccelGroup     *accels)
+                           const gchar       *action_namespace)
 {
   GMenuAttributeIter *iter;
   GMenuModel *submenu;
@@ -125,12 +125,12 @@ gtk_model_menu_item_setup (GtkModelMenuItem  *item,
       if (action_namespace)
         {
           gchar *namespace = g_strjoin (".", action_namespace, section_namespace, NULL);
-          menu = gtk_model_menu_create_menu (submenu, namespace, accels);
+          menu = gtk_model_menu_create_menu (submenu, namespace);
           g_free (namespace);
         }
       else
         {
-          menu = gtk_model_menu_create_menu (submenu, section_namespace, accels);
+          menu = gtk_model_menu_create_menu (submenu, section_namespace);
         }
 
       gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), menu);
@@ -145,6 +145,26 @@ gtk_model_menu_item_setup (GtkModelMenuItem  *item,
       if (g_str_equal (key, "label") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
         gtk_menu_item_set_label (GTK_MENU_ITEM (item), g_variant_get_string (value, NULL));
 
+      else if (g_str_equal (key, "accel") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
+        {
+          GdkModifierType modifiers;
+          guint key;
+
+          gtk_accelerator_parse (g_variant_get_string (value, NULL), &key, &modifiers);
+
+          if (key)
+            {
+              GtkAccelLabel *accel_label;
+
+              /* Ensure that the GtkAccelLabel has been created... */
+              (void) gtk_menu_item_get_label (GTK_MENU_ITEM (item));
+              accel_label = GTK_ACCEL_LABEL (gtk_bin_get_child (GTK_BIN (item)));
+              g_assert (accel_label);
+
+              gtk_accel_label_set_accel (accel_label, key, modifiers);
+            }
+        }
+
       else if (g_str_equal (key, "action") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
         gtk_actionable_set_namespaced_action_name (GTK_ACTIONABLE (item), action_namespace,
                                                    g_variant_get_string (value, NULL));
@@ -260,14 +280,13 @@ gtk_model_menu_item_class_init (GtkModelMenuItemClass *class)
 GtkMenuItem *
 gtk_model_menu_item_new (GMenuModel        *model,
                          gint               item_index,
-                         const gchar       *action_namespace,
-                         GtkAccelGroup     *accels)
+                         const gchar       *action_namespace)
 {
   GtkModelMenuItem *item;
 
   item = g_object_new (GTK_TYPE_MODEL_MENU_ITEM, NULL);
 
-  gtk_model_menu_item_setup (item, model, item_index, action_namespace, accels);
+  gtk_model_menu_item_setup (item, model, item_index, action_namespace);
 
   return GTK_MENU_ITEM (item);
 }
diff --git a/gtk/gtkmodelmenuitem.h b/gtk/gtkmodelmenuitem.h
index 9e35327..655f073 100644
--- a/gtk/gtkmodelmenuitem.h
+++ b/gtk/gtkmodelmenuitem.h
@@ -36,7 +36,6 @@ GType                   gtk_model_menu_item_get_type                    (void) G
 G_GNUC_INTERNAL
 GtkMenuItem *           gtk_model_menu_item_new                         (GMenuModel        *model,
                                                                          gint               item_index,
-                                                                         const gchar       *action_namespace,
-                                                                         GtkAccelGroup     *accels);
+                                                                         const gchar       *action_namespace);
 
 #endif /* __GTK_MODEL_MENU_ITEM_H__ */



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