/** * dbusmenu_menuitem_property_set_shortcut_string: * @menuitem: The #DbusmenuMenuitem to set the shortcut on * @shortcut: String describing the shortcut * * This function takes a GTK shortcut string as defined in * #gtk_accelerator_parse and turns that into the information * required to send it over DBusmenu. * * Return value: Whether it was successful at setting the property. */ gboolean dbusmenu_menuitem_property_set_shortcut_string (DbusmenuMenuitem * menuitem, const gchar * shortcut) { g_return_val_if_fail(DBUSMENU_IS_MENUITEM(menuitem), FALSE); g_return_val_if_fail(shortcut != NULL, FALSE); guint key = 0; GdkModifierType modifier = 0; gtk_accelerator_parse(shortcut, &key, &modifier); if (key == 0) { g_warning("Unable to parse shortcut string '%s'", shortcut); return FALSE; } return dbusmenu_menuitem_property_set_shortcut(menuitem, key, modifier); }
/** * 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 uGlobalMenuItem::SyncAccelFromContent() { if (!mKeyContent) { dbusmenu_menuitem_property_remove(mDbusMenuItem, DBUSMENU_MENUITEM_PROP_SHORTCUT); return; } nsAutoString modStr; mKeyContent->GetAttr(kNameSpaceID_None, uWidgetAtoms::modifiers, modStr); PRUint32 modifier = 0; if (!modStr.IsEmpty()) { char* str = ToNewUTF8String(modStr); char *token = strtok(str, ", \t"); while(token) { if (strcmp(token, "shift") == 0) { modifier |= GDK_SHIFT_MASK; } else if (strcmp(token, "alt") == 0) { modifier |= GDK_MOD1_MASK; } else if (strcmp(token, "meta") == 0) { modifier |= GDK_META_MASK; } else if (strcmp(token, "control") == 0) { modifier |= GDK_CONTROL_MASK; } else if (strcmp(token, "accel") == 0) { nsIPrefBranch *prefs = uGlobalMenuService::GetPrefService(); PRInt32 accel; prefs->GetIntPref("ui.key.accelKey", &accel); if (accel == nsIDOMKeyEvent::DOM_VK_META) { modifier |= GDK_META_MASK; } else if (accel == nsIDOMKeyEvent::DOM_VK_ALT) { modifier |= GDK_MOD1_MASK; } else { modifier |= GDK_CONTROL_MASK; } } token = strtok(nullptr, ", \t"); } nsMemory::Free(str); } nsAutoString keyStr; guint key = 0; mKeyContent->GetAttr(kNameSpaceID_None, uWidgetAtoms::key, keyStr); nsAutoCString cKeyStr; CopyUTF16toUTF8(keyStr, cKeyStr); if (!cKeyStr.IsEmpty()) { key = gdk_keyval_from_name(cKeyStr.get()); } if (key == 0 && !keyStr.IsEmpty()) { key = gdk_unicode_to_keyval(*keyStr.BeginReading()); } if (key == 0) { mKeyContent->GetAttr(kNameSpaceID_None, uWidgetAtoms::keycode, keyStr); if (!keyStr.IsEmpty()) key = MozKeyCodeToGdkKeyCode(GetKeyCode(keyStr)); } if (key == 0) { key = GDK_VoidSymbol; } if (key != GDK_VoidSymbol) { dbusmenu_menuitem_property_set_shortcut(mDbusMenuItem, key, static_cast<GdkModifierType>(modifier)); } else { dbusmenu_menuitem_property_remove(mDbusMenuItem, DBUSMENU_MENUITEM_PROP_SHORTCUT); } }