[gtk+] GtkAccelLabel: add manual accel API
- From: Ryan Lortie <ryanl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] GtkAccelLabel: add manual accel API
- Date: Mon, 17 Sep 2012 16:34:57 +0000 (UTC)
commit 778aa7ade0107fa645ab1427132551d138c7334a
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]