mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-05 16:20:10 +00:00
GtkApplication: Extract accelerators from menus
This allows to specify accelerators in a convenient way, by adding accel="..." attributes to the menu items in the XML for the menu. Currently, the accelerators are extracted only once, when the menu property is changed on the application.
This commit is contained in:
parent
2398d7e900
commit
f7244431a9
@ -347,11 +347,89 @@ gtk_application_window_removed (GtkApplication *application,
|
||||
gtk_window_set_application (window, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
extract_accel_from_menu_item (GMenuModel *model,
|
||||
gint item,
|
||||
GtkApplication *app)
|
||||
{
|
||||
GMenuAttributeIter *iter;
|
||||
const gchar *key;
|
||||
GVariant *value;
|
||||
const gchar *accel = NULL;
|
||||
const gchar *action = NULL;
|
||||
GVariant *target = NULL;
|
||||
|
||||
iter = g_menu_model_iterate_item_attributes (model, item);
|
||||
while (g_menu_attribute_iter_get_next (iter, &key, &value))
|
||||
{
|
||||
if (g_str_equal (key, "action") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
|
||||
action = g_variant_get_string (value, NULL);
|
||||
else if (g_str_equal (key, "accel") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
|
||||
accel = g_variant_get_string (value, NULL);
|
||||
else if (g_str_equal (key, "target"))
|
||||
target = g_variant_ref (value);
|
||||
g_variant_unref (value);
|
||||
}
|
||||
g_object_unref (iter);
|
||||
|
||||
if (accel && action)
|
||||
gtk_application_add_accelerator (app, accel, action, target);
|
||||
|
||||
if (target)
|
||||
g_variant_unref (target);
|
||||
}
|
||||
|
||||
static void
|
||||
extract_accels_from_menu (GMenuModel *model,
|
||||
GtkApplication *app)
|
||||
{
|
||||
gint i;
|
||||
GMenuLinkIter *iter;
|
||||
const gchar *key;
|
||||
GMenuModel *m;
|
||||
|
||||
for (i = 0; i < g_menu_model_get_n_items (model); i++)
|
||||
{
|
||||
extract_accel_from_menu_item (model, i, app);
|
||||
|
||||
iter = g_menu_model_iterate_item_links (model, i);
|
||||
while (g_menu_link_iter_get_next (iter, &key, &m))
|
||||
{
|
||||
extract_accels_from_menu (m, app);
|
||||
g_object_unref (m);
|
||||
}
|
||||
g_object_unref (iter);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_application_notify (GObject *object,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
if (strcmp (pspec->name, "app-menu") == 0 ||
|
||||
strcmp (pspec->name, "menubar") == 0)
|
||||
{
|
||||
GMenuModel *model;
|
||||
g_object_get (object, pspec->name, &model, NULL);
|
||||
if (model)
|
||||
{
|
||||
extract_accels_from_menu (model, GTK_APPLICATION (object));
|
||||
g_object_unref (model);
|
||||
}
|
||||
}
|
||||
|
||||
if (G_OBJECT_CLASS (gtk_application_parent_class)->notify)
|
||||
G_OBJECT_CLASS (gtk_application_parent_class)->notify (object, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_application_class_init (GtkApplicationClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GApplicationClass *application_class = G_APPLICATION_CLASS (class);
|
||||
|
||||
object_class->notify = gtk_application_notify;
|
||||
|
||||
application_class->add_platform_data = gtk_application_add_platform_data;
|
||||
application_class->before_emit = gtk_application_before_emit;
|
||||
application_class->after_emit = gtk_application_after_emit;
|
||||
|
Loading…
Reference in New Issue
Block a user