nsMenuFrame* nsMenuBarFrame::FindMenuWithShortcut(nsIDOMKeyEvent* aKeyEvent) { uint32_t charCode; aKeyEvent->GetCharCode(&charCode); AutoTArray<uint32_t, 10> accessKeys; WidgetKeyboardEvent* nativeKeyEvent = aKeyEvent->AsEvent()->WidgetEventPtr()->AsKeyboardEvent(); if (nativeKeyEvent) { nativeKeyEvent->GetAccessKeyCandidates(accessKeys); } if (accessKeys.IsEmpty() && charCode) accessKeys.AppendElement(charCode); if (accessKeys.IsEmpty()) return nullptr; // no character was pressed so just return // Enumerate over our list of frames. auto insertion = PresContext()->PresShell()->FrameConstructor()-> GetInsertionPoint(GetContent(), nullptr); nsContainerFrame* immediateParent = insertion.mParentFrame; if (!immediateParent) immediateParent = this; // Find a most preferred accesskey which should be returned. nsIFrame* foundMenu = nullptr; size_t foundIndex = accessKeys.NoIndex; nsIFrame* currFrame = immediateParent->PrincipalChildList().FirstChild(); while (currFrame) { nsIContent* current = currFrame->GetContent(); // See if it's a menu item. if (nsXULPopupManager::IsValidMenuItem(current, false)) { // Get the shortcut attribute. nsAutoString shortcutKey; current->GetAttr(kNameSpaceID_None, nsGkAtoms::accesskey, shortcutKey); if (!shortcutKey.IsEmpty()) { ToLowerCase(shortcutKey); const char16_t* start = shortcutKey.BeginReading(); const char16_t* end = shortcutKey.EndReading(); uint32_t ch = UTF16CharEnumerator::NextChar(&start, end); size_t index = accessKeys.IndexOf(ch); if (index != accessKeys.NoIndex && (foundIndex == accessKeys.NoIndex || index < foundIndex)) { foundMenu = currFrame; foundIndex = index; } } } currFrame = currFrame->GetNextSibling(); } if (foundMenu) { return do_QueryFrame(foundMenu); } // didn't find a matching menu item #ifdef XP_WIN // behavior on Windows - this item is on the menu bar, beep and deactivate the menu bar if (mIsActive) { nsCOMPtr<nsISound> soundInterface = do_CreateInstance("@mozilla.org/sound;1"); if (soundInterface) soundInterface->Beep(); } nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); if (pm) { nsIFrame* popup = pm->GetTopPopup(ePopupTypeAny); if (popup) pm->HidePopup(popup->GetContent(), true, true, true, false); } SetCurrentMenuItem(nullptr); SetActive(false); #endif // #ifdef XP_WIN return nullptr; }