static gboolean snooper_loopkup_keys_in_accel_map(GdkEventKey *kevent, Tbfwin *bfwin) { gpointer retval; retval = bfwin->accel_group ? gtk_accel_group_find( bfwin->accel_group, snooper_accel_group_find_func, kevent ) : NULL; DEBUG_MSG("snooper: lookup in accel.map (1)\n" ); if (!retval) { DEBUG_MSG("snooper: lookup in accel.map (2)\n" ); retval = bfwin->accel_group2 ? gtk_accel_group_find( bfwin->accel_group2, snooper_accel_group_find_func, kevent ) : NULL; } #ifdef DEBUG gchar *tmpstr = snooper_parse_key(kevent); DEBUG_MSG("snooper: lookup '%s' in accel.map, return %p\n", tmpstr, retval); g_free(tmpstr); #endif /* DEBUG */ return retval != NULL; }
void dt_accel_rename_global(const gchar *path,const gchar *new_path) { dt_accel_t *accel; GSList * l = darktable.control->accelerator_list; char build_path[1024]; dt_accel_path_global(build_path, 1024,path); while(l) { accel = (dt_accel_t*)l->data; if(!strncmp(accel->path, build_path, 1024)) { GtkAccelKey tmp_key = *(gtk_accel_group_find(darktable.control->accelerators,find_accel_internal,accel->closure)); dt_accel_deregister_global(path); g_closure_ref(accel->closure); dt_accel_register_global(new_path,tmp_key.accel_key,tmp_key.accel_mods); dt_accel_connect_global(new_path,accel->closure); g_closure_unref(accel->closure); l = NULL; } else { l = g_slist_next(l); } } }
void dt_accel_rename_preset_iop(dt_iop_module_t *module,const gchar *path,const gchar *new_path) { dt_accel_t *accel; GSList * l = module->accel_closures; char build_path[1024]; dt_accel_path_iop(build_path, 1024, module->op, path); while(l) { accel = (dt_accel_t*)l->data; if(!strncmp(accel->path, build_path, 1024)) { GtkAccelKey tmp_key = *(gtk_accel_group_find(darktable.control->accelerators,find_accel_internal,accel->closure)); gboolean local = accel->local; dt_accel_deregister_iop(module,path); snprintf(build_path,1024,"%s/%s",_("preset"),new_path); dt_accel_register_iop(module->so,local,build_path,tmp_key.accel_key,tmp_key.accel_mods); dt_accel_connect_preset_iop(module,new_path); l = NULL; } else { l = g_slist_next(l); } } }
void EvalCcRqREMOVEMENUSHORTKEY (CrossCallInfo *pcci) /* frameptr, cmd; no result. */ { GtkWidget *frame; GtkWidget *box; GtkWidget *menu_item; GtkAccelGroup *accel_group; printf("EvalCcRqREMOVEMENUSHORTKEY\n"); frame = GTK_WIDGET(pcci->p1); menu_item = GTK_WIDGET(pcci->p2); accel_group = ((GtkAccelGroup*)gtk_accel_groups_from_object(G_OBJECT(frame))->data); for (;;) { GtkAccelKey *key = gtk_accel_group_find(accel_group, dummy_find_accel, NULL); if (!key) break; gtk_widget_remove_accelerator(menu_item, accel_group, key->accel_key, key->accel_mods); } MakeReturn0Cci (pcci); }
static void gimp_widget_accel_changed (GtkAccelGroup *accel_group, guint unused1, GdkModifierType unused2, GClosure *accel_closure, GtkWidget *widget) { GClosure *widget_closure; widget_closure = g_object_get_data (G_OBJECT (widget), "gimp-accel-closure"); if (accel_closure == widget_closure) { GtkAction *action; GtkAccelKey *accel_key; gchar *orig_tooltip; gchar *tooltip; const gchar *help_id; action = g_object_get_data (G_OBJECT (widget), "gimp-accel-action"); g_object_get (action, "tooltip", &orig_tooltip, NULL); help_id = g_object_get_qdata (G_OBJECT (action), GIMP_HELP_ID); accel_key = gtk_accel_group_find (accel_group, gimp_widget_accel_find_func, accel_closure); if (accel_key && accel_key->accel_key && accel_key->accel_flags & GTK_ACCEL_VISIBLE) { gchar *accel = gtk_accelerator_get_label (accel_key->accel_key, accel_key->accel_mods); tooltip = g_strdup_printf ("%s (%s)", orig_tooltip, accel); g_free (accel); } else { tooltip = g_strdup (orig_tooltip); } gimp_help_set_help_data (widget, tooltip, help_id); g_free (tooltip); g_free (orig_tooltip); } }
static void gimp_widget_accel_changed (GtkAccelGroup *accel_group, guint unused1, GdkModifierType unused2, GClosure *accel_closure, GtkWidget *widget) { GClosure *widget_closure; widget_closure = g_object_get_data (G_OBJECT (widget), "gimp-accel-closure"); if (accel_closure == widget_closure) { GtkAction *action; GtkAccelKey *accel_key; const gchar *tooltip; const gchar *help_id; action = g_object_get_data (G_OBJECT (widget), "gimp-accel-action"); tooltip = gtk_action_get_tooltip (action); help_id = g_object_get_qdata (G_OBJECT (action), GIMP_HELP_ID); accel_key = gtk_accel_group_find (accel_group, gimp_widget_accel_find_func, accel_closure); if (accel_key && accel_key->accel_key && accel_key->accel_flags & GTK_ACCEL_VISIBLE) { gchar *escaped = g_markup_escape_text (tooltip, -1); gchar *accel = gtk_accelerator_get_label (accel_key->accel_key, accel_key->accel_mods); gchar *tmp = g_strdup_printf ("%s <b>%s</b>", escaped, accel); g_free (accel); g_free (escaped); gimp_help_set_help_data_with_markup (widget, tmp, help_id); g_free (tmp); } else { gimp_help_set_help_data (widget, tooltip, help_id); } } }
/** * dbusmenu_menuitem_property_set_shortcut_menuitem: * @menuitem: The #DbusmenuMenuitem to set the shortcut on * @gmi: A menu item to steal the shortcut off of * * Takes the shortcut that is installed on a menu item and calls * #dbusmenu_menuitem_property_set_shortcut with it. It also sets * up listeners to watch it change. * * Return value: Whether it was successful at setting the property. */ gboolean dbusmenu_menuitem_property_set_shortcut_menuitem (DbusmenuMenuitem * menuitem, const GtkMenuItem * gmi) { g_return_val_if_fail(DBUSMENU_IS_MENUITEM(menuitem), FALSE); g_return_val_if_fail(GTK_IS_MENU_ITEM(gmi), FALSE); GClosure * closure = NULL; GtkWidget *label = gtk_bin_get_child(GTK_BIN (gmi)); if (GTK_IS_ACCEL_LABEL (label)) { g_object_get (label, "accel-closure", &closure, NULL); } if (closure == NULL) { /* As a fallback, check for a closure in the related menu item. This actually happens with SWT menu items. */ GList * closures = gtk_widget_list_accel_closures (GTK_WIDGET (gmi)); if (closures == NULL) return FALSE; closure = closures->data; g_list_free (closures); } GtkAccelGroup * group = gtk_accel_group_from_accel_closure(closure); /* Apparently this is more common than I thought. */ if (group == NULL) { return FALSE; } GtkAccelKey * key = gtk_accel_group_find(group, find_closure, closure); /* Again, not much we can do except complain loudly. */ g_return_val_if_fail(key != NULL, FALSE); if (!gtk_accelerator_valid (key->accel_key, key->accel_mods)) return FALSE; return dbusmenu_menuitem_property_set_shortcut(menuitem, key->accel_key, key->accel_mods); }
void debug_dump_keyboard_shortcuts_cmd_callback (GtkAction *action, gpointer data) { GimpDisplay *display; GimpImageWindow *window; GtkUIManager *manager; GtkAccelGroup *accel_group; GList *group_it; GList *strings = NULL; return_if_no_display (display, data); window = gimp_display_shell_get_window (gimp_display_get_shell (display)); manager = GTK_UI_MANAGER (gimp_image_window_get_ui_manager (window)); accel_group = gtk_ui_manager_get_accel_group (manager); /* Gather formated strings of keyboard shortcuts */ for (group_it = gtk_ui_manager_get_action_groups (manager); group_it; group_it = g_list_next (group_it)) { GimpActionGroup *group = group_it->data; GList *actions = NULL; GList *action_it = NULL; actions = gtk_action_group_list_actions (GTK_ACTION_GROUP (group)); actions = g_list_sort (actions, (GCompareFunc) gimp_action_name_compare); for (action_it = actions; action_it; action_it = g_list_next (action_it)) { GtkAction *action = action_it->data; const gchar *name = gtk_action_get_name (action); GClosure *accel_closure = NULL; if (strstr (name, "-menu") || strstr (name, "-popup") || name[0] == '<') continue; accel_closure = gtk_action_get_accel_closure (action); if (accel_closure) { GtkAccelKey *key = gtk_accel_group_find (accel_group, debug_accel_find_func, accel_closure); if (key && key->accel_key && key->accel_flags & GTK_ACCEL_VISIBLE) { const gchar *label_tmp; gchar *label; gchar *key_string; label_tmp = gtk_action_get_label (action); label = gimp_strip_uline (label_tmp); key_string = gtk_accelerator_get_label (key->accel_key, key->accel_mods); strings = g_list_prepend (strings, g_strdup_printf ("%-20s %s", key_string, label)); g_free (key_string); g_free (label); } } } g_list_free (actions); } /* Sort and prints the strings */ { GList *string_it = NULL; strings = g_list_sort (strings, (GCompareFunc) strcmp); for (string_it = strings; string_it; string_it = g_list_next (string_it)) { g_print ("%s\n", (gchar *) string_it->data); g_free (string_it->data); } g_list_free (strings); } }
static void gimp_action_view_accel_changed (GtkAccelGroup *accel_group, guint unused1, GdkModifierType unused2, GClosure *accel_closure, GimpActionView *view) { GtkTreeModel *model; GtkTreeIter iter; gboolean iter_valid; model = gtk_tree_view_get_model (GTK_TREE_VIEW (view)); if (! model) return; model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model)); if (! model) return; for (iter_valid = gtk_tree_model_get_iter_first (model, &iter); iter_valid; iter_valid = gtk_tree_model_iter_next (model, &iter)) { GtkTreeIter child_iter; gboolean child_valid; for (child_valid = gtk_tree_model_iter_children (model, &child_iter, &iter); child_valid; child_valid = gtk_tree_model_iter_next (model, &child_iter)) { GClosure *closure; gtk_tree_model_get (model, &child_iter, GIMP_ACTION_VIEW_COLUMN_ACCEL_CLOSURE, &closure, -1); if (closure) g_closure_unref (closure); if (accel_closure == closure) { GtkAccelKey *key; guint accel_key = 0; GdkModifierType accel_mask = 0; key = gtk_accel_group_find (accel_group, gimp_action_view_accel_find_func, accel_closure); if (key && key->accel_key && key->accel_flags & GTK_ACCEL_VISIBLE) { accel_key = key->accel_key; accel_mask = key->accel_mods; } gtk_tree_store_set (GTK_TREE_STORE (model), &child_iter, GIMP_ACTION_VIEW_COLUMN_ACCEL_KEY, accel_key, GIMP_ACTION_VIEW_COLUMN_ACCEL_MASK, accel_mask, -1); return; } } } }
GtkWidget * gimp_action_view_new (GimpUIManager *manager, const gchar *select_action, gboolean show_shortcuts) { GtkTreeView *view; GtkTreeViewColumn *column; GtkCellRenderer *cell; GtkTreeStore *store; GtkTreeModel *filter; GtkAccelGroup *accel_group; GList *list; GtkTreePath *select_path = NULL; g_return_val_if_fail (GIMP_IS_UI_MANAGER (manager), NULL); store = gtk_tree_store_new (GIMP_ACTION_VIEW_N_COLUMNS, G_TYPE_BOOLEAN, /* COLUMN_VISIBLE */ GTK_TYPE_ACTION, /* COLUMN_ACTION */ G_TYPE_STRING, /* COLUMN_STOCK_ID */ G_TYPE_STRING, /* COLUMN_LABEL */ G_TYPE_STRING, /* COLUMN_LABEL_CASEFOLD */ G_TYPE_STRING, /* COLUMN_NAME */ G_TYPE_UINT, /* COLUMN_ACCEL_KEY */ GDK_TYPE_MODIFIER_TYPE, /* COLUMN_ACCEL_MASK */ G_TYPE_CLOSURE); /* COLUMN_ACCEL_CLOSURE */ accel_group = gtk_ui_manager_get_accel_group (GTK_UI_MANAGER (manager)); for (list = gtk_ui_manager_get_action_groups (GTK_UI_MANAGER (manager)); list; list = g_list_next (list)) { GimpActionGroup *group = list->data; GList *actions; GList *list2; GtkTreeIter group_iter; gtk_tree_store_append (store, &group_iter, NULL); gtk_tree_store_set (store, &group_iter, GIMP_ACTION_VIEW_COLUMN_STOCK_ID, group->stock_id, GIMP_ACTION_VIEW_COLUMN_LABEL, group->label, -1); actions = gtk_action_group_list_actions (GTK_ACTION_GROUP (group)); actions = g_list_sort (actions, (GCompareFunc) gimp_action_name_compare); for (list2 = actions; list2; list2 = g_list_next (list2)) { GtkAction *action = list2->data; const gchar *name = gtk_action_get_name (action); const gchar *stock_id = gtk_action_get_stock_id (action); gchar *label; gchar *label_casefold; guint accel_key = 0; GdkModifierType accel_mask = 0; GClosure *accel_closure = NULL; GtkTreeIter action_iter; if (strstr (name, "-menu") || strstr (name, "-popup") || name[0] == '<') continue; label = gimp_strip_uline (gtk_action_get_label (action)); if (! (label && strlen (label))) { g_free (label); label = g_strdup (name); } label_casefold = g_utf8_casefold (label, -1); if (show_shortcuts) { accel_closure = gtk_action_get_accel_closure (action); if (accel_closure) { GtkAccelKey *key; key = gtk_accel_group_find (accel_group, gimp_action_view_accel_find_func, accel_closure); if (key && key->accel_key && key->accel_flags & GTK_ACCEL_VISIBLE) { accel_key = key->accel_key; accel_mask = key->accel_mods; } } } gtk_tree_store_append (store, &action_iter, &group_iter); gtk_tree_store_set (store, &action_iter, GIMP_ACTION_VIEW_COLUMN_VISIBLE, TRUE, GIMP_ACTION_VIEW_COLUMN_ACTION, action, GIMP_ACTION_VIEW_COLUMN_STOCK_ID, stock_id, GIMP_ACTION_VIEW_COLUMN_LABEL, label, GIMP_ACTION_VIEW_COLUMN_LABEL_CASEFOLD, label_casefold, GIMP_ACTION_VIEW_COLUMN_NAME, name, GIMP_ACTION_VIEW_COLUMN_ACCEL_KEY, accel_key, GIMP_ACTION_VIEW_COLUMN_ACCEL_MASK, accel_mask, GIMP_ACTION_VIEW_COLUMN_ACCEL_CLOSURE, accel_closure, -1); g_free (label); g_free (label_casefold); if (select_action && ! strcmp (select_action, name)) { select_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &action_iter); } } g_list_free (actions); } filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL); g_object_unref (store); view = g_object_new (GIMP_TYPE_ACTION_VIEW, "model", filter, "rules-hint", TRUE, NULL); g_object_unref (filter); gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter), GIMP_ACTION_VIEW_COLUMN_VISIBLE); GIMP_ACTION_VIEW (view)->manager = g_object_ref (manager); GIMP_ACTION_VIEW (view)->show_shortcuts = show_shortcuts; gtk_tree_view_set_search_column (GTK_TREE_VIEW (view), GIMP_ACTION_VIEW_COLUMN_LABEL); column = gtk_tree_view_column_new (); gtk_tree_view_column_set_title (column, _("Action")); cell = gtk_cell_renderer_pixbuf_new (); gtk_tree_view_column_pack_start (column, cell, FALSE); gtk_tree_view_column_set_attributes (column, cell, "stock-id", GIMP_ACTION_VIEW_COLUMN_STOCK_ID, NULL); cell = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, cell, TRUE); gtk_tree_view_column_set_attributes (column, cell, "text", GIMP_ACTION_VIEW_COLUMN_LABEL, NULL); gtk_tree_view_append_column (view, column); if (show_shortcuts) { g_signal_connect (view, "button-press-event", G_CALLBACK (gimp_action_view_button_press), NULL); g_signal_connect (accel_group, "accel-changed", G_CALLBACK (gimp_action_view_accel_changed), view); column = gtk_tree_view_column_new (); gtk_tree_view_column_set_title (column, _("Shortcut")); cell = gtk_cell_renderer_accel_new (); g_object_set (cell, "mode", GTK_CELL_RENDERER_MODE_EDITABLE, "editable", TRUE, NULL); gtk_tree_view_column_pack_start (column, cell, TRUE); gtk_tree_view_column_set_attributes (column, cell, "accel-key", GIMP_ACTION_VIEW_COLUMN_ACCEL_KEY, "accel-mods", GIMP_ACTION_VIEW_COLUMN_ACCEL_MASK, NULL); g_signal_connect (cell, "accel-edited", G_CALLBACK (gimp_action_view_accel_edited), view); g_signal_connect (cell, "accel-cleared", G_CALLBACK (gimp_action_view_accel_cleared), view); gtk_tree_view_append_column (view, column); } column = gtk_tree_view_column_new (); gtk_tree_view_column_set_title (column, _("Name")); cell = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, cell, TRUE); gtk_tree_view_column_set_attributes (column, cell, "text", GIMP_ACTION_VIEW_COLUMN_NAME, NULL); gtk_tree_view_append_column (view, column); if (select_path) { gimp_action_view_select_path (GIMP_ACTION_VIEW (view), select_path); gtk_tree_path_free (select_path); } return GTK_WIDGET (view); }
static G_CONST_RETURN gchar* gail_menu_item_get_keybinding (AtkAction *action, gint i) { /* * This function returns a string of the form A;B;C where * A is the keybinding for the widget; B is the keybinding to traverse * from the menubar and C is the accelerator. * The items in the keybinding to traverse from the menubar are separated * by ":". */ GailMenuItem *gail_menu_item; gchar *keybinding = NULL; gchar *item_keybinding = NULL; gchar *full_keybinding = NULL; gchar *accelerator = NULL; gail_menu_item = GAIL_MENU_ITEM (action); if (i == 0) { GtkWidget *item; GtkWidget *temp_item; GtkWidget *child; GtkWidget *parent; item = GTK_ACCESSIBLE (action)->widget; if (item == NULL) /* State is defunct */ return NULL; temp_item = item; while (TRUE) { GdkModifierType mnemonic_modifier = 0; guint key_val; gchar *key, *temp_keybinding; child = gtk_bin_get_child (GTK_BIN (temp_item)); if (child == NULL) { /* Possibly a tear off menu item; it could also be a menu * separator generated by gtk_item_factory_create_items() */ return NULL; } parent = gtk_widget_get_parent (temp_item); if (!parent) { /* * parent can be NULL when activating a window from the panel */ return NULL; } g_return_val_if_fail (GTK_IS_MENU_SHELL (parent), NULL); if (GTK_IS_MENU_BAR (parent)) { GtkWidget *toplevel; toplevel = gtk_widget_get_toplevel (parent); if (toplevel && GTK_IS_WINDOW (toplevel)) mnemonic_modifier = gtk_window_get_mnemonic_modifier ( GTK_WINDOW (toplevel)); } if (GTK_IS_LABEL (child)) { key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (child)); if (key_val != GDK_VoidSymbol) { key = gtk_accelerator_name (key_val, mnemonic_modifier); if (full_keybinding) temp_keybinding = g_strconcat (key, ":", full_keybinding, NULL); else temp_keybinding = g_strconcat (key, NULL); if (temp_item == item) { item_keybinding = g_strdup (key); } g_free (key); g_free (full_keybinding); full_keybinding = temp_keybinding; } else { /* No keybinding */ g_free (full_keybinding); full_keybinding = NULL; break; } } if (GTK_IS_MENU_BAR (parent)) /* We have reached the menu bar so we are finished */ break; g_return_val_if_fail (GTK_IS_MENU (parent), NULL); temp_item = gtk_menu_get_attach_widget (GTK_MENU (parent)); if (!GTK_IS_MENU_ITEM (temp_item)) { /* * Menu is attached to something other than a menu item; * probably an option menu */ g_free (full_keybinding); full_keybinding = NULL; break; } } parent = gtk_widget_get_parent (item); if (GTK_IS_MENU (parent)) { GtkAccelGroup *group; GtkAccelKey *key; group = gtk_menu_get_accel_group (GTK_MENU (parent)); if (group) { key = gtk_accel_group_find (group, find_accel, item); } else { /* * If the menu item is created using GtkAction and GtkUIManager * we get here. */ key = NULL; child = GTK_BIN (item)->child; if (GTK_IS_ACCEL_LABEL (child)) { GtkAccelLabel *accel_label; accel_label = GTK_ACCEL_LABEL (child); if (accel_label->accel_closure) { key = gtk_accel_group_find (accel_label->accel_group, find_accel_new, accel_label->accel_closure); } } } if (key) { accelerator = gtk_accelerator_name (key->accel_key, key->accel_mods); } } } /* * Concatenate the bindings */ if (item_keybinding || full_keybinding || accelerator) { gchar *temp; if (item_keybinding) { keybinding = g_strconcat (item_keybinding, KEYBINDING_SEPARATOR, NULL); g_free (item_keybinding); } else keybinding = g_strconcat (KEYBINDING_SEPARATOR, NULL); if (full_keybinding) { temp = g_strconcat (keybinding, full_keybinding, KEYBINDING_SEPARATOR, NULL); g_free (full_keybinding); } else temp = g_strconcat (keybinding, KEYBINDING_SEPARATOR, NULL); g_free (keybinding); keybinding = temp; if (accelerator) { temp = g_strconcat (keybinding, accelerator, NULL); g_free (accelerator); g_free (keybinding); keybinding = temp; } } g_free (gail_menu_item->click_keybinding); gail_menu_item->click_keybinding = keybinding; return keybinding; }
static void carbon_menu_item_update_accelerator (CarbonMenuItem *carbon_item, GtkWidget *widget) { GtkWidget *label; get_menu_label_text (widget, &label); if (GTK_IS_ACCEL_LABEL (label)) { GClosure *closure; g_object_get (label, "accel-closure", &closure, NULL); if (closure) { GtkAccelGroup *group; GtkAccelKey *key; group = gtk_accel_group_from_accel_closure (closure); key = gtk_accel_group_find (group, accel_find_func, closure); g_closure_unref (closure); if (key && key->accel_key && key->accel_flags & GTK_ACCEL_VISIBLE) { GdkDisplay *display = gtk_widget_get_display (widget); GdkKeymap *keymap = gdk_keymap_get_for_display (display); GdkKeymapKey *keys; gint n_keys; if (gdk_keymap_get_entries_for_keyval (keymap, key->accel_key, &keys, &n_keys)) { UInt8 modifiers = 0; SetMenuItemCommandKey (carbon_item->menu, carbon_item->index, true, keys[0].keycode); g_free (keys); if (key->accel_mods) { if (key->accel_mods & GDK_SHIFT_MASK) modifiers |= kMenuShiftModifier; if (key->accel_mods & GDK_MOD1_MASK) modifiers |= kMenuOptionModifier; } if (!(key->accel_mods & GDK_META_MASK)) { modifiers |= kMenuNoCommandModifier; } SetMenuItemModifiers (carbon_item->menu, carbon_item->index, modifiers); return; } } } } /* otherwise, clear the menu shortcut */ SetMenuItemModifiers (carbon_item->menu, carbon_item->index, kMenuNoModifiers | kMenuNoCommandModifier); ChangeMenuItemAttributes (carbon_item->menu, carbon_item->index, 0, kMenuItemAttrUseVirtualKey); SetMenuItemCommandKey (carbon_item->menu, carbon_item->index, false, 0); }
/* This function returns a string of the form A;B;C where A is * the keybinding for the widget; B is the keybinding to traverse * from the menubar and C is the accelerator. The items in the * keybinding to traverse from the menubar are separated by ":". */ static const gchar * gtk_menu_item_accessible_get_keybinding (AtkAction *action, gint i) { gchar *keybinding = NULL; gchar *item_keybinding = NULL; gchar *full_keybinding = NULL; gchar *accelerator = NULL; GtkWidget *item; GtkWidget *temp_item; GtkWidget *child; GtkWidget *parent; item = gtk_accessible_get_widget (GTK_ACCESSIBLE (action)); if (item == NULL) return NULL; if (i != 0) return NULL; temp_item = item; while (TRUE) { GdkModifierType mnemonic_modifier = 0; guint key_val; gchar *key, *temp_keybinding; child = gtk_bin_get_child (GTK_BIN (temp_item)); if (child == NULL) return NULL; parent = gtk_widget_get_parent (temp_item); if (!parent) /* parent can be NULL when activating a window from the panel */ return NULL; if (GTK_IS_MENU_BAR (parent)) { GtkWidget *toplevel; toplevel = gtk_widget_get_toplevel (parent); if (toplevel && GTK_IS_WINDOW (toplevel)) mnemonic_modifier = gtk_window_get_mnemonic_modifier (GTK_WINDOW (toplevel)); } if (GTK_IS_LABEL (child)) { key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (child)); if (key_val != GDK_KEY_VoidSymbol) { key = gtk_accelerator_name (key_val, mnemonic_modifier); if (full_keybinding) temp_keybinding = g_strconcat (key, ":", full_keybinding, NULL); else temp_keybinding = g_strdup (key); if (temp_item == item) item_keybinding = g_strdup (key); g_free (key); g_free (full_keybinding); full_keybinding = temp_keybinding; } else { /* No keybinding */ g_free (full_keybinding); full_keybinding = NULL; break; } } /* We have reached the menu bar so we are finished */ if (GTK_IS_MENU_BAR (parent)) break; g_return_val_if_fail (GTK_IS_MENU (parent), NULL); temp_item = gtk_menu_get_attach_widget (GTK_MENU (parent)); if (!GTK_IS_MENU_ITEM (temp_item)) { /* Menu is attached to something other than a menu item; * probably an option menu */ g_free (full_keybinding); full_keybinding = NULL; break; } } parent = gtk_widget_get_parent (item); if (GTK_IS_MENU (parent)) { GtkAccelGroup *group; GtkAccelKey *key; group = gtk_menu_get_accel_group (GTK_MENU (parent)); if (group) key = gtk_accel_group_find (group, find_accel_by_widget, item); else { key = NULL; child = gtk_bin_get_child (GTK_BIN (item)); if (GTK_IS_ACCEL_LABEL (child)) { GtkAccelLabel *accel_label; GClosure *accel_closure; accel_label = GTK_ACCEL_LABEL (child); g_object_get (accel_label, "accel-closure", &accel_closure, NULL); if (accel_closure) { key = gtk_accel_group_find (gtk_accel_group_from_accel_closure (accel_closure), find_accel_by_closure, accel_closure); g_closure_unref (accel_closure); } } } if (key) accelerator = gtk_accelerator_name (key->accel_key, key->accel_mods); } /* Concatenate the bindings */ if (item_keybinding || full_keybinding || accelerator) { gchar *temp; if (item_keybinding) { keybinding = g_strconcat (item_keybinding, KEYBINDING_SEPARATOR, NULL); g_free (item_keybinding); } else keybinding = g_strdup (KEYBINDING_SEPARATOR); if (full_keybinding) { temp = g_strconcat (keybinding, full_keybinding, KEYBINDING_SEPARATOR, NULL); g_free (full_keybinding); } else temp = g_strconcat (keybinding, KEYBINDING_SEPARATOR, NULL); g_free (keybinding); keybinding = temp; if (accelerator) { temp = g_strconcat (keybinding, accelerator, NULL); g_free (accelerator); g_free (keybinding); keybinding = temp; } } return keybinding; }