diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 3f40e8a97bb9..96b3666a0d07 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -6308,6 +6308,36 @@ IsSynthesizedMouseMove(nsEvent* aEvent) static_cast(aEvent)->reason != nsMouseEvent::eReal; } +static PRBool CanHandleContextMenuEvent(nsMouseEvent* aMouseEvent, + nsIFrame* aFrame) +{ +#if defined(XP_MACOSX) && defined(MOZ_XUL) + nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); + if (pm) { + nsIFrame* popupFrame = pm->GetTopPopup(ePopupTypeMenu); + if (popupFrame) { + // context menus should not be opened while another menu is open on Mac, + // so return false so that the event is not fired. + if (aMouseEvent->context == nsMouseEvent::eContextMenuKey) { + return PR_FALSE; + } else if (aMouseEvent->widget) { + nsWindowType windowType; + aMouseEvent->widget->GetWindowType(windowType); + if (windowType == eWindowType_popup) { + for (nsIFrame* current = aFrame; current; + current = nsLayoutUtils::GetCrossDocParentFrame(current)) { + if (current->GetType() == nsGkAtoms::menuPopupFrame) { + return PR_FALSE; + } + } + } + } + } + } +#endif + return PR_TRUE; +} + nsresult PresShell::HandleEventInternal(nsEvent* aEvent, nsIView *aView, nsEventStatus* aStatus) @@ -6358,11 +6388,16 @@ PresShell::HandleEventInternal(nsEvent* aEvent, nsIView *aView, } } - if (aEvent->message == NS_CONTEXTMENU && - static_cast(aEvent)->context == nsMouseEvent::eContextMenuKey) { - if (!AdjustContextMenuKeyEvent(static_cast(aEvent))) + if (aEvent->message == NS_CONTEXTMENU) { + nsMouseEvent* me = static_cast(aEvent); + if (!CanHandleContextMenuEvent(me, GetCurrentEventFrame())) { return NS_OK; - } + } + if (me->context == nsMouseEvent::eContextMenuKey && + !AdjustContextMenuKeyEvent(me)) { + return NS_OK; + } + } nsAutoHandlingUserInputStatePusher userInpStatePusher(isHandlingUserInput); @@ -6460,18 +6495,11 @@ PRBool PresShell::AdjustContextMenuKeyEvent(nsMouseEvent* aEvent) { #ifdef MOZ_XUL - // if a menu is open, open the context menu relative to the active item on the menu. - // XXXndeakin Mac doesn't fire mouse-triggered context menus while another - // menu is open. Maybe we should prevent keyboard-tiggered context menu events too. + // if a menu is open, open the context menu relative to the active item on the menu. nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); if (pm) { nsIFrame* popupFrame = pm->GetTopPopup(ePopupTypeMenu); if (popupFrame) { -#ifdef XP_MACOSX - // context menus should not be opened while another menu is open on Mac, - // so return false so that the event is not fired. - return PR_FALSE; -#else nsIFrame* itemFrame = (static_cast(popupFrame))->GetCurrentMenuItem(); if (!itemFrame) @@ -6486,7 +6514,6 @@ PresShell::AdjustContextMenuKeyEvent(nsMouseEvent* aEvent) mCurrentEventFrame = itemFrame; return PR_TRUE; -#endif } } #endif