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