forked from mirrors/gecko-dev
		
	Bug 1812329 - Remove nsMenuBarFrame. r=smaug
This ended up being a lot more straight-forward than the menu changes. TLDR: * nsMenuBarFrame -> XULMenuBarElement * nsMenuBarListener -> MenuBarListener Rest should be rather straight-forward. Depends on D168649 Differential Revision: https://phabricator.services.mozilla.com/D167809
This commit is contained in:
		
							parent
							
								
									720ce2d73f
								
							
						
					
					
						commit
						b9833bfcca
					
				
					 23 changed files with 379 additions and 476 deletions
				
			
		|  | @ -6,6 +6,7 @@ | ||||||
| #include "XULMenuAccessible.h" | #include "XULMenuAccessible.h" | ||||||
| 
 | 
 | ||||||
| #include "LocalAccessible-inl.h" | #include "LocalAccessible-inl.h" | ||||||
|  | #include "XULMenuBarElement.h" | ||||||
| #include "XULMenuParentElement.h" | #include "XULMenuParentElement.h" | ||||||
| #include "XULPopupElement.h" | #include "XULPopupElement.h" | ||||||
| #include "mozilla/Assertions.h" | #include "mozilla/Assertions.h" | ||||||
|  | @ -21,7 +22,6 @@ | ||||||
| #include "nsIDOMXULSelectCntrlEl.h" | #include "nsIDOMXULSelectCntrlEl.h" | ||||||
| #include "nsIDOMXULSelectCntrlItemEl.h" | #include "nsIDOMXULSelectCntrlItemEl.h" | ||||||
| #include "nsIContent.h" | #include "nsIContent.h" | ||||||
| #include "nsMenuBarFrame.h" |  | ||||||
| #include "nsMenuPopupFrame.h" | #include "nsMenuPopupFrame.h" | ||||||
| 
 | 
 | ||||||
| #include "mozilla/Preferences.h" | #include "mozilla/Preferences.h" | ||||||
|  | @ -464,8 +464,8 @@ role XULMenubarAccessible::NativeRole() const { return roles::MENUBAR; } | ||||||
| // XULMenubarAccessible: Widgets
 | // XULMenubarAccessible: Widgets
 | ||||||
| 
 | 
 | ||||||
| bool XULMenubarAccessible::IsActiveWidget() const { | bool XULMenubarAccessible::IsActiveWidget() const { | ||||||
|   nsMenuBarFrame* menuBarFrame = do_QueryFrame(GetFrame()); |   auto* menuBar = dom::XULMenuBarElement::FromNode(GetContent()); | ||||||
|   return menuBarFrame && menuBarFrame->IsActive(); |   return menuBar && menuBar->IsActive(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool XULMenubarAccessible::AreItemsOperable() const { return true; } | bool XULMenubarAccessible::AreItemsOperable() const { return true; } | ||||||
|  |  | ||||||
|  | @ -4,24 +4,21 @@ | ||||||
|  * License, v. 2.0. If a copy of the MPL was not distributed with this |  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 |  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | ||||||
| 
 | 
 | ||||||
| #include "nsMenuBarListener.h" | #include "MenuBarListener.h" | ||||||
| #include "XULButtonElement.h" | #include "XULButtonElement.h" | ||||||
| #include "mozilla/Attributes.h" | #include "mozilla/Attributes.h" | ||||||
| #include "mozilla/dom/XULButtonElement.h" |  | ||||||
| #include "nsMenuBarFrame.h" |  | ||||||
| #include "nsMenuPopupFrame.h" |  | ||||||
| #include "nsPIWindowRoot.h" |  | ||||||
| #include "nsISound.h" | #include "nsISound.h" | ||||||
| 
 | 
 | ||||||
| // Drag & Drop, Clipboard
 | // Drag & Drop, Clipboard
 | ||||||
| #include "nsWidgetsCID.h" | #include "nsWidgetsCID.h" | ||||||
| #include "nsCOMPtr.h" | #include "nsCOMPtr.h" | ||||||
| #include "nsIContent.h" |  | ||||||
| 
 | 
 | ||||||
| #include "nsContentUtils.h" | #include "nsContentUtils.h" | ||||||
|  | #include "nsPIWindowRoot.h" | ||||||
|  | #include "nsIFrame.h" | ||||||
| #include "mozilla/BasicEvents.h" | #include "mozilla/BasicEvents.h" | ||||||
| #include "mozilla/LookAndFeel.h" |  | ||||||
| #include "mozilla/Preferences.h" | #include "mozilla/Preferences.h" | ||||||
|  | #include "mozilla/LookAndFeel.h" | ||||||
| #include "mozilla/StaticPrefs_ui.h" | #include "mozilla/StaticPrefs_ui.h" | ||||||
| #include "mozilla/TextEvents.h" | #include "mozilla/TextEvents.h" | ||||||
| #include "mozilla/dom/Document.h" | #include "mozilla/dom/Document.h" | ||||||
|  | @ -29,31 +26,30 @@ | ||||||
| #include "mozilla/dom/EventBinding.h" | #include "mozilla/dom/EventBinding.h" | ||||||
| #include "mozilla/dom/KeyboardEvent.h" | #include "mozilla/dom/KeyboardEvent.h" | ||||||
| #include "mozilla/dom/KeyboardEventBinding.h" | #include "mozilla/dom/KeyboardEventBinding.h" | ||||||
|  | #include "mozilla/dom/XULButtonElement.h" | ||||||
|  | #include "mozilla/dom/XULMenuBarElement.h" | ||||||
| #include "mozilla/dom/XULMenuParentElement.h" | #include "mozilla/dom/XULMenuParentElement.h" | ||||||
| #include "nsXULPopupManager.h" | #include "nsXULPopupManager.h" | ||||||
| 
 | 
 | ||||||
| using namespace mozilla; | namespace mozilla::dom { | ||||||
| using mozilla::dom::Event; |  | ||||||
| using mozilla::dom::KeyboardEvent; |  | ||||||
| 
 | 
 | ||||||
| /*
 | NS_IMPL_CYCLE_COLLECTION(MenuBarListener, mTopWindowEventTarget) | ||||||
|  * nsMenuBarListener implementation |  | ||||||
|  */ |  | ||||||
| 
 | 
 | ||||||
| NS_IMPL_ISUPPORTS(nsMenuBarListener, nsIDOMEventListener) | NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MenuBarListener) | ||||||
|  |   NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener) | ||||||
|  | NS_INTERFACE_MAP_END | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////
 | NS_IMPL_CYCLE_COLLECTING_ADDREF(MenuBarListener) | ||||||
|  | NS_IMPL_CYCLE_COLLECTING_RELEASE(MenuBarListener) | ||||||
| 
 | 
 | ||||||
| nsMenuBarListener::nsMenuBarListener(nsMenuBarFrame* aMenuBarFrame, | MenuBarListener::MenuBarListener(XULMenuBarElement& aElement) | ||||||
|                                      nsIContent* aMenuBarContent) |     : mMenuBar(&aElement), | ||||||
|     : mMenuBarFrame(aMenuBarFrame), |       mEventTarget(aElement.GetComposedDoc()), | ||||||
|       mContent(dom::XULMenuParentElement::FromNode(aMenuBarContent)), |  | ||||||
|       mEventTarget(aMenuBarContent->GetComposedDoc()), |  | ||||||
|       mTopWindowEventTarget(nullptr), |       mTopWindowEventTarget(nullptr), | ||||||
|       mAccessKeyDown(false), |       mAccessKeyDown(false), | ||||||
|       mAccessKeyDownCanceled(false) { |       mAccessKeyDownCanceled(false) { | ||||||
|   MOZ_ASSERT(mEventTarget); |   MOZ_ASSERT(mEventTarget); | ||||||
|   MOZ_ASSERT(mContent); |   MOZ_ASSERT(mMenuBar); | ||||||
| 
 | 
 | ||||||
|   // Hook up the menubar as a key listener on the whole document.  This will
 |   // Hook up the menubar as a key listener on the whole document.  This will
 | ||||||
|   // see every keypress that occurs, but after everyone else does.
 |   // see every keypress that occurs, but after everyone else does.
 | ||||||
|  | @ -78,20 +74,16 @@ nsMenuBarListener::nsMenuBarListener(nsMenuBarFrame* aMenuBarFrame, | ||||||
|   mEventTarget->AddEventListener(u"MozDOMFullscreen:Entered"_ns, this, false); |   mEventTarget->AddEventListener(u"MozDOMFullscreen:Entered"_ns, this, false); | ||||||
| 
 | 
 | ||||||
|   // Needs to listen to the deactivate event of the window.
 |   // Needs to listen to the deactivate event of the window.
 | ||||||
|   RefPtr<dom::EventTarget> topWindowEventTarget = |   mTopWindowEventTarget = nsContentUtils::GetWindowRoot(mEventTarget); | ||||||
|       nsContentUtils::GetWindowRoot(aMenuBarContent->GetComposedDoc()); |  | ||||||
|   mTopWindowEventTarget = topWindowEventTarget.get(); |  | ||||||
| 
 |  | ||||||
|   mTopWindowEventTarget->AddSystemEventListener(u"deactivate"_ns, this, true); |   mTopWindowEventTarget->AddSystemEventListener(u"deactivate"_ns, this, true); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////
 | ||||||
| nsMenuBarListener::~nsMenuBarListener() { | MenuBarListener::~MenuBarListener() { | ||||||
|   MOZ_ASSERT(!mEventTarget, |   MOZ_ASSERT(!mEventTarget, "Should've detached always"); | ||||||
|              "OnDestroyMenuBarFrame() should've alreay been called"); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void nsMenuBarListener::OnDestroyMenuBarFrame() { | void MenuBarListener::Detach() { | ||||||
|   mEventTarget->RemoveSystemEventListener(u"keypress"_ns, this, false); |   mEventTarget->RemoveSystemEventListener(u"keypress"_ns, this, false); | ||||||
|   mEventTarget->RemoveSystemEventListener(u"keydown"_ns, this, false); |   mEventTarget->RemoveSystemEventListener(u"keydown"_ns, this, false); | ||||||
|   mEventTarget->RemoveSystemEventListener(u"keyup"_ns, this, false); |   mEventTarget->RemoveSystemEventListener(u"keyup"_ns, this, false); | ||||||
|  | @ -109,23 +101,26 @@ void nsMenuBarListener::OnDestroyMenuBarFrame() { | ||||||
|   mTopWindowEventTarget->RemoveSystemEventListener(u"deactivate"_ns, this, |   mTopWindowEventTarget->RemoveSystemEventListener(u"deactivate"_ns, this, | ||||||
|                                                    true); |                                                    true); | ||||||
| 
 | 
 | ||||||
|   mMenuBarFrame = nullptr; |   mMenuBar = nullptr; | ||||||
|   mEventTarget = nullptr; |   mEventTarget = nullptr; | ||||||
|   mTopWindowEventTarget = nullptr; |   mTopWindowEventTarget = nullptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void nsMenuBarListener::ToggleMenuActiveState() { | void MenuBarListener::ToggleMenuActiveState(ByKeyboard aByKeyboard) { | ||||||
|   if (mMenuBarFrame->IsActive()) { |   RefPtr menuBar = mMenuBar; | ||||||
|     mMenuBarFrame->SetActive(false); |   if (menuBar->IsActive()) { | ||||||
|  |     menuBar->SetActive(false); | ||||||
|   } else { |   } else { | ||||||
|     RefPtr content = mContent; |     if (aByKeyboard == ByKeyboard::Yes) { | ||||||
|     mMenuBarFrame->SetActive(true); |       menuBar->SetActiveByKeyboard(); | ||||||
|     content->SelectFirstItem(); |     } | ||||||
|  |     menuBar->SetActive(true); | ||||||
|  |     menuBar->SelectFirstItem(); | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////
 | ||||||
| nsresult nsMenuBarListener::KeyUp(Event* aKeyEvent) { | nsresult MenuBarListener::KeyUp(Event* aKeyEvent) { | ||||||
|   WidgetKeyboardEvent* nativeKeyEvent = |   WidgetKeyboardEvent* nativeKeyEvent = | ||||||
|       aKeyEvent->WidgetEventPtr()->AsKeyboardEvent(); |       aKeyEvent->WidgetEventPtr()->AsKeyboardEvent(); | ||||||
|   if (!nativeKeyEvent) { |   if (!nativeKeyEvent) { | ||||||
|  | @ -149,7 +144,7 @@ nsresult nsMenuBarListener::KeyUp(Event* aKeyEvent) { | ||||||
|     // The access key was down and is now up, and no other
 |     // The access key was down and is now up, and no other
 | ||||||
|     // keys were pressed in between.
 |     // keys were pressed in between.
 | ||||||
|     bool toggleMenuActiveState = true; |     bool toggleMenuActiveState = true; | ||||||
|     if (!mMenuBarFrame->IsActive()) { |     if (!mMenuBar->IsActive()) { | ||||||
|       // If the focused content is in a remote process, we should allow the
 |       // If the focused content is in a remote process, we should allow the
 | ||||||
|       // focused web app to prevent to activate the menubar.
 |       // focused web app to prevent to activate the menubar.
 | ||||||
|       if (nativeKeyEvent->WillBeSentToRemoteProcess()) { |       if (nativeKeyEvent->WillBeSentToRemoteProcess()) { | ||||||
|  | @ -165,20 +160,17 @@ nsresult nsMenuBarListener::KeyUp(Event* aKeyEvent) { | ||||||
|       } |       } | ||||||
|       // If menubar active state is changed or the menubar is destroyed
 |       // If menubar active state is changed or the menubar is destroyed
 | ||||||
|       // during closing the popups, we should do nothing anymore.
 |       // during closing the popups, we should do nothing anymore.
 | ||||||
|       toggleMenuActiveState = !Destroyed() && !mMenuBarFrame->IsActive(); |       toggleMenuActiveState = !Destroyed() && !mMenuBar->IsActive(); | ||||||
|     } |     } | ||||||
|     if (toggleMenuActiveState) { |     if (toggleMenuActiveState) { | ||||||
|       if (!mMenuBarFrame->IsActive()) { |       ToggleMenuActiveState(ByKeyboard::Yes); | ||||||
|         mMenuBarFrame->SetActiveByKeyboard(); |  | ||||||
|       } |  | ||||||
|       ToggleMenuActiveState(); |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   mAccessKeyDown = false; |   mAccessKeyDown = false; | ||||||
|   mAccessKeyDownCanceled = false; |   mAccessKeyDownCanceled = false; | ||||||
| 
 | 
 | ||||||
|   if (!Destroyed() && mMenuBarFrame->IsActive()) { |   if (!Destroyed() && mMenuBar->IsActive()) { | ||||||
|     nativeKeyEvent->StopPropagation(); |     nativeKeyEvent->StopPropagation(); | ||||||
|     nativeKeyEvent->PreventDefault(); |     nativeKeyEvent->PreventDefault(); | ||||||
|   } |   } | ||||||
|  | @ -187,7 +179,7 @@ nsresult nsMenuBarListener::KeyUp(Event* aKeyEvent) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////
 | ||||||
| nsresult nsMenuBarListener::KeyPress(Event* aKeyEvent) { | nsresult MenuBarListener::KeyPress(Event* aKeyEvent) { | ||||||
|   // if event has already been handled, bail
 |   // if event has already been handled, bail
 | ||||||
|   if (!aKeyEvent || aKeyEvent->DefaultPrevented()) { |   if (!aKeyEvent || aKeyEvent->DefaultPrevented()) { | ||||||
|     return NS_OK;  // don't consume event
 |     return NS_OK;  // don't consume event
 | ||||||
|  | @ -198,7 +190,7 @@ nsresult nsMenuBarListener::KeyPress(Event* aKeyEvent) { | ||||||
|     return NS_OK; |     return NS_OK; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   auto accessKey = LookAndFeel::GetMenuAccessKey(); |   const auto accessKey = LookAndFeel::GetMenuAccessKey(); | ||||||
|   if (!accessKey) { |   if (!accessKey) { | ||||||
|     return NS_OK; |     return NS_OK; | ||||||
|   } |   } | ||||||
|  | @ -235,12 +227,11 @@ nsresult nsMenuBarListener::KeyPress(Event* aKeyEvent) { | ||||||
|       } |       } | ||||||
|       // The F10 key just went down by itself or with ctrl pressed.
 |       // The F10 key just went down by itself or with ctrl pressed.
 | ||||||
|       // In Windows, both of these activate the menu bar.
 |       // In Windows, both of these activate the menu bar.
 | ||||||
|       mMenuBarFrame->SetActiveByKeyboard(); |       ToggleMenuActiveState(ByKeyboard::Yes); | ||||||
|       ToggleMenuActiveState(); |  | ||||||
| 
 | 
 | ||||||
|       if (mMenuBarFrame->IsActive()) { |       if (mMenuBar && mMenuBar->IsActive()) { | ||||||
| #  ifdef MOZ_WIDGET_GTK | #  ifdef MOZ_WIDGET_GTK | ||||||
|         RefPtr child = mContent->GetActiveMenuChild(); |         RefPtr child = mMenuBar->GetActiveMenuChild(); | ||||||
|         // In GTK, this also opens the first menu.
 |         // In GTK, this also opens the first menu.
 | ||||||
|         child->OpenMenuPopup(false); |         child->OpenMenuPopup(false); | ||||||
| #  endif | #  endif | ||||||
|  | @ -260,11 +251,11 @@ nsresult nsMenuBarListener::KeyPress(Event* aKeyEvent) { | ||||||
|     // the menu bar.
 |     // the menu bar.
 | ||||||
|     // TODO(emilio): This is rather odd, and I cannot get the beep to work,
 |     // TODO(emilio): This is rather odd, and I cannot get the beep to work,
 | ||||||
|     // but this matches what old code was doing...
 |     // but this matches what old code was doing...
 | ||||||
|     if (mMenuBarFrame->IsActive()) { |     if (mMenuBar && mMenuBar->IsActive()) { | ||||||
|       if (nsCOMPtr<nsISound> sound = do_GetService("@mozilla.org/sound;1")) { |       if (nsCOMPtr<nsISound> sound = do_GetService("@mozilla.org/sound;1")) { | ||||||
|         sound->Beep(); |         sound->Beep(); | ||||||
|       } |       } | ||||||
|       mMenuBarFrame->SetActive(false); |       ToggleMenuActiveState(ByKeyboard::Yes); | ||||||
|     } |     } | ||||||
| #endif | #endif | ||||||
|     return NS_OK; |     return NS_OK; | ||||||
|  | @ -282,8 +273,9 @@ nsresult nsMenuBarListener::KeyPress(Event* aKeyEvent) { | ||||||
|     return NS_OK; |     return NS_OK; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   mMenuBarFrame->SetActiveByKeyboard(); |   RefPtr menuBar = mMenuBar; | ||||||
|   mMenuBarFrame->SetActive(true); |   menuBar->SetActiveByKeyboard(); | ||||||
|  |   menuBar->SetActive(true); | ||||||
|   menuForKey->OpenMenuPopup(true); |   menuForKey->OpenMenuPopup(true); | ||||||
| 
 | 
 | ||||||
|   // The opened menu will listen next keyup event.
 |   // The opened menu will listen next keyup event.
 | ||||||
|  | @ -292,11 +284,10 @@ nsresult nsMenuBarListener::KeyPress(Event* aKeyEvent) { | ||||||
| 
 | 
 | ||||||
|   aKeyEvent->StopPropagation(); |   aKeyEvent->StopPropagation(); | ||||||
|   aKeyEvent->PreventDefault(); |   aKeyEvent->PreventDefault(); | ||||||
| 
 |  | ||||||
|   return NS_OK; |   return NS_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| dom::XULButtonElement* nsMenuBarListener::GetMenuForKeyEvent( | dom::XULButtonElement* MenuBarListener::GetMenuForKeyEvent( | ||||||
|     KeyboardEvent& aKeyEvent) { |     KeyboardEvent& aKeyEvent) { | ||||||
|   if (!aKeyEvent.IsMenuAccessKeyPressed()) { |   if (!aKeyEvent.IsMenuAccessKeyPressed()) { | ||||||
|     return nullptr; |     return nullptr; | ||||||
|  | @ -318,10 +309,10 @@ dom::XULButtonElement* nsMenuBarListener::GetMenuForKeyEvent( | ||||||
|   // Do shortcut navigation.
 |   // Do shortcut navigation.
 | ||||||
|   // A letter was pressed. We want to see if a shortcut gets matched. If
 |   // A letter was pressed. We want to see if a shortcut gets matched. If
 | ||||||
|   // so, we'll know the menu got activated.
 |   // so, we'll know the menu got activated.
 | ||||||
|   return mMenuBarFrame->MenubarElement().FindMenuWithShortcut(aKeyEvent); |   return mMenuBar->FindMenuWithShortcut(aKeyEvent); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void nsMenuBarListener::ReserveKeyIfNeeded(Event* aKeyEvent) { | void MenuBarListener::ReserveKeyIfNeeded(Event* aKeyEvent) { | ||||||
|   WidgetKeyboardEvent* nativeKeyEvent = |   WidgetKeyboardEvent* nativeKeyEvent = | ||||||
|       aKeyEvent->WidgetEventPtr()->AsKeyboardEvent(); |       aKeyEvent->WidgetEventPtr()->AsKeyboardEvent(); | ||||||
|   if (nsContentUtils::ShouldBlockReservedKeys(nativeKeyEvent)) { |   if (nsContentUtils::ShouldBlockReservedKeys(nativeKeyEvent)) { | ||||||
|  | @ -330,7 +321,7 @@ void nsMenuBarListener::ReserveKeyIfNeeded(Event* aKeyEvent) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////
 | ||||||
| nsresult nsMenuBarListener::KeyDown(Event* aKeyEvent) { | nsresult MenuBarListener::KeyDown(Event* aKeyEvent) { | ||||||
|   // handlers shouldn't be triggered by non-trusted events.
 |   // handlers shouldn't be triggered by non-trusted events.
 | ||||||
|   if (!aKeyEvent || !aKeyEvent->IsTrusted()) { |   if (!aKeyEvent || !aKeyEvent->IsTrusted()) { | ||||||
|     return NS_OK; |     return NS_OK; | ||||||
|  | @ -360,9 +351,9 @@ nsresult nsMenuBarListener::KeyDown(Event* aKeyEvent) { | ||||||
|     // Especially CTRL.  CTRL+ALT == AltGR, and we'll break on non-US
 |     // Especially CTRL.  CTRL+ALT == AltGR, and we'll break on non-US
 | ||||||
|     // enhanced 102-key keyboards if we don't check this.
 |     // enhanced 102-key keyboards if we don't check this.
 | ||||||
|     bool isAccessKeyDownEvent = |     bool isAccessKeyDownEvent = | ||||||
|         theChar == accessKey && |         (theChar == accessKey && | ||||||
|         (keyEvent->GetModifiersForMenuAccessKey() & |          (keyEvent->GetModifiersForMenuAccessKey() & | ||||||
|          ~LookAndFeel::GetMenuAccessKeyModifiers()) == 0; |           ~LookAndFeel::GetMenuAccessKeyModifiers()) == 0); | ||||||
| 
 | 
 | ||||||
|     if (!capturing && !mAccessKeyDown) { |     if (!capturing && !mAccessKeyDown) { | ||||||
|       // If accesskey isn't being pressed and the key isn't the accesskey,
 |       // If accesskey isn't being pressed and the key isn't the accesskey,
 | ||||||
|  | @ -389,7 +380,7 @@ nsresult nsMenuBarListener::KeyDown(Event* aKeyEvent) { | ||||||
|     mAccessKeyDownCanceled = !isAccessKeyDownEvent; |     mAccessKeyDownCanceled = !isAccessKeyDownEvent; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (capturing && LookAndFeel::GetMenuAccessKey()) { |   if (capturing && accessKey) { | ||||||
|     if (GetMenuForKeyEvent(*keyEvent)) { |     if (GetMenuForKeyEvent(*keyEvent)) { | ||||||
|       ReserveKeyIfNeeded(aKeyEvent); |       ReserveKeyIfNeeded(aKeyEvent); | ||||||
|     } |     } | ||||||
|  | @ -400,9 +391,9 @@ nsresult nsMenuBarListener::KeyDown(Event* aKeyEvent) { | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////
 | ||||||
| 
 | 
 | ||||||
| nsresult nsMenuBarListener::Blur(Event* aEvent) { | nsresult MenuBarListener::Blur(Event* aEvent) { | ||||||
|   if (!IsMenuOpen() && mMenuBarFrame->IsActive()) { |   if (!IsMenuOpen() && mMenuBar->IsActive()) { | ||||||
|     ToggleMenuActiveState(); |     ToggleMenuActiveState(ByKeyboard::No); | ||||||
|     mAccessKeyDown = false; |     mAccessKeyDown = false; | ||||||
|     mAccessKeyDownCanceled = false; |     mAccessKeyDownCanceled = false; | ||||||
|   } |   } | ||||||
|  | @ -411,7 +402,7 @@ nsresult nsMenuBarListener::Blur(Event* aEvent) { | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////
 | ||||||
| 
 | 
 | ||||||
| nsresult nsMenuBarListener::OnWindowDeactivated(Event* aEvent) { | nsresult MenuBarListener::OnWindowDeactivated(Event* aEvent) { | ||||||
|   // Reset the accesskey state because we cannot receive the keyup event for
 |   // Reset the accesskey state because we cannot receive the keyup event for
 | ||||||
|   // the pressing accesskey.
 |   // the pressing accesskey.
 | ||||||
|   mAccessKeyDown = false; |   mAccessKeyDown = false; | ||||||
|  | @ -419,13 +410,13 @@ nsresult nsMenuBarListener::OnWindowDeactivated(Event* aEvent) { | ||||||
|   return NS_OK;  // means I am NOT consuming event
 |   return NS_OK;  // means I am NOT consuming event
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool nsMenuBarListener::IsMenuOpen() const { | bool MenuBarListener::IsMenuOpen() const { | ||||||
|   auto* activeChild = mContent->GetActiveMenuChild(); |   auto* activeChild = mMenuBar->GetActiveMenuChild(); | ||||||
|   return activeChild && activeChild->IsMenuPopupOpen(); |   return activeChild && activeChild->IsMenuPopupOpen(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////
 | ||||||
| nsresult nsMenuBarListener::MouseDown(Event* aMouseEvent) { | nsresult MenuBarListener::MouseDown(Event* aMouseEvent) { | ||||||
|   // NOTE: MouseDown method listens all phases
 |   // NOTE: MouseDown method listens all phases
 | ||||||
| 
 | 
 | ||||||
|   // Even if the mousedown event is canceled, it means the user don't want
 |   // Even if the mousedown event is canceled, it means the user don't want
 | ||||||
|  | @ -440,8 +431,8 @@ nsresult nsMenuBarListener::MouseDown(Event* aMouseEvent) { | ||||||
|     return NS_OK; |     return NS_OK; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (!IsMenuOpen() && mMenuBarFrame->IsActive()) { |   if (!IsMenuOpen() && mMenuBar->IsActive()) { | ||||||
|     ToggleMenuActiveState(); |     ToggleMenuActiveState(ByKeyboard::No); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   return NS_OK;  // means I am NOT consuming event
 |   return NS_OK;  // means I am NOT consuming event
 | ||||||
|  | @ -449,18 +440,19 @@ nsresult nsMenuBarListener::MouseDown(Event* aMouseEvent) { | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////
 | ||||||
| 
 | 
 | ||||||
| nsresult nsMenuBarListener::Fullscreen(Event* aEvent) { | nsresult MenuBarListener::Fullscreen(Event* aEvent) { | ||||||
|   if (mMenuBarFrame->IsActive()) { |   if (mMenuBar->IsActive()) { | ||||||
|     ToggleMenuActiveState(); |     ToggleMenuActiveState(ByKeyboard::No); | ||||||
|   } |   } | ||||||
|   return NS_OK; |   return NS_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////
 | ||||||
| MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult | MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult | ||||||
| nsMenuBarListener::HandleEvent(Event* aEvent) { | MenuBarListener::HandleEvent(Event* aEvent) { | ||||||
|   // If the menu bar is collapsed, don't do anything.
 |   // If the menu bar is collapsed, don't do anything.
 | ||||||
|   if (!mMenuBarFrame->StyleVisibility()->IsVisible()) { |   if (!mMenuBar->GetPrimaryFrame() || | ||||||
|  |       !mMenuBar->GetPrimaryFrame()->StyleVisibility()->IsVisible()) { | ||||||
|     return NS_OK; |     return NS_OK; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -495,3 +487,5 @@ nsMenuBarListener::HandleEvent(Event* aEvent) { | ||||||
|   MOZ_ASSERT_UNREACHABLE("Unexpected eventType"); |   MOZ_ASSERT_UNREACHABLE("Unexpected eventType"); | ||||||
|   return NS_OK; |   return NS_OK; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | }  // namespace mozilla::dom
 | ||||||
							
								
								
									
										83
									
								
								dom/xul/MenuBarListener.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								dom/xul/MenuBarListener.h
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,83 @@ | ||||||
|  | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | ||||||
|  | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ | ||||||
|  | /* This Source Code Form is subject to the terms of the Mozilla Public
 | ||||||
|  |  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||||
|  |  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | ||||||
|  | #ifndef mozilla_dom_MenuBarListener_h | ||||||
|  | #define mozilla_dom_MenuBarListener_h | ||||||
|  | 
 | ||||||
|  | #include "mozilla/Attributes.h" | ||||||
|  | #include "mozilla/EventForwards.h" | ||||||
|  | #include "nsIDOMEventListener.h" | ||||||
|  | #include "nsCycleCollectionParticipant.h" | ||||||
|  | #include "nsISupports.h" | ||||||
|  | 
 | ||||||
|  | namespace mozilla::dom { | ||||||
|  | class Document; | ||||||
|  | class EventTarget; | ||||||
|  | class KeyboardEvent; | ||||||
|  | class XULMenuBarElement; | ||||||
|  | class XULButtonElement; | ||||||
|  | 
 | ||||||
|  | class MenuBarListener final : public nsIDOMEventListener { | ||||||
|  |  public: | ||||||
|  |   explicit MenuBarListener(XULMenuBarElement&); | ||||||
|  | 
 | ||||||
|  |   NS_DECL_CYCLE_COLLECTING_ISUPPORTS | ||||||
|  |   NS_DECL_CYCLE_COLLECTION_CLASS(MenuBarListener) | ||||||
|  | 
 | ||||||
|  |   NS_DECL_NSIDOMEVENTLISTENER | ||||||
|  | 
 | ||||||
|  |   // Should be called when unbound from the document and so on.
 | ||||||
|  |   void Detach(); | ||||||
|  | 
 | ||||||
|  |  protected: | ||||||
|  |   virtual ~MenuBarListener(); | ||||||
|  | 
 | ||||||
|  |   bool IsMenuOpen() const; | ||||||
|  | 
 | ||||||
|  |   MOZ_CAN_RUN_SCRIPT nsresult KeyUp(Event* aMouseEvent); | ||||||
|  |   MOZ_CAN_RUN_SCRIPT nsresult KeyDown(Event* aMouseEvent); | ||||||
|  |   MOZ_CAN_RUN_SCRIPT nsresult KeyPress(Event* aMouseEvent); | ||||||
|  |   MOZ_CAN_RUN_SCRIPT nsresult Blur(Event* aEvent); | ||||||
|  |   MOZ_CAN_RUN_SCRIPT nsresult OnWindowDeactivated(Event* aEvent); | ||||||
|  |   MOZ_CAN_RUN_SCRIPT nsresult MouseDown(Event* aMouseEvent); | ||||||
|  |   MOZ_CAN_RUN_SCRIPT nsresult Fullscreen(Event* aEvent); | ||||||
|  | 
 | ||||||
|  |   /**
 | ||||||
|  |    * Given a key event for an Alt+shortcut combination, | ||||||
|  |    * return the menu, if any, that would be opened. If aPeek | ||||||
|  |    * is false, then play a beep and deactivate the menubar on Windows. | ||||||
|  |    */ | ||||||
|  |   XULButtonElement* GetMenuForKeyEvent(KeyboardEvent& aKeyEvent); | ||||||
|  | 
 | ||||||
|  |   /**
 | ||||||
|  |    * Call MarkAsReservedByChrome if the user's preferences indicate that | ||||||
|  |    * the key should be chrome-only. | ||||||
|  |    */ | ||||||
|  |   void ReserveKeyIfNeeded(Event* aKeyEvent); | ||||||
|  | 
 | ||||||
|  |   // This should only be called by the MenuBarListener during event dispatch.
 | ||||||
|  |   enum class ByKeyboard : bool { No, Yes }; | ||||||
|  |   MOZ_CAN_RUN_SCRIPT void ToggleMenuActiveState(ByKeyboard); | ||||||
|  | 
 | ||||||
|  |   bool Destroyed() const { return !mMenuBar; } | ||||||
|  | 
 | ||||||
|  |   // The menu bar object. Safe because it keeps us alive.
 | ||||||
|  |   XULMenuBarElement* mMenuBar; | ||||||
|  |   // The event target to listen to the events.
 | ||||||
|  |   //
 | ||||||
|  |   // Weak reference is safe because we clear the listener on unbind from the
 | ||||||
|  |   // document.
 | ||||||
|  |   Document* mEventTarget; | ||||||
|  |   // The top window as EventTarget.
 | ||||||
|  |   RefPtr<EventTarget> mTopWindowEventTarget; | ||||||
|  |   // Whether or not the ALT key is currently down.
 | ||||||
|  |   bool mAccessKeyDown = false; | ||||||
|  |   // Whether or not the ALT key down is canceled by other action.
 | ||||||
|  |   bool mAccessKeyDownCanceled = false; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | }  // namespace mozilla::dom
 | ||||||
|  | 
 | ||||||
|  | #endif  // #ifndef mozilla_dom_MenuBarListener_h
 | ||||||
|  | @ -18,12 +18,12 @@ | ||||||
| #include "mozilla/dom/MouseEventBinding.h" | #include "mozilla/dom/MouseEventBinding.h" | ||||||
| #include "mozilla/dom/NameSpaceConstants.h" | #include "mozilla/dom/NameSpaceConstants.h" | ||||||
| #include "mozilla/dom/AncestorIterator.h" | #include "mozilla/dom/AncestorIterator.h" | ||||||
|  | #include "mozilla/dom/XULMenuBarElement.h" | ||||||
| #include "nsGkAtoms.h" | #include "nsGkAtoms.h" | ||||||
| #include "nsITimer.h" | #include "nsITimer.h" | ||||||
| #include "nsLayoutUtils.h" | #include "nsLayoutUtils.h" | ||||||
| #include "nsCaseTreatment.h" | #include "nsCaseTreatment.h" | ||||||
| #include "nsChangeHint.h" | #include "nsChangeHint.h" | ||||||
| #include "nsMenuBarFrame.h" |  | ||||||
| #include "nsMenuPopupFrame.h" | #include "nsMenuPopupFrame.h" | ||||||
| #include "nsPlaceholderFrame.h" | #include "nsPlaceholderFrame.h" | ||||||
| #include "nsPresContext.h" | #include "nsPresContext.h" | ||||||
|  | @ -444,7 +444,8 @@ void XULButtonElement::PostHandleEventForMenus( | ||||||
|             // If we're open we never deselect. PopupClosed will do as needed.
 |             // If we're open we never deselect. PopupClosed will do as needed.
 | ||||||
|             return false; |             return false; | ||||||
|           } |           } | ||||||
|           if (!parent->IsMenuBar()) { |           auto* menubar = XULMenuBarElement::FromNode(*parent); | ||||||
|  |           if (!menubar) { | ||||||
|             // Don't de-select when not in the menubar.
 |             // Don't de-select when not in the menubar.
 | ||||||
|             // NOTE(emilio): Behavior from before bug 1811466 is equivalent to
 |             // NOTE(emilio): Behavior from before bug 1811466 is equivalent to
 | ||||||
|             // returning true here, consider flipping this.
 |             // returning true here, consider flipping this.
 | ||||||
|  | @ -452,9 +453,7 @@ void XULButtonElement::PostHandleEventForMenus( | ||||||
|           } |           } | ||||||
|           // De-select when exiting a menubar item, if the menubar wasn't
 |           // De-select when exiting a menubar item, if the menubar wasn't
 | ||||||
|           // activated by keyboard.
 |           // activated by keyboard.
 | ||||||
|           nsMenuBarFrame* menubar = do_QueryFrame(parent->GetPrimaryFrame()); |           return !menubar->IsActiveByKeyboard(); | ||||||
|           const bool openedByKey = menubar && menubar->IsActiveByKeyboard(); |  | ||||||
|           return !openedByKey; |  | ||||||
|         }(); |         }(); | ||||||
| 
 | 
 | ||||||
|         if (shouldDeactivate) { |         if (shouldDeactivate) { | ||||||
|  | @ -756,17 +755,11 @@ auto XULButtonElement::GetMenuType() const -> Maybe<MenuType> { | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| nsMenuBarFrame* XULButtonElement::GetMenuBar(FlushType aFlushType) { | XULMenuBarElement* XULButtonElement::GetMenuBar() const { | ||||||
|   if (!IsMenu()) { |   if (!IsMenu()) { | ||||||
|     return nullptr; |     return nullptr; | ||||||
|   } |   } | ||||||
|   nsIFrame* frame = GetPrimaryFrame(aFlushType); |   return FirstAncestorOfType<XULMenuBarElement>(); | ||||||
|   for (; frame; frame = frame->GetParent()) { |  | ||||||
|     if (nsMenuBarFrame* menubar = do_QueryFrame(frame)) { |  | ||||||
|       return menubar; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   return nullptr; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| XULMenuParentElement* XULButtonElement::GetMenuParent() const { | XULMenuParentElement* XULButtonElement::GetMenuParent() const { | ||||||
|  | @ -800,8 +793,8 @@ nsMenuPopupFrame* XULButtonElement::GetMenuPopup(FlushType aFlushType) { | ||||||
|   return do_QueryFrame(popup->GetPrimaryFrame(aFlushType)); |   return do_QueryFrame(popup->GetPrimaryFrame(aFlushType)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool XULButtonElement::OpenedWithKey() { | bool XULButtonElement::OpenedWithKey() const { | ||||||
|   nsMenuBarFrame* menubar = GetMenuBar(FlushType::Frames); |   auto* menubar = GetMenuBar(); | ||||||
|   return menubar && menubar->IsActiveByKeyboard(); |   return menubar && menubar->IsActiveByKeyboard(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -19,6 +19,7 @@ namespace mozilla::dom { | ||||||
| 
 | 
 | ||||||
| class KeyboardEvent; | class KeyboardEvent; | ||||||
| class XULPopupElement; | class XULPopupElement; | ||||||
|  | class XULMenuBarElement; | ||||||
| class XULMenuParentElement; | class XULMenuParentElement; | ||||||
| 
 | 
 | ||||||
| class XULButtonElement : public nsXULElement { | class XULButtonElement : public nsXULElement { | ||||||
|  | @ -57,7 +58,7 @@ class XULButtonElement : public nsXULElement { | ||||||
|   void UnbindFromTree(bool aNullParent) override; |   void UnbindFromTree(bool aNullParent) override; | ||||||
| 
 | 
 | ||||||
|   MOZ_CAN_RUN_SCRIPT bool HandleKeyPress(KeyboardEvent& keyEvent); |   MOZ_CAN_RUN_SCRIPT bool HandleKeyPress(KeyboardEvent& keyEvent); | ||||||
|   MOZ_CAN_RUN_SCRIPT bool OpenedWithKey(); |   bool OpenedWithKey() const; | ||||||
|   // Called to execute our command handler.
 |   // Called to execute our command handler.
 | ||||||
|   MOZ_CAN_RUN_SCRIPT void ExecuteMenu(WidgetEvent&); |   MOZ_CAN_RUN_SCRIPT void ExecuteMenu(WidgetEvent&); | ||||||
|   MOZ_CAN_RUN_SCRIPT void ExecuteMenu(Modifiers, int16_t aButton, |   MOZ_CAN_RUN_SCRIPT void ExecuteMenu(Modifiers, int16_t aButton, | ||||||
|  | @ -93,8 +94,8 @@ class XULButtonElement : public nsXULElement { | ||||||
|   bool IsDisabled() const { return GetXULBoolAttr(nsGkAtoms::disabled); } |   bool IsDisabled() const { return GetXULBoolAttr(nsGkAtoms::disabled); } | ||||||
| 
 | 
 | ||||||
|  private: |  private: | ||||||
|  |   XULMenuBarElement* GetMenuBar() const; | ||||||
|   void Blurred(); |   void Blurred(); | ||||||
|   nsMenuBarFrame* GetMenuBar(FlushType aFlushType); |  | ||||||
|   enum class MenuType { |   enum class MenuType { | ||||||
|     Checkbox, |     Checkbox, | ||||||
|     Radio, |     Radio, | ||||||
|  |  | ||||||
							
								
								
									
										92
									
								
								dom/xul/XULMenuBarElement.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								dom/xul/XULMenuBarElement.cpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,92 @@ | ||||||
|  | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | ||||||
|  | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ | ||||||
|  | /* This Source Code Form is subject to the terms of the Mozilla Public
 | ||||||
|  |  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||||
|  |  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | ||||||
|  | 
 | ||||||
|  | #include "XULMenuBarElement.h" | ||||||
|  | #include "MenuBarListener.h" | ||||||
|  | #include "XULButtonElement.h" | ||||||
|  | #include "nsXULPopupManager.h" | ||||||
|  | #include "mozilla/Assertions.h" | ||||||
|  | #include "mozilla/dom/BindContext.h" | ||||||
|  | #include "mozilla/AsyncEventDispatcher.h" | ||||||
|  | 
 | ||||||
|  | namespace mozilla::dom { | ||||||
|  | 
 | ||||||
|  | NS_IMPL_CYCLE_COLLECTION_INHERITED(XULMenuBarElement, XULMenuParentElement, | ||||||
|  |                                    mListener) | ||||||
|  | NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(XULMenuBarElement, | ||||||
|  |                                                XULMenuParentElement) | ||||||
|  | 
 | ||||||
|  | XULMenuBarElement::XULMenuBarElement( | ||||||
|  |     already_AddRefed<class NodeInfo>&& aNodeInfo) | ||||||
|  |     : XULMenuParentElement(std::move(aNodeInfo)) {} | ||||||
|  | 
 | ||||||
|  | XULMenuBarElement::~XULMenuBarElement() { MOZ_DIAGNOSTIC_ASSERT(!mListener); } | ||||||
|  | 
 | ||||||
|  | void XULMenuBarElement::SetActive(bool aActiveFlag) { | ||||||
|  |   // If the activity is not changed, there is nothing to do.
 | ||||||
|  |   if (mIsActive == aActiveFlag) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // We can't activate a menubar outside of the document.
 | ||||||
|  |   if (!IsInComposedDoc()) { | ||||||
|  |     MOZ_ASSERT(!mIsActive, "How?"); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if (!aActiveFlag) { | ||||||
|  |     // If there is a request to deactivate the menu bar, check to see whether
 | ||||||
|  |     // there is a menu popup open for the menu bar. In this case, don't
 | ||||||
|  |     // deactivate the menu bar.
 | ||||||
|  |     if (auto* activeChild = GetActiveMenuChild()) { | ||||||
|  |       if (activeChild->IsMenuPopupOpen()) { | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   mIsActive = aActiveFlag; | ||||||
|  |   if (nsXULPopupManager* pm = nsXULPopupManager::GetInstance()) { | ||||||
|  |     pm->SetActiveMenuBar(this, aActiveFlag); | ||||||
|  |   } | ||||||
|  |   if (!aActiveFlag) { | ||||||
|  |     mActiveByKeyboard = false; | ||||||
|  |     SetActiveMenuChild(nullptr); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   RefPtr dispatcher = new AsyncEventDispatcher( | ||||||
|  |       this, aActiveFlag ? u"DOMMenuBarActive"_ns : u"DOMMenuBarInactive"_ns, | ||||||
|  |       CanBubble::eYes, ChromeOnlyDispatch::eNo); | ||||||
|  |   DebugOnly<nsresult> rv = dispatcher->PostDOMEvent(); | ||||||
|  |   NS_ASSERTION(NS_SUCCEEDED(rv), "AsyncEventDispatcher failed to dispatch"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | nsresult XULMenuBarElement::BindToTree(BindContext& aContext, | ||||||
|  |                                        nsINode& aParent) { | ||||||
|  |   MOZ_TRY(XULMenuParentElement::BindToTree(aContext, aParent)); | ||||||
|  |   MOZ_DIAGNOSTIC_ASSERT(!mListener); | ||||||
|  |   if (aContext.InComposedDoc()) { | ||||||
|  |     mListener = new MenuBarListener(*this); | ||||||
|  |   } | ||||||
|  |   return NS_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void XULMenuBarElement::UnbindFromTree(bool aNullParent) { | ||||||
|  |   if (mListener) { | ||||||
|  |     mListener->Detach(); | ||||||
|  |     mListener = nullptr; | ||||||
|  |   } | ||||||
|  |   if (NS_WARN_IF(mIsActive)) { | ||||||
|  |     // Clean up silently when getting removed from the document while active.
 | ||||||
|  |     mIsActive = false; | ||||||
|  |     if (nsXULPopupManager* pm = nsXULPopupManager::GetInstance()) { | ||||||
|  |       pm->SetActiveMenuBar(this, false); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return XULMenuParentElement::UnbindFromTree(aNullParent); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | }  // namespace mozilla::dom
 | ||||||
							
								
								
									
										61
									
								
								dom/xul/XULMenuBarElement.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								dom/xul/XULMenuBarElement.h
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,61 @@ | ||||||
|  | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | ||||||
|  | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ | ||||||
|  | /* This Source Code Form is subject to the terms of the Mozilla Public
 | ||||||
|  |  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||||
|  |  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | ||||||
|  | 
 | ||||||
|  | #ifndef XULMenuBarElement_h__ | ||||||
|  | #define XULMenuBarElement_h__ | ||||||
|  | 
 | ||||||
|  | #include "mozilla/Attributes.h" | ||||||
|  | #include "mozilla/dom/NameSpaceConstants.h" | ||||||
|  | #include "nsINode.h" | ||||||
|  | #include "nsISupports.h" | ||||||
|  | #include "XULMenuParentElement.h" | ||||||
|  | 
 | ||||||
|  | namespace mozilla::dom { | ||||||
|  | 
 | ||||||
|  | class KeyboardEvent; | ||||||
|  | class XULButtonElement; | ||||||
|  | class MenuBarListener; | ||||||
|  | 
 | ||||||
|  | nsXULElement* NS_NewXULMenuBarElement( | ||||||
|  |     already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo); | ||||||
|  | 
 | ||||||
|  | class XULMenuBarElement final : public XULMenuParentElement { | ||||||
|  |  public: | ||||||
|  |   NS_DECL_ISUPPORTS_INHERITED | ||||||
|  |   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(XULMenuBarElement, | ||||||
|  |                                            XULMenuParentElement) | ||||||
|  |   NS_IMPL_FROMNODE_WITH_TAG(XULMenuBarElement, kNameSpaceID_XUL, menubar) | ||||||
|  | 
 | ||||||
|  |   explicit XULMenuBarElement(already_AddRefed<class NodeInfo>&&); | ||||||
|  | 
 | ||||||
|  |   MOZ_CAN_RUN_SCRIPT void SetActive(bool); | ||||||
|  |   bool IsActive() const { return mIsActive; } | ||||||
|  | 
 | ||||||
|  |   void SetActiveByKeyboard() { mActiveByKeyboard = true; } | ||||||
|  |   bool IsActiveByKeyboard() const { return mActiveByKeyboard; } | ||||||
|  | 
 | ||||||
|  |   MOZ_CAN_RUN_SCRIPT void MenuClosed() { SetActive(false); } | ||||||
|  | 
 | ||||||
|  |   nsresult BindToTree(BindContext&, nsINode& aParent) override; | ||||||
|  |   void UnbindFromTree(bool aNullParent) override; | ||||||
|  | 
 | ||||||
|  |  protected: | ||||||
|  |   ~XULMenuBarElement() override; | ||||||
|  | 
 | ||||||
|  |   // Whether or not the menu bar is active (a menu item is highlighted or
 | ||||||
|  |   // shown).
 | ||||||
|  |   bool mIsActive = false; | ||||||
|  | 
 | ||||||
|  |   // Whether the menubar was made active via the keyboard.
 | ||||||
|  |   bool mActiveByKeyboard = false; | ||||||
|  | 
 | ||||||
|  |   // The event listener that listens to document key presses and so on.
 | ||||||
|  |   RefPtr<MenuBarListener> mListener; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | }  // namespace mozilla::dom
 | ||||||
|  | 
 | ||||||
|  | #endif  // XULMenuBarElement_h
 | ||||||
|  | @ -11,7 +11,6 @@ | ||||||
| #include "mozilla/dom/XULPopupElement.h" | #include "mozilla/dom/XULPopupElement.h" | ||||||
| #include "mozilla/dom/KeyboardEvent.h" | #include "mozilla/dom/KeyboardEvent.h" | ||||||
| #include "mozilla/dom/KeyboardEventBinding.h" | #include "mozilla/dom/KeyboardEventBinding.h" | ||||||
| #include "nsMenuBarListener.h" |  | ||||||
| #include "nsXULPopupManager.h" | #include "nsXULPopupManager.h" | ||||||
| #include "nsMenuPopupFrame.h" | #include "nsMenuPopupFrame.h" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -5,20 +5,20 @@ | ||||||
| 
 | 
 | ||||||
| #include "XULMenuParentElement.h" | #include "XULMenuParentElement.h" | ||||||
| #include "XULButtonElement.h" | #include "XULButtonElement.h" | ||||||
|  | #include "XULMenuBarElement.h" | ||||||
| #include "XULPopupElement.h" | #include "XULPopupElement.h" | ||||||
| #include "mozilla/LookAndFeel.h" | #include "mozilla/LookAndFeel.h" | ||||||
|  | #include "mozilla/StaticAnalysisFunctions.h" | ||||||
| #include "mozilla/TextEvents.h" | #include "mozilla/TextEvents.h" | ||||||
| #include "mozilla/dom/DocumentInlines.h" | #include "mozilla/dom/DocumentInlines.h" | ||||||
| #include "mozilla/dom/KeyboardEvent.h" | #include "mozilla/dom/KeyboardEvent.h" | ||||||
| #include "mozilla/EventDispatcher.h" | #include "mozilla/EventDispatcher.h" | ||||||
| #include "nsDebug.h" | #include "nsDebug.h" | ||||||
| #include "nsMenuBarFrame.h" |  | ||||||
| #include "nsMenuPopupFrame.h" | #include "nsMenuPopupFrame.h" | ||||||
| #include "nsString.h" | #include "nsString.h" | ||||||
| #include "nsStringFwd.h" | #include "nsStringFwd.h" | ||||||
| #include "nsUTF8Utils.h" | #include "nsUTF8Utils.h" | ||||||
| #include "nsXULElement.h" | #include "nsXULElement.h" | ||||||
| #include "nsMenuBarListener.h" |  | ||||||
| #include "nsXULPopupManager.h" | #include "nsXULPopupManager.h" | ||||||
| 
 | 
 | ||||||
| namespace mozilla::dom { | namespace mozilla::dom { | ||||||
|  | @ -127,8 +127,9 @@ void XULMenuParentElement::SetActiveMenuChild(XULButtonElement* aChild, | ||||||
|   } |   } | ||||||
|   mActiveItem = nullptr; |   mActiveItem = nullptr; | ||||||
| 
 | 
 | ||||||
|   if (nsMenuBarFrame* f = do_QueryFrame(GetPrimaryFrame())) { |   if (auto* menuBar = XULMenuBarElement::FromNode(*this)) { | ||||||
|     f->SetActive(!!aChild); |     // KnownLive because `this` is known-live by definition.
 | ||||||
|  |     MOZ_KnownLive(menuBar)->SetActive(!!aChild); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (!aChild) { |   if (!aChild) { | ||||||
|  | @ -388,4 +389,10 @@ XULButtonElement* XULMenuParentElement::FindMenuWithShortcut( | ||||||
|   return foundMenuBeforeCurrent; |   return foundMenuBeforeCurrent; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void XULMenuParentElement::HandleEnterKeyPress(WidgetEvent& aEvent) { | ||||||
|  |   if (RefPtr child = GetActiveMenuChild()) { | ||||||
|  |     child->HandleEnterKeyPress(aEvent); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| }  // namespace mozilla::dom
 | }  // namespace mozilla::dom
 | ||||||
|  |  | ||||||
|  | @ -41,6 +41,7 @@ class XULMenuParentElement : public nsXULElement { | ||||||
|   XULButtonElement* FindMenuWithShortcut(KeyboardEvent&) const; |   XULButtonElement* FindMenuWithShortcut(KeyboardEvent&) const; | ||||||
|   XULButtonElement* FindMenuWithShortcut(const nsAString& aString, |   XULButtonElement* FindMenuWithShortcut(const nsAString& aString, | ||||||
|                                          bool& aDoAction) const; |                                          bool& aDoAction) const; | ||||||
|  |   MOZ_CAN_RUN_SCRIPT void HandleEnterKeyPress(WidgetEvent&); | ||||||
| 
 | 
 | ||||||
|   NS_IMPL_FROMNODE_HELPER(XULMenuParentElement, |   NS_IMPL_FROMNODE_HELPER(XULMenuParentElement, | ||||||
|                           IsAnyOfXULElements(nsGkAtoms::menupopup, |                           IsAnyOfXULElements(nsGkAtoms::menupopup, | ||||||
|  |  | ||||||
|  | @ -7,7 +7,6 @@ | ||||||
| #include "XULMenuParentElement.h" | #include "XULMenuParentElement.h" | ||||||
| #include "nsCOMPtr.h" | #include "nsCOMPtr.h" | ||||||
| #include "nsIContent.h" | #include "nsIContent.h" | ||||||
| #include "nsMenuBarListener.h" |  | ||||||
| #include "nsNameSpaceManager.h" | #include "nsNameSpaceManager.h" | ||||||
| #include "nsGkAtoms.h" | #include "nsGkAtoms.h" | ||||||
| #include "nsMenuPopupFrame.h" | #include "nsMenuPopupFrame.h" | ||||||
|  |  | ||||||
|  | @ -24,6 +24,7 @@ EXPORTS.mozilla.dom += [ | ||||||
|     "XULBroadcastManager.h", |     "XULBroadcastManager.h", | ||||||
|     "XULButtonElement.h", |     "XULButtonElement.h", | ||||||
|     "XULFrameElement.h", |     "XULFrameElement.h", | ||||||
|  |     "XULMenuBarElement.h", | ||||||
|     "XULMenuElement.h", |     "XULMenuElement.h", | ||||||
|     "XULMenuParentElement.h", |     "XULMenuParentElement.h", | ||||||
|     "XULPersist.h", |     "XULPersist.h", | ||||||
|  | @ -35,6 +36,7 @@ EXPORTS.mozilla.dom += [ | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
| UNIFIED_SOURCES += [ | UNIFIED_SOURCES += [ | ||||||
|  |     "MenuBarListener.cpp", | ||||||
|     "nsXULCommandDispatcher.cpp", |     "nsXULCommandDispatcher.cpp", | ||||||
|     "nsXULContentSink.cpp", |     "nsXULContentSink.cpp", | ||||||
|     "nsXULContentUtils.cpp", |     "nsXULContentUtils.cpp", | ||||||
|  | @ -46,6 +48,7 @@ UNIFIED_SOURCES += [ | ||||||
|     "XULBroadcastManager.cpp", |     "XULBroadcastManager.cpp", | ||||||
|     "XULButtonElement.cpp", |     "XULButtonElement.cpp", | ||||||
|     "XULFrameElement.cpp", |     "XULFrameElement.cpp", | ||||||
|  |     "XULMenuBarElement.cpp", | ||||||
|     "XULMenuElement.cpp", |     "XULMenuElement.cpp", | ||||||
|     "XULMenuParentElement.cpp", |     "XULMenuParentElement.cpp", | ||||||
|     "XULPersist.cpp", |     "XULPersist.cpp", | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ | ||||||
| #include "XULButtonElement.h" | #include "XULButtonElement.h" | ||||||
| #include "XULFrameElement.h" | #include "XULFrameElement.h" | ||||||
| #include "XULMenuElement.h" | #include "XULMenuElement.h" | ||||||
|  | #include "XULMenuBarElement.h" | ||||||
| #include "XULPopupElement.h" | #include "XULPopupElement.h" | ||||||
| #include "XULResizerElement.h" | #include "XULResizerElement.h" | ||||||
| #include "XULTextElement.h" | #include "XULTextElement.h" | ||||||
|  | @ -185,7 +186,7 @@ nsXULElement* nsXULElement::Construct( | ||||||
| 
 | 
 | ||||||
|   if (nodeInfo->Equals(nsGkAtoms::menubar)) { |   if (nodeInfo->Equals(nsGkAtoms::menubar)) { | ||||||
|     auto* nim = nodeInfo->NodeInfoManager(); |     auto* nim = nodeInfo->NodeInfoManager(); | ||||||
|     return new (nim) XULMenuParentElement(nodeInfo.forget()); |     return new (nim) XULMenuBarElement(nodeInfo.forget()); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (nodeInfo->Equals(nsGkAtoms::menu) || |   if (nodeInfo->Equals(nsGkAtoms::menu) || | ||||||
|  |  | ||||||
|  | @ -39,7 +39,6 @@ | ||||||
| #include "mozilla/Unused.h" | #include "mozilla/Unused.h" | ||||||
| #include "RetainedDisplayListBuilder.h" | #include "RetainedDisplayListBuilder.h" | ||||||
| #include "nsAbsoluteContainingBlock.h" | #include "nsAbsoluteContainingBlock.h" | ||||||
| #include "nsMenuBarListener.h" |  | ||||||
| #include "nsCSSPseudoElements.h" | #include "nsCSSPseudoElements.h" | ||||||
| #include "nsCheckboxRadioFrame.h" | #include "nsCheckboxRadioFrame.h" | ||||||
| #include "nsCRT.h" | #include "nsCRT.h" | ||||||
|  | @ -221,8 +220,6 @@ nsIFrame* NS_NewMenuPopupFrame(PresShell* aPresShell, ComputedStyle* aStyle); | ||||||
| nsIFrame* NS_NewMenuFrame(PresShell* aPresShell, ComputedStyle* aStyle, | nsIFrame* NS_NewMenuFrame(PresShell* aPresShell, ComputedStyle* aStyle, | ||||||
|                           uint32_t aFlags); |                           uint32_t aFlags); | ||||||
| 
 | 
 | ||||||
| nsIFrame* NS_NewMenuBarFrame(PresShell* aPresShell, ComputedStyle* aStyle); |  | ||||||
| 
 |  | ||||||
| nsIFrame* NS_NewTreeBodyFrame(PresShell* aPresShell, ComputedStyle* aStyle); | nsIFrame* NS_NewTreeBodyFrame(PresShell* aPresShell, ComputedStyle* aStyle); | ||||||
| 
 | 
 | ||||||
| nsHTMLScrollFrame* NS_NewHTMLScrollFrame(PresShell* aPresShell, | nsHTMLScrollFrame* NS_NewHTMLScrollFrame(PresShell* aPresShell, | ||||||
|  | @ -4155,8 +4152,6 @@ nsCSSFrameConstructor::FindXULTagData(const Element& aElement, | ||||||
|                        nsCSSFrameConstructor::FindXULLabelOrDescriptionData), |                        nsCSSFrameConstructor::FindXULLabelOrDescriptionData), | ||||||
| #ifdef XP_MACOSX | #ifdef XP_MACOSX | ||||||
|       SIMPLE_TAG_CHAIN(menubar, nsCSSFrameConstructor::FindXULMenubarData), |       SIMPLE_TAG_CHAIN(menubar, nsCSSFrameConstructor::FindXULMenubarData), | ||||||
| #else |  | ||||||
|       SIMPLE_XUL_CREATE(menubar, NS_NewMenuBarFrame), |  | ||||||
| #endif /* XP_MACOSX */ | #endif /* XP_MACOSX */ | ||||||
|       SIMPLE_XUL_CREATE(iframe, NS_NewSubDocumentFrame), |       SIMPLE_XUL_CREATE(iframe, NS_NewSubDocumentFrame), | ||||||
|       SIMPLE_XUL_CREATE(editor, NS_NewSubDocumentFrame), |       SIMPLE_XUL_CREATE(editor, NS_NewSubDocumentFrame), | ||||||
|  | @ -4209,9 +4204,7 @@ nsCSSFrameConstructor::FindXULMenubarData(const Element& aElement, | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   static constexpr FrameConstructionData sMenubarData = |   return nullptr; | ||||||
|       SIMPLE_XUL_FCDATA(NS_NewMenuBarFrame); |  | ||||||
|   return &sMenubarData; |  | ||||||
| } | } | ||||||
| #endif /* XP_MACOSX */ | #endif /* XP_MACOSX */ | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -63,7 +63,6 @@ FRAME_CLASSES = [ | ||||||
|     Frame("nsMathMLmunderoverFrame", "None", NOT_LEAF), |     Frame("nsMathMLmunderoverFrame", "None", NOT_LEAF), | ||||||
|     Frame("nsMathMLsemanticsFrame", "None", NOT_LEAF), |     Frame("nsMathMLsemanticsFrame", "None", NOT_LEAF), | ||||||
|     Frame("nsMathMLTokenFrame", "None", NOT_LEAF), |     Frame("nsMathMLTokenFrame", "None", NOT_LEAF), | ||||||
|     Frame("nsMenuBarFrame", "Box", NOT_LEAF), |  | ||||||
|     Frame("nsMenuPopupFrame", "MenuPopup", NOT_LEAF), |     Frame("nsMenuPopupFrame", "MenuPopup", NOT_LEAF), | ||||||
|     Frame("nsMeterFrame", "Meter", LEAF), |     Frame("nsMeterFrame", "Meter", LEAF), | ||||||
|     Frame("nsNumberControlFrame", "TextInput", LEAF), |     Frame("nsNumberControlFrame", "TextInput", LEAF), | ||||||
|  |  | ||||||
|  | @ -25,8 +25,6 @@ UNIFIED_SOURCES += [ | ||||||
|     "nsBoxLayoutState.cpp", |     "nsBoxLayoutState.cpp", | ||||||
|     "nsImageBoxFrame.cpp", |     "nsImageBoxFrame.cpp", | ||||||
|     "nsLeafBoxFrame.cpp", |     "nsLeafBoxFrame.cpp", | ||||||
|     "nsMenuBarFrame.cpp", |  | ||||||
|     "nsMenuBarListener.cpp", |  | ||||||
|     "nsMenuPopupFrame.cpp", |     "nsMenuPopupFrame.cpp", | ||||||
|     "nsRepeatService.cpp", |     "nsRepeatService.cpp", | ||||||
|     "nsScrollbarButtonFrame.cpp", |     "nsScrollbarButtonFrame.cpp", | ||||||
|  |  | ||||||
|  | @ -1,136 +0,0 @@ | ||||||
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |  | ||||||
| /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |  | ||||||
| /* This Source Code Form is subject to the terms of the Mozilla Public
 |  | ||||||
|  * License, v. 2.0. If a copy of the MPL was not distributed with this |  | ||||||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 |  | ||||||
| 
 |  | ||||||
| #include "nsMenuBarFrame.h" |  | ||||||
| #include "mozilla/BasicEvents.h" |  | ||||||
| #include "nsIContent.h" |  | ||||||
| #include "nsAtom.h" |  | ||||||
| #include "nsPresContext.h" |  | ||||||
| #include "nsCSSRendering.h" |  | ||||||
| #include "nsNameSpaceManager.h" |  | ||||||
| #include "nsGkAtoms.h" |  | ||||||
| #include "nsMenuPopupFrame.h" |  | ||||||
| #include "nsUnicharUtils.h" |  | ||||||
| #include "nsPIDOMWindow.h" |  | ||||||
| #include "nsIInterfaceRequestorUtils.h" |  | ||||||
| #include "nsCSSFrameConstructor.h" |  | ||||||
| #ifdef XP_WIN |  | ||||||
| #  include "nsISound.h" |  | ||||||
| #  include "nsWidgetsCID.h" |  | ||||||
| #endif |  | ||||||
| #include "nsUTF8Utils.h" |  | ||||||
| #include "mozilla/ComputedStyle.h" |  | ||||||
| #include "mozilla/PresShell.h" |  | ||||||
| #include "mozilla/dom/Document.h" |  | ||||||
| #include "mozilla/dom/XULMenuParentElement.h" |  | ||||||
| #include "mozilla/dom/XULButtonElement.h" |  | ||||||
| 
 |  | ||||||
| using namespace mozilla; |  | ||||||
| 
 |  | ||||||
| //
 |  | ||||||
| // NS_NewMenuBarFrame
 |  | ||||||
| //
 |  | ||||||
| // Wrapper for creating a new menu Bar container
 |  | ||||||
| //
 |  | ||||||
| nsIFrame* NS_NewMenuBarFrame(PresShell* aPresShell, ComputedStyle* aStyle) { |  | ||||||
|   return new (aPresShell) nsMenuBarFrame(aStyle, aPresShell->GetPresContext()); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| NS_IMPL_FRAMEARENA_HELPERS(nsMenuBarFrame) |  | ||||||
| 
 |  | ||||||
| NS_QUERYFRAME_HEAD(nsMenuBarFrame) |  | ||||||
|   NS_QUERYFRAME_ENTRY(nsMenuBarFrame) |  | ||||||
| NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame) |  | ||||||
| 
 |  | ||||||
| //
 |  | ||||||
| // nsMenuBarFrame cntr
 |  | ||||||
| //
 |  | ||||||
| nsMenuBarFrame::nsMenuBarFrame(ComputedStyle* aStyle, |  | ||||||
|                                nsPresContext* aPresContext) |  | ||||||
|     : nsBoxFrame(aStyle, aPresContext, kClassID) {} |  | ||||||
| 
 |  | ||||||
| void nsMenuBarFrame::Init(nsIContent* aContent, nsContainerFrame* aParent, |  | ||||||
|                           nsIFrame* aPrevInFlow) { |  | ||||||
|   nsBoxFrame::Init(aContent, aParent, aPrevInFlow); |  | ||||||
| 
 |  | ||||||
|   // Create the menu bar listener.
 |  | ||||||
|   mMenuBarListener = new nsMenuBarListener(this, aContent); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| dom::XULMenuParentElement& nsMenuBarFrame::MenubarElement() const { |  | ||||||
|   auto* content = dom::XULMenuParentElement::FromNode(GetContent()); |  | ||||||
|   MOZ_DIAGNOSTIC_ASSERT(content); |  | ||||||
|   return *content; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| MOZ_CAN_RUN_SCRIPT void nsMenuBarFrame::SetActive(bool aActiveFlag) { |  | ||||||
|   // If the activity is not changed, there is nothing to do.
 |  | ||||||
|   if (mIsActive == aActiveFlag) { |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   if (!aActiveFlag) { |  | ||||||
|     // If there is a request to deactivate the menu bar, check to see whether
 |  | ||||||
|     // there is a menu popup open for the menu bar. In this case, don't
 |  | ||||||
|     // deactivate the menu bar.
 |  | ||||||
|     if (auto* activeChild = MenubarElement().GetActiveMenuChild()) { |  | ||||||
|       if (activeChild->IsMenuPopupOpen()) { |  | ||||||
|         return; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   mIsActive = aActiveFlag; |  | ||||||
|   if (mIsActive) { |  | ||||||
|     InstallKeyboardNavigator(); |  | ||||||
|   } else { |  | ||||||
|     mActiveByKeyboard = false; |  | ||||||
|     RemoveKeyboardNavigator(); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   RefPtr menubar = &MenubarElement(); |  | ||||||
|   if (!aActiveFlag) { |  | ||||||
|     menubar->SetActiveMenuChild(nullptr); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   constexpr auto active = u"DOMMenuBarActive"_ns; |  | ||||||
|   constexpr auto inactive = u"DOMMenuBarInactive"_ns; |  | ||||||
|   FireDOMEvent(aActiveFlag ? active : inactive, menubar); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void nsMenuBarFrame::InstallKeyboardNavigator() { |  | ||||||
|   if (nsXULPopupManager* pm = nsXULPopupManager::GetInstance()) { |  | ||||||
|     pm->SetActiveMenuBar(this, true); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void nsMenuBarFrame::MenuClosed() { SetActive(false); } |  | ||||||
| 
 |  | ||||||
| void nsMenuBarFrame::HandleEnterKeyPress(WidgetEvent& aEvent) { |  | ||||||
|   if (RefPtr<dom::XULButtonElement> activeChild = |  | ||||||
|           MenubarElement().GetActiveMenuChild()) { |  | ||||||
|     activeChild->HandleEnterKeyPress(aEvent); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void nsMenuBarFrame::RemoveKeyboardNavigator() { |  | ||||||
|   if (!mIsActive) { |  | ||||||
|     if (nsXULPopupManager* pm = nsXULPopupManager::GetInstance()) { |  | ||||||
|       pm->SetActiveMenuBar(this, false); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void nsMenuBarFrame::DestroyFrom(nsIFrame* aDestructRoot, |  | ||||||
|                                  PostDestroyData& aPostDestroyData) { |  | ||||||
|   nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); |  | ||||||
|   if (pm) pm->SetActiveMenuBar(this, false); |  | ||||||
| 
 |  | ||||||
|   mMenuBarListener->OnDestroyMenuBarFrame(); |  | ||||||
|   mMenuBarListener = nullptr; |  | ||||||
| 
 |  | ||||||
|   nsBoxFrame::DestroyFrom(aDestructRoot, aPostDestroyData); |  | ||||||
| } |  | ||||||
|  | @ -1,83 +0,0 @@ | ||||||
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |  | ||||||
| /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |  | ||||||
| /* This Source Code Form is subject to the terms of the Mozilla Public
 |  | ||||||
|  * License, v. 2.0. If a copy of the MPL was not distributed with this |  | ||||||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 |  | ||||||
| 
 |  | ||||||
| //
 |  | ||||||
| // nsMenuBarFrame
 |  | ||||||
| //
 |  | ||||||
| 
 |  | ||||||
| #ifndef nsMenuBarFrame_h__ |  | ||||||
| #define nsMenuBarFrame_h__ |  | ||||||
| 
 |  | ||||||
| #include "nsAtom.h" |  | ||||||
| #include "nsCOMPtr.h" |  | ||||||
| #include "nsBoxFrame.h" |  | ||||||
| #include "nsMenuBarListener.h" |  | ||||||
| 
 |  | ||||||
| class nsIContent; |  | ||||||
| 
 |  | ||||||
| namespace mozilla { |  | ||||||
| class PresShell; |  | ||||||
| namespace dom { |  | ||||||
| class KeyboardEvent; |  | ||||||
| class XULMenuParentElement; |  | ||||||
| }  // namespace dom
 |  | ||||||
| }  // namespace mozilla
 |  | ||||||
| 
 |  | ||||||
| nsIFrame* NS_NewMenuBarFrame(mozilla::PresShell* aPresShell, |  | ||||||
|                              mozilla::ComputedStyle* aStyle); |  | ||||||
| 
 |  | ||||||
| class nsMenuBarFrame final : public nsBoxFrame { |  | ||||||
|  public: |  | ||||||
|   NS_DECL_QUERYFRAME |  | ||||||
|   NS_DECL_FRAMEARENA_HELPERS(nsMenuBarFrame) |  | ||||||
| 
 |  | ||||||
|   explicit nsMenuBarFrame(ComputedStyle* aStyle, nsPresContext* aPresContext); |  | ||||||
| 
 |  | ||||||
|   void InstallKeyboardNavigator(); |  | ||||||
|   void RemoveKeyboardNavigator(); |  | ||||||
|   MOZ_CAN_RUN_SCRIPT void MenuClosed(); |  | ||||||
| 
 |  | ||||||
|   void Init(nsIContent* aContent, nsContainerFrame* aParent, |  | ||||||
|             nsIFrame* aPrevInFlow) override; |  | ||||||
| 
 |  | ||||||
|   void DestroyFrom(nsIFrame* aDestructRoot, |  | ||||||
|                    PostDestroyData& aPostDestroyData) override; |  | ||||||
| 
 |  | ||||||
|   bool IsActiveByKeyboard() { return mActiveByKeyboard; } |  | ||||||
|   void SetActiveByKeyboard() { mActiveByKeyboard = true; } |  | ||||||
|   MOZ_CAN_RUN_SCRIPT void SetActive(bool aActive); |  | ||||||
|   bool IsActive() const { return mIsActive; } |  | ||||||
| 
 |  | ||||||
|   mozilla::dom::XULMenuParentElement& MenubarElement() const; |  | ||||||
| 
 |  | ||||||
|   // Called when Enter is pressed while the menubar is focused. If the current
 |  | ||||||
|   // menu is open, let the child handle the key.
 |  | ||||||
|   MOZ_CAN_RUN_SCRIPT void HandleEnterKeyPress(mozilla::WidgetEvent&); |  | ||||||
| 
 |  | ||||||
|   bool IsFrameOfType(uint32_t aFlags) const override { |  | ||||||
|     // Override bogus IsFrameOfType in nsBoxFrame.
 |  | ||||||
|     if (aFlags & (nsIFrame::eReplacedContainsBlock | nsIFrame::eReplaced)) |  | ||||||
|       return false; |  | ||||||
|     return nsBoxFrame::IsFrameOfType(aFlags); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
| #ifdef DEBUG_FRAME_DUMP |  | ||||||
|   nsresult GetFrameName(nsAString& aResult) const override { |  | ||||||
|     return MakeFrameName(u"MenuBar"_ns, aResult); |  | ||||||
|   } |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
|  protected: |  | ||||||
|   RefPtr<nsMenuBarListener> mMenuBarListener;  // The listener that tells us
 |  | ||||||
|                                                // about key and mouse events.
 |  | ||||||
| 
 |  | ||||||
|   bool mIsActive = false;  // Whether or not the menu bar is active (a menu item
 |  | ||||||
|                            // is highlighted or shown).
 |  | ||||||
|   // Whether the menubar was made active via the keyboard.
 |  | ||||||
|   bool mActiveByKeyboard = false; |  | ||||||
| };  // class nsMenuBarFrame
 |  | ||||||
| 
 |  | ||||||
| #endif |  | ||||||
|  | @ -1,100 +0,0 @@ | ||||||
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |  | ||||||
| /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |  | ||||||
| /* This Source Code Form is subject to the terms of the Mozilla Public
 |  | ||||||
|  * License, v. 2.0. If a copy of the MPL was not distributed with this |  | ||||||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 |  | ||||||
| #ifndef nsMenuBarListener_h |  | ||||||
| #define nsMenuBarListener_h |  | ||||||
| 
 |  | ||||||
| #include "mozilla/Attributes.h" |  | ||||||
| #include "mozilla/EventForwards.h" |  | ||||||
| #include "nsIContent.h" |  | ||||||
| #include "nsIDOMEventListener.h" |  | ||||||
| 
 |  | ||||||
| // X.h defines KeyPress
 |  | ||||||
| #ifdef KeyPress |  | ||||||
| #  undef KeyPress |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| class nsMenuFrame; |  | ||||||
| class nsMenuBarFrame; |  | ||||||
| 
 |  | ||||||
| namespace mozilla { |  | ||||||
| namespace dom { |  | ||||||
| class EventTarget; |  | ||||||
| class KeyboardEvent; |  | ||||||
| class XULMenuParentElement; |  | ||||||
| class XULButtonElement; |  | ||||||
| }  // namespace dom
 |  | ||||||
| }  // namespace mozilla
 |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * EventListener implementation for menubar. |  | ||||||
|  */ |  | ||||||
| class nsMenuBarListener final : public nsIDOMEventListener { |  | ||||||
|  public: |  | ||||||
|   explicit nsMenuBarListener(nsMenuBarFrame* aMenuBarFrame, |  | ||||||
|                              nsIContent* aMenuBarContent); |  | ||||||
| 
 |  | ||||||
|   NS_DECL_ISUPPORTS |  | ||||||
| 
 |  | ||||||
|   /**
 |  | ||||||
|    * nsIDOMEventListener interface method. |  | ||||||
|    */ |  | ||||||
|   NS_DECL_NSIDOMEVENTLISTENER |  | ||||||
| 
 |  | ||||||
|   /**
 |  | ||||||
|    * When mMenuBarFrame is being destroyed, this should be called. |  | ||||||
|    */ |  | ||||||
|   void OnDestroyMenuBarFrame(); |  | ||||||
| 
 |  | ||||||
|  protected: |  | ||||||
|   virtual ~nsMenuBarListener(); |  | ||||||
| 
 |  | ||||||
|   bool IsMenuOpen() const; |  | ||||||
| 
 |  | ||||||
|   MOZ_CAN_RUN_SCRIPT nsresult KeyUp(mozilla::dom::Event* aMouseEvent); |  | ||||||
|   MOZ_CAN_RUN_SCRIPT nsresult KeyDown(mozilla::dom::Event* aMouseEvent); |  | ||||||
|   MOZ_CAN_RUN_SCRIPT nsresult KeyPress(mozilla::dom::Event* aMouseEvent); |  | ||||||
|   MOZ_CAN_RUN_SCRIPT nsresult Blur(mozilla::dom::Event* aEvent); |  | ||||||
|   MOZ_CAN_RUN_SCRIPT nsresult OnWindowDeactivated(mozilla::dom::Event* aEvent); |  | ||||||
|   MOZ_CAN_RUN_SCRIPT nsresult MouseDown(mozilla::dom::Event* aMouseEvent); |  | ||||||
|   MOZ_CAN_RUN_SCRIPT nsresult Fullscreen(mozilla::dom::Event* aEvent); |  | ||||||
| 
 |  | ||||||
|   /**
 |  | ||||||
|    * Given a key event for an Alt+shortcut combination, |  | ||||||
|    * return the menu, if any, that would be opened. If aPeek |  | ||||||
|    * is false, then play a beep and deactivate the menubar on Windows. |  | ||||||
|    */ |  | ||||||
|   mozilla::dom::XULButtonElement* GetMenuForKeyEvent( |  | ||||||
|       mozilla::dom::KeyboardEvent& aKeyEvent); |  | ||||||
| 
 |  | ||||||
|   /**
 |  | ||||||
|    * Call MarkAsReservedByChrome if the user's preferences indicate that |  | ||||||
|    * the key should be chrome-only. |  | ||||||
|    */ |  | ||||||
|   void ReserveKeyIfNeeded(mozilla::dom::Event* aKeyEvent); |  | ||||||
| 
 |  | ||||||
|   // This should only be called by the nsMenuBarListener during event dispatch,
 |  | ||||||
|   // thus ensuring that this doesn't get destroyed during the process.
 |  | ||||||
|   MOZ_CAN_RUN_SCRIPT void ToggleMenuActiveState(); |  | ||||||
| 
 |  | ||||||
|   bool Destroyed() const { return !mMenuBarFrame; } |  | ||||||
| 
 |  | ||||||
|   // The menu bar object.
 |  | ||||||
|   nsMenuBarFrame* mMenuBarFrame; |  | ||||||
|   mozilla::dom::XULMenuParentElement* mContent; |  | ||||||
|   // The event target to listen to the events.
 |  | ||||||
|   // XXX Should this store this as strong reference?  However,
 |  | ||||||
|   //     OnDestroyMenuBarFrame() should be called at destroying mMenuBarFrame.
 |  | ||||||
|   //     So, weak reference must be safe.
 |  | ||||||
|   mozilla::dom::EventTarget* mEventTarget; |  | ||||||
|   // The top window as EventTarget.
 |  | ||||||
|   mozilla::dom::EventTarget* mTopWindowEventTarget; |  | ||||||
|   // Whether or not the ALT key is currently down.
 |  | ||||||
|   bool mAccessKeyDown; |  | ||||||
|   // Whether or not the ALT key down is canceled by other action.
 |  | ||||||
|   bool mAccessKeyDownCanceled; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| #endif  // #ifndef nsMenuBarListener_h
 |  | ||||||
|  | @ -19,7 +19,6 @@ | ||||||
| #include "nsIFrameInlines.h" | #include "nsIFrameInlines.h" | ||||||
| #include "nsViewManager.h" | #include "nsViewManager.h" | ||||||
| #include "nsWidgetsCID.h" | #include "nsWidgetsCID.h" | ||||||
| #include "nsMenuBarFrame.h" |  | ||||||
| #include "nsPIDOMWindow.h" | #include "nsPIDOMWindow.h" | ||||||
| #include "nsFrameManager.h" | #include "nsFrameManager.h" | ||||||
| #include "mozilla/dom/Document.h" | #include "mozilla/dom/Document.h" | ||||||
|  | @ -2028,10 +2027,8 @@ nsIFrame* nsMenuPopupFrame::GetCurrentMenuItemFrame() const { | ||||||
| 
 | 
 | ||||||
| void nsMenuPopupFrame::HandleEnterKeyPress(WidgetEvent& aEvent) { | void nsMenuPopupFrame::HandleEnterKeyPress(WidgetEvent& aEvent) { | ||||||
|   mIncrementalString.Truncate(); |   mIncrementalString.Truncate(); | ||||||
|   if (RefPtr menu = GetCurrentMenuItem()) { |   RefPtr popup = &PopupElement(); | ||||||
|     // Give it to the child.
 |   popup->HandleEnterKeyPress(aEvent); | ||||||
|     menu->HandleEnterKeyPress(aEvent); |  | ||||||
|   } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| XULButtonElement* nsMenuPopupFrame::FindMenuWithShortcut( | XULButtonElement* nsMenuPopupFrame::FindMenuWithShortcut( | ||||||
|  |  | ||||||
|  | @ -26,7 +26,6 @@ | ||||||
| #include "nsIContent.h" | #include "nsIContent.h" | ||||||
| #include "nsNameSpaceManager.h" | #include "nsNameSpaceManager.h" | ||||||
| #include "nsBoxLayoutState.h" | #include "nsBoxLayoutState.h" | ||||||
| #include "nsMenuBarListener.h" |  | ||||||
| #include "nsString.h" | #include "nsString.h" | ||||||
| #include "nsITheme.h" | #include "nsITheme.h" | ||||||
| #include "nsUnicharUtils.h" | #include "nsUnicharUtils.h" | ||||||
|  |  | ||||||
|  | @ -5,7 +5,6 @@ | ||||||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 |  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | ||||||
| 
 | 
 | ||||||
| #include "XULButtonElement.h" | #include "XULButtonElement.h" | ||||||
| #include "XULMenuParentElement.h" |  | ||||||
| #include "mozilla/Assertions.h" | #include "mozilla/Assertions.h" | ||||||
| #include "mozilla/Attributes.h" | #include "mozilla/Attributes.h" | ||||||
| #include "mozilla/FlushType.h" | #include "mozilla/FlushType.h" | ||||||
|  | @ -14,8 +13,6 @@ | ||||||
| #include "nsISound.h" | #include "nsISound.h" | ||||||
| #include "nsXULPopupManager.h" | #include "nsXULPopupManager.h" | ||||||
| #include "nsMenuPopupFrame.h" | #include "nsMenuPopupFrame.h" | ||||||
| #include "nsMenuBarFrame.h" |  | ||||||
| #include "nsMenuBarListener.h" |  | ||||||
| #include "nsContentUtils.h" | #include "nsContentUtils.h" | ||||||
| #include "nsXULElement.h" | #include "nsXULElement.h" | ||||||
| #include "nsIDOMXULCommandDispatcher.h" | #include "nsIDOMXULCommandDispatcher.h" | ||||||
|  | @ -50,6 +47,7 @@ | ||||||
| #include "mozilla/dom/PopupPositionedEventBinding.h" | #include "mozilla/dom/PopupPositionedEventBinding.h" | ||||||
| #include "mozilla/dom/XULCommandEvent.h" | #include "mozilla/dom/XULCommandEvent.h" | ||||||
| #include "mozilla/dom/XULMenuElement.h" | #include "mozilla/dom/XULMenuElement.h" | ||||||
|  | #include "mozilla/dom/XULMenuBarElement.h" | ||||||
| #include "mozilla/dom/XULPopupElement.h" | #include "mozilla/dom/XULPopupElement.h" | ||||||
| #include "mozilla/EventDispatcher.h" | #include "mozilla/EventDispatcher.h" | ||||||
| #include "mozilla/EventStateManager.h" | #include "mozilla/EventStateManager.h" | ||||||
|  | @ -77,6 +75,17 @@ static_assert(KeyboardEvent_Binding::DOM_VK_HOME == | ||||||
|                       KeyboardEvent_Binding::DOM_VK_END + 5, |                       KeyboardEvent_Binding::DOM_VK_END + 5, | ||||||
|               "nsXULPopupManager assumes some keyCode values are consecutive"); |               "nsXULPopupManager assumes some keyCode values are consecutive"); | ||||||
| 
 | 
 | ||||||
|  | #define NS_DIRECTION_IS_INLINE(dir) \ | ||||||
|  |   (dir == eNavigationDirection_Start || dir == eNavigationDirection_End) | ||||||
|  | #define NS_DIRECTION_IS_BLOCK(dir) \ | ||||||
|  |   (dir == eNavigationDirection_Before || dir == eNavigationDirection_After) | ||||||
|  | #define NS_DIRECTION_IS_BLOCK_TO_EDGE(dir) \ | ||||||
|  |   (dir == eNavigationDirection_First || dir == eNavigationDirection_Last) | ||||||
|  | 
 | ||||||
|  | static_assert(static_cast<uint8_t>(mozilla::StyleDirection::Ltr) == 0 && | ||||||
|  |                   static_cast<uint8_t>(mozilla::StyleDirection::Rtl) == 1, | ||||||
|  |               "Left to Right should be 0 and Right to Left should be 1"); | ||||||
|  | 
 | ||||||
| const nsNavigationDirection DirectionFromKeyCodeTable[2][6] = { | const nsNavigationDirection DirectionFromKeyCodeTable[2][6] = { | ||||||
|     { |     { | ||||||
|         eNavigationDirection_Last,    // KeyboardEvent_Binding::DOM_VK_END
 |         eNavigationDirection_Last,    // KeyboardEvent_Binding::DOM_VK_END
 | ||||||
|  | @ -707,7 +716,7 @@ nsMenuChainItem* nsXULPopupManager::GetRollupItem(RollupKind aKind) { | ||||||
|   return nullptr; |   return nullptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void nsXULPopupManager::SetActiveMenuBar(nsMenuBarFrame* aMenuBar, | void nsXULPopupManager::SetActiveMenuBar(XULMenuBarElement* aMenuBar, | ||||||
|                                          bool aActivate) { |                                          bool aActivate) { | ||||||
|   if (aActivate) { |   if (aActivate) { | ||||||
|     mActiveMenuBar = aMenuBar; |     mActiveMenuBar = aMenuBar; | ||||||
|  | @ -2010,7 +2019,7 @@ void nsXULPopupManager::UpdateKeyboardListeners() { | ||||||
|     } |     } | ||||||
|     isForMenu = item->GetPopupType() == PopupType::Menu; |     isForMenu = item->GetPopupType() == PopupType::Menu; | ||||||
|   } else if (mActiveMenuBar) { |   } else if (mActiveMenuBar) { | ||||||
|     newTarget = mActiveMenuBar->GetContent()->GetComposedDoc(); |     newTarget = mActiveMenuBar->GetComposedDoc(); | ||||||
|     isForMenu = true; |     isForMenu = true; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -2209,7 +2218,7 @@ bool nsXULPopupManager::HandleShortcutNavigation(KeyboardEvent& aKeyEvent, | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (mActiveMenuBar) { |   if (mActiveMenuBar) { | ||||||
|     RefPtr menubar = &mActiveMenuBar->MenubarElement(); |     RefPtr menubar = mActiveMenuBar; | ||||||
|     if (RefPtr result = menubar->FindMenuWithShortcut(aKeyEvent)) { |     if (RefPtr result = menubar->FindMenuWithShortcut(aKeyEvent)) { | ||||||
|       result->OpenMenuPopup(true); |       result->OpenMenuPopup(true); | ||||||
|       return true; |       return true; | ||||||
|  | @ -2222,7 +2231,7 @@ bool nsXULPopupManager::HandleShortcutNavigation(KeyboardEvent& aKeyEvent, | ||||||
|     if (nsCOMPtr<nsISound> sound = do_GetService("@mozilla.org/sound;1")) { |     if (nsCOMPtr<nsISound> sound = do_GetService("@mozilla.org/sound;1")) { | ||||||
|       sound->Beep(); |       sound->Beep(); | ||||||
|     } |     } | ||||||
|     mActiveMenuBar->SetActive(false); |     menubar->SetActive(false); | ||||||
| #endif | #endif | ||||||
|   } |   } | ||||||
|   return false; |   return false; | ||||||
|  | @ -2264,7 +2273,10 @@ bool nsXULPopupManager::HandleKeyboardNavigation(uint32_t aKeyCode) { | ||||||
|   if (item) { |   if (item) { | ||||||
|     itemFrame = item->Frame(); |     itemFrame = item->Frame(); | ||||||
|   } else if (mActiveMenuBar) { |   } else if (mActiveMenuBar) { | ||||||
|     itemFrame = mActiveMenuBar; |     itemFrame = mActiveMenuBar->GetPrimaryFrame(); | ||||||
|  |     if (!itemFrame) { | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|   } else { |   } else { | ||||||
|     return false; |     return false; | ||||||
|   } |   } | ||||||
|  | @ -2301,7 +2313,7 @@ bool nsXULPopupManager::HandleKeyboardNavigation(uint32_t aKeyCode) { | ||||||
|   if (!mActiveMenuBar) { |   if (!mActiveMenuBar) { | ||||||
|     return false; |     return false; | ||||||
|   } |   } | ||||||
|   RefPtr menubar = XULMenuParentElement::FromNode(mActiveMenuBar->GetContent()); |   RefPtr menubar = mActiveMenuBar; | ||||||
|   if (NS_DIRECTION_IS_INLINE(theDirection)) { |   if (NS_DIRECTION_IS_INLINE(theDirection)) { | ||||||
|     RefPtr prevActiveItem = menubar->GetActiveMenuChild(); |     RefPtr prevActiveItem = menubar->GetActiveMenuChild(); | ||||||
|     const bool open = prevActiveItem && prevActiveItem->IsMenuPopupOpen(); |     const bool open = prevActiveItem && prevActiveItem->IsMenuPopupOpen(); | ||||||
|  | @ -2460,7 +2472,8 @@ bool nsXULPopupManager::HandleKeyboardEventWithKeyCode( | ||||||
|       if (aTopVisibleMenuItem) { |       if (aTopVisibleMenuItem) { | ||||||
|         HidePopup(aTopVisibleMenuItem->Content(), {HidePopupOption::IsRollup}); |         HidePopup(aTopVisibleMenuItem->Content(), {HidePopupOption::IsRollup}); | ||||||
|       } else if (mActiveMenuBar) { |       } else if (mActiveMenuBar) { | ||||||
|         mActiveMenuBar->MenuClosed(); |         RefPtr menubar = mActiveMenuBar; | ||||||
|  |         menubar->MenuClosed(); | ||||||
|       } |       } | ||||||
|       break; |       break; | ||||||
| 
 | 
 | ||||||
|  | @ -2476,7 +2489,8 @@ bool nsXULPopupManager::HandleKeyboardEventWithKeyCode( | ||||||
|         Rollup({}); |         Rollup({}); | ||||||
|         break; |         break; | ||||||
|       } else if (mActiveMenuBar) { |       } else if (mActiveMenuBar) { | ||||||
|         mActiveMenuBar->MenuClosed(); |         RefPtr menubar = mActiveMenuBar; | ||||||
|  |         menubar->MenuClosed(); | ||||||
|         break; |         break; | ||||||
|       } |       } | ||||||
|       // Intentional fall-through to RETURN case
 |       // Intentional fall-through to RETURN case
 | ||||||
|  | @ -2490,7 +2504,8 @@ bool nsXULPopupManager::HandleKeyboardEventWithKeyCode( | ||||||
|       if (aTopVisibleMenuItem) { |       if (aTopVisibleMenuItem) { | ||||||
|         aTopVisibleMenuItem->Frame()->HandleEnterKeyPress(*event); |         aTopVisibleMenuItem->Frame()->HandleEnterKeyPress(*event); | ||||||
|       } else if (mActiveMenuBar) { |       } else if (mActiveMenuBar) { | ||||||
|         mActiveMenuBar->HandleEnterKeyPress(*event); |         RefPtr menubar = mActiveMenuBar; | ||||||
|  |         menubar->HandleEnterKeyPress(*event); | ||||||
|       } |       } | ||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
|  | @ -2541,8 +2556,7 @@ nsresult nsXULPopupManager::UpdateIgnoreKeys(bool aIgnoreKeys) { | ||||||
|   return NS_OK; |   return NS_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| nsPopupState nsXULPopupManager::GetPopupState( | nsPopupState nsXULPopupManager::GetPopupState(Element* aPopupElement) { | ||||||
|     mozilla::dom::Element* aPopupElement) { |  | ||||||
|   if (mNativeMenu && mNativeMenu->Element()->Contains(aPopupElement)) { |   if (mNativeMenu && mNativeMenu->Element()->Contains(aPopupElement)) { | ||||||
|     if (aPopupElement != mNativeMenu->Element()) { |     if (aPopupElement != mNativeMenu->Element()) { | ||||||
|       // Submenu state is stored in mNativeMenuSubmenuStates.
 |       // Submenu state is stored in mNativeMenuSubmenuStates.
 | ||||||
|  | @ -2621,7 +2635,8 @@ nsresult nsXULPopupManager::KeyDown(KeyboardEvent* aKeyEvent) { | ||||||
|         if (item && !item->Frame()->IsMenuList()) { |         if (item && !item->Frame()->IsMenuList()) { | ||||||
|           Rollup({}); |           Rollup({}); | ||||||
|         } else if (mActiveMenuBar) { |         } else if (mActiveMenuBar) { | ||||||
|           mActiveMenuBar->MenuClosed(); |           RefPtr menubar = mActiveMenuBar; | ||||||
|  |           menubar->MenuClosed(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Clear the item to avoid bugs as it may have been deleted during
 |         // Clear the item to avoid bugs as it may have been deleted during
 | ||||||
|  |  | ||||||
|  | @ -12,23 +12,19 @@ | ||||||
| #define nsXULPopupManager_h__ | #define nsXULPopupManager_h__ | ||||||
| 
 | 
 | ||||||
| #include "mozilla/Logging.h" | #include "mozilla/Logging.h" | ||||||
| #include "mozilla/widget/InitData.h" |  | ||||||
| #include "nsHashtablesFwd.h" | #include "nsHashtablesFwd.h" | ||||||
| #include "nsIContent.h" | #include "nsIContent.h" | ||||||
| #include "nsIRollupListener.h" | #include "nsIRollupListener.h" | ||||||
| #include "nsIDOMEventListener.h" | #include "nsIDOMEventListener.h" | ||||||
|  | #include "Units.h" | ||||||
| #include "nsPoint.h" | #include "nsPoint.h" | ||||||
| #include "nsCOMPtr.h" | #include "nsCOMPtr.h" | ||||||
| #include "nsTArray.h" | #include "nsTArray.h" | ||||||
| #include "nsIObserver.h" | #include "nsIObserver.h" | ||||||
| #include "nsITimer.h" |  | ||||||
| #include "nsIReflowCallback.h" |  | ||||||
| #include "nsThreadUtils.h" | #include "nsThreadUtils.h" | ||||||
| #include "nsPresContext.h" |  | ||||||
| #include "nsStyleConsts.h" |  | ||||||
| #include "mozilla/Attributes.h" | #include "mozilla/Attributes.h" | ||||||
|  | #include "mozilla/widget/InitData.h" | ||||||
| #include "mozilla/widget/NativeMenu.h" | #include "mozilla/widget/NativeMenu.h" | ||||||
| #include "Units.h" |  | ||||||
| 
 | 
 | ||||||
| // XXX Avoid including this here by moving function bodies to the cpp file.
 | // XXX Avoid including this here by moving function bodies to the cpp file.
 | ||||||
| #include "mozilla/dom/Element.h" | #include "mozilla/dom/Element.h" | ||||||
|  | @ -54,9 +50,9 @@ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| class nsContainerFrame; | class nsContainerFrame; | ||||||
| class nsMenuPopupFrame; | class nsITimer; | ||||||
| class nsMenuBarFrame; |  | ||||||
| class nsIDocShellTreeItem; | class nsIDocShellTreeItem; | ||||||
|  | class nsMenuPopupFrame; | ||||||
| class nsPIDOMWindowOuter; | class nsPIDOMWindowOuter; | ||||||
| class nsRefreshDriver; | class nsRefreshDriver; | ||||||
| 
 | 
 | ||||||
|  | @ -67,6 +63,7 @@ class Event; | ||||||
| class KeyboardEvent; | class KeyboardEvent; | ||||||
| class UIEvent; | class UIEvent; | ||||||
| class XULButtonElement; | class XULButtonElement; | ||||||
|  | class XULMenuBarElement; | ||||||
| }  // namespace dom
 | }  // namespace dom
 | ||||||
| }  // namespace mozilla
 | }  // namespace mozilla
 | ||||||
| 
 | 
 | ||||||
|  | @ -178,17 +175,6 @@ enum class HidePopupOption : uint8_t { | ||||||
| 
 | 
 | ||||||
| using HidePopupOptions = mozilla::EnumSet<HidePopupOption>; | using HidePopupOptions = mozilla::EnumSet<HidePopupOption>; | ||||||
| 
 | 
 | ||||||
| #define NS_DIRECTION_IS_INLINE(dir) \ |  | ||||||
|   (dir == eNavigationDirection_Start || dir == eNavigationDirection_End) |  | ||||||
| #define NS_DIRECTION_IS_BLOCK(dir) \ |  | ||||||
|   (dir == eNavigationDirection_Before || dir == eNavigationDirection_After) |  | ||||||
| #define NS_DIRECTION_IS_BLOCK_TO_EDGE(dir) \ |  | ||||||
|   (dir == eNavigationDirection_First || dir == eNavigationDirection_Last) |  | ||||||
| 
 |  | ||||||
| static_assert(static_cast<uint8_t>(mozilla::StyleDirection::Ltr) == 0 && |  | ||||||
|                   static_cast<uint8_t>(mozilla::StyleDirection::Rtl) == 1, |  | ||||||
|               "Left to Right should be 0 and Right to Left should be 1"); |  | ||||||
| 
 |  | ||||||
| /**
 | /**
 | ||||||
|  * DirectionFromKeyCodeTable: two arrays, the first for left-to-right and the |  * DirectionFromKeyCodeTable: two arrays, the first for left-to-right and the | ||||||
|  * other for right-to-left, that map keycodes to values of |  * other for right-to-left, that map keycodes to values of | ||||||
|  | @ -437,7 +423,8 @@ class nsXULPopupManager final : public nsIDOMEventListener, | ||||||
|   // when the active menu bar should be defocused. In the latter case, if
 |   // when the active menu bar should be defocused. In the latter case, if
 | ||||||
|   // aMenuBar isn't currently active, yet another menu bar is, that menu bar
 |   // aMenuBar isn't currently active, yet another menu bar is, that menu bar
 | ||||||
|   // will remain active.
 |   // will remain active.
 | ||||||
|   void SetActiveMenuBar(nsMenuBarFrame* aMenuBar, bool aActivate); |   void SetActiveMenuBar(mozilla::dom::XULMenuBarElement* aMenuBar, | ||||||
|  |                         bool aActivate); | ||||||
| 
 | 
 | ||||||
|   struct MayShowMenuResult { |   struct MayShowMenuResult { | ||||||
|     const bool mIsNative = false; |     const bool mIsNative = false; | ||||||
|  | @ -865,7 +852,7 @@ class nsXULPopupManager final : public nsIDOMEventListener, | ||||||
|   nsCOMPtr<nsIWidget> mWidget; |   nsCOMPtr<nsIWidget> mWidget; | ||||||
| 
 | 
 | ||||||
|   // set to the currently active menu bar, if any
 |   // set to the currently active menu bar, if any
 | ||||||
|   nsMenuBarFrame* mActiveMenuBar; |   mozilla::dom::XULMenuBarElement* mActiveMenuBar; | ||||||
| 
 | 
 | ||||||
|   // linked list of normal menus and panels. mPopups points to the innermost
 |   // linked list of normal menus and panels. mPopups points to the innermost
 | ||||||
|   // popup, which keeps alive all their parents.
 |   // popup, which keeps alive all their parents.
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Emilio Cobos Álvarez
						Emilio Cobos Álvarez