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 "LocalAccessible-inl.h"
|
||||
#include "XULMenuBarElement.h"
|
||||
#include "XULMenuParentElement.h"
|
||||
#include "XULPopupElement.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
|
|
@ -21,7 +22,6 @@
|
|||
#include "nsIDOMXULSelectCntrlEl.h"
|
||||
#include "nsIDOMXULSelectCntrlItemEl.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsMenuBarFrame.h"
|
||||
#include "nsMenuPopupFrame.h"
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
|
|
@ -464,8 +464,8 @@ role XULMenubarAccessible::NativeRole() const { return roles::MENUBAR; }
|
|||
// XULMenubarAccessible: Widgets
|
||||
|
||||
bool XULMenubarAccessible::IsActiveWidget() const {
|
||||
nsMenuBarFrame* menuBarFrame = do_QueryFrame(GetFrame());
|
||||
return menuBarFrame && menuBarFrame->IsActive();
|
||||
auto* menuBar = dom::XULMenuBarElement::FromNode(GetContent());
|
||||
return menuBar && menuBar->IsActive();
|
||||
}
|
||||
|
||||
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
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsMenuBarListener.h"
|
||||
#include "MenuBarListener.h"
|
||||
#include "XULButtonElement.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/XULButtonElement.h"
|
||||
#include "nsMenuBarFrame.h"
|
||||
#include "nsMenuPopupFrame.h"
|
||||
#include "nsPIWindowRoot.h"
|
||||
#include "nsISound.h"
|
||||
|
||||
// Drag & Drop, Clipboard
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIContent.h"
|
||||
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsPIWindowRoot.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "mozilla/BasicEvents.h"
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
#include "mozilla/StaticPrefs_ui.h"
|
||||
#include "mozilla/TextEvents.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
|
|
@ -29,31 +26,30 @@
|
|||
#include "mozilla/dom/EventBinding.h"
|
||||
#include "mozilla/dom/KeyboardEvent.h"
|
||||
#include "mozilla/dom/KeyboardEventBinding.h"
|
||||
#include "mozilla/dom/XULButtonElement.h"
|
||||
#include "mozilla/dom/XULMenuBarElement.h"
|
||||
#include "mozilla/dom/XULMenuParentElement.h"
|
||||
#include "nsXULPopupManager.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using mozilla::dom::Event;
|
||||
using mozilla::dom::KeyboardEvent;
|
||||
namespace mozilla::dom {
|
||||
|
||||
/*
|
||||
* nsMenuBarListener implementation
|
||||
*/
|
||||
NS_IMPL_CYCLE_COLLECTION(MenuBarListener, mTopWindowEventTarget)
|
||||
|
||||
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,
|
||||
nsIContent* aMenuBarContent)
|
||||
: mMenuBarFrame(aMenuBarFrame),
|
||||
mContent(dom::XULMenuParentElement::FromNode(aMenuBarContent)),
|
||||
mEventTarget(aMenuBarContent->GetComposedDoc()),
|
||||
MenuBarListener::MenuBarListener(XULMenuBarElement& aElement)
|
||||
: mMenuBar(&aElement),
|
||||
mEventTarget(aElement.GetComposedDoc()),
|
||||
mTopWindowEventTarget(nullptr),
|
||||
mAccessKeyDown(false),
|
||||
mAccessKeyDownCanceled(false) {
|
||||
MOZ_ASSERT(mEventTarget);
|
||||
MOZ_ASSERT(mContent);
|
||||
MOZ_ASSERT(mMenuBar);
|
||||
|
||||
// Hook up the menubar as a key listener on the whole document. This will
|
||||
// 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);
|
||||
|
||||
// Needs to listen to the deactivate event of the window.
|
||||
RefPtr<dom::EventTarget> topWindowEventTarget =
|
||||
nsContentUtils::GetWindowRoot(aMenuBarContent->GetComposedDoc());
|
||||
mTopWindowEventTarget = topWindowEventTarget.get();
|
||||
|
||||
mTopWindowEventTarget = nsContentUtils::GetWindowRoot(mEventTarget);
|
||||
mTopWindowEventTarget->AddSystemEventListener(u"deactivate"_ns, this, true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
nsMenuBarListener::~nsMenuBarListener() {
|
||||
MOZ_ASSERT(!mEventTarget,
|
||||
"OnDestroyMenuBarFrame() should've alreay been called");
|
||||
MenuBarListener::~MenuBarListener() {
|
||||
MOZ_ASSERT(!mEventTarget, "Should've detached always");
|
||||
}
|
||||
|
||||
void nsMenuBarListener::OnDestroyMenuBarFrame() {
|
||||
void MenuBarListener::Detach() {
|
||||
mEventTarget->RemoveSystemEventListener(u"keypress"_ns, this, false);
|
||||
mEventTarget->RemoveSystemEventListener(u"keydown"_ns, this, false);
|
||||
mEventTarget->RemoveSystemEventListener(u"keyup"_ns, this, false);
|
||||
|
|
@ -109,23 +101,26 @@ void nsMenuBarListener::OnDestroyMenuBarFrame() {
|
|||
mTopWindowEventTarget->RemoveSystemEventListener(u"deactivate"_ns, this,
|
||||
true);
|
||||
|
||||
mMenuBarFrame = nullptr;
|
||||
mMenuBar = nullptr;
|
||||
mEventTarget = nullptr;
|
||||
mTopWindowEventTarget = nullptr;
|
||||
}
|
||||
|
||||
void nsMenuBarListener::ToggleMenuActiveState() {
|
||||
if (mMenuBarFrame->IsActive()) {
|
||||
mMenuBarFrame->SetActive(false);
|
||||
void MenuBarListener::ToggleMenuActiveState(ByKeyboard aByKeyboard) {
|
||||
RefPtr menuBar = mMenuBar;
|
||||
if (menuBar->IsActive()) {
|
||||
menuBar->SetActive(false);
|
||||
} else {
|
||||
RefPtr content = mContent;
|
||||
mMenuBarFrame->SetActive(true);
|
||||
content->SelectFirstItem();
|
||||
if (aByKeyboard == ByKeyboard::Yes) {
|
||||
menuBar->SetActiveByKeyboard();
|
||||
}
|
||||
menuBar->SetActive(true);
|
||||
menuBar->SelectFirstItem();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
nsresult nsMenuBarListener::KeyUp(Event* aKeyEvent) {
|
||||
nsresult MenuBarListener::KeyUp(Event* aKeyEvent) {
|
||||
WidgetKeyboardEvent* nativeKeyEvent =
|
||||
aKeyEvent->WidgetEventPtr()->AsKeyboardEvent();
|
||||
if (!nativeKeyEvent) {
|
||||
|
|
@ -149,7 +144,7 @@ nsresult nsMenuBarListener::KeyUp(Event* aKeyEvent) {
|
|||
// The access key was down and is now up, and no other
|
||||
// keys were pressed in between.
|
||||
bool toggleMenuActiveState = true;
|
||||
if (!mMenuBarFrame->IsActive()) {
|
||||
if (!mMenuBar->IsActive()) {
|
||||
// If the focused content is in a remote process, we should allow the
|
||||
// focused web app to prevent to activate the menubar.
|
||||
if (nativeKeyEvent->WillBeSentToRemoteProcess()) {
|
||||
|
|
@ -165,20 +160,17 @@ nsresult nsMenuBarListener::KeyUp(Event* aKeyEvent) {
|
|||
}
|
||||
// If menubar active state is changed or the menubar is destroyed
|
||||
// during closing the popups, we should do nothing anymore.
|
||||
toggleMenuActiveState = !Destroyed() && !mMenuBarFrame->IsActive();
|
||||
toggleMenuActiveState = !Destroyed() && !mMenuBar->IsActive();
|
||||
}
|
||||
if (toggleMenuActiveState) {
|
||||
if (!mMenuBarFrame->IsActive()) {
|
||||
mMenuBarFrame->SetActiveByKeyboard();
|
||||
}
|
||||
ToggleMenuActiveState();
|
||||
ToggleMenuActiveState(ByKeyboard::Yes);
|
||||
}
|
||||
}
|
||||
|
||||
mAccessKeyDown = false;
|
||||
mAccessKeyDownCanceled = false;
|
||||
|
||||
if (!Destroyed() && mMenuBarFrame->IsActive()) {
|
||||
if (!Destroyed() && mMenuBar->IsActive()) {
|
||||
nativeKeyEvent->StopPropagation();
|
||||
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 (!aKeyEvent || aKeyEvent->DefaultPrevented()) {
|
||||
return NS_OK; // don't consume event
|
||||
|
|
@ -198,7 +190,7 @@ nsresult nsMenuBarListener::KeyPress(Event* aKeyEvent) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
auto accessKey = LookAndFeel::GetMenuAccessKey();
|
||||
const auto accessKey = LookAndFeel::GetMenuAccessKey();
|
||||
if (!accessKey) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
@ -235,12 +227,11 @@ nsresult nsMenuBarListener::KeyPress(Event* aKeyEvent) {
|
|||
}
|
||||
// The F10 key just went down by itself or with ctrl pressed.
|
||||
// In Windows, both of these activate the menu bar.
|
||||
mMenuBarFrame->SetActiveByKeyboard();
|
||||
ToggleMenuActiveState();
|
||||
ToggleMenuActiveState(ByKeyboard::Yes);
|
||||
|
||||
if (mMenuBarFrame->IsActive()) {
|
||||
if (mMenuBar && mMenuBar->IsActive()) {
|
||||
# ifdef MOZ_WIDGET_GTK
|
||||
RefPtr child = mContent->GetActiveMenuChild();
|
||||
RefPtr child = mMenuBar->GetActiveMenuChild();
|
||||
// In GTK, this also opens the first menu.
|
||||
child->OpenMenuPopup(false);
|
||||
# endif
|
||||
|
|
@ -260,11 +251,11 @@ nsresult nsMenuBarListener::KeyPress(Event* aKeyEvent) {
|
|||
// the menu bar.
|
||||
// TODO(emilio): This is rather odd, and I cannot get the beep to work,
|
||||
// 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")) {
|
||||
sound->Beep();
|
||||
}
|
||||
mMenuBarFrame->SetActive(false);
|
||||
ToggleMenuActiveState(ByKeyboard::Yes);
|
||||
}
|
||||
#endif
|
||||
return NS_OK;
|
||||
|
|
@ -282,8 +273,9 @@ nsresult nsMenuBarListener::KeyPress(Event* aKeyEvent) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
mMenuBarFrame->SetActiveByKeyboard();
|
||||
mMenuBarFrame->SetActive(true);
|
||||
RefPtr menuBar = mMenuBar;
|
||||
menuBar->SetActiveByKeyboard();
|
||||
menuBar->SetActive(true);
|
||||
menuForKey->OpenMenuPopup(true);
|
||||
|
||||
// The opened menu will listen next keyup event.
|
||||
|
|
@ -292,11 +284,10 @@ nsresult nsMenuBarListener::KeyPress(Event* aKeyEvent) {
|
|||
|
||||
aKeyEvent->StopPropagation();
|
||||
aKeyEvent->PreventDefault();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
dom::XULButtonElement* nsMenuBarListener::GetMenuForKeyEvent(
|
||||
dom::XULButtonElement* MenuBarListener::GetMenuForKeyEvent(
|
||||
KeyboardEvent& aKeyEvent) {
|
||||
if (!aKeyEvent.IsMenuAccessKeyPressed()) {
|
||||
return nullptr;
|
||||
|
|
@ -318,10 +309,10 @@ dom::XULButtonElement* nsMenuBarListener::GetMenuForKeyEvent(
|
|||
// Do shortcut navigation.
|
||||
// A letter was pressed. We want to see if a shortcut gets matched. If
|
||||
// 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 =
|
||||
aKeyEvent->WidgetEventPtr()->AsKeyboardEvent();
|
||||
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.
|
||||
if (!aKeyEvent || !aKeyEvent->IsTrusted()) {
|
||||
return NS_OK;
|
||||
|
|
@ -360,9 +351,9 @@ nsresult nsMenuBarListener::KeyDown(Event* aKeyEvent) {
|
|||
// Especially CTRL. CTRL+ALT == AltGR, and we'll break on non-US
|
||||
// enhanced 102-key keyboards if we don't check this.
|
||||
bool isAccessKeyDownEvent =
|
||||
theChar == accessKey &&
|
||||
(keyEvent->GetModifiersForMenuAccessKey() &
|
||||
~LookAndFeel::GetMenuAccessKeyModifiers()) == 0;
|
||||
(theChar == accessKey &&
|
||||
(keyEvent->GetModifiersForMenuAccessKey() &
|
||||
~LookAndFeel::GetMenuAccessKeyModifiers()) == 0);
|
||||
|
||||
if (!capturing && !mAccessKeyDown) {
|
||||
// If accesskey isn't being pressed and the key isn't the accesskey,
|
||||
|
|
@ -389,7 +380,7 @@ nsresult nsMenuBarListener::KeyDown(Event* aKeyEvent) {
|
|||
mAccessKeyDownCanceled = !isAccessKeyDownEvent;
|
||||
}
|
||||
|
||||
if (capturing && LookAndFeel::GetMenuAccessKey()) {
|
||||
if (capturing && accessKey) {
|
||||
if (GetMenuForKeyEvent(*keyEvent)) {
|
||||
ReserveKeyIfNeeded(aKeyEvent);
|
||||
}
|
||||
|
|
@ -400,9 +391,9 @@ nsresult nsMenuBarListener::KeyDown(Event* aKeyEvent) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult nsMenuBarListener::Blur(Event* aEvent) {
|
||||
if (!IsMenuOpen() && mMenuBarFrame->IsActive()) {
|
||||
ToggleMenuActiveState();
|
||||
nsresult MenuBarListener::Blur(Event* aEvent) {
|
||||
if (!IsMenuOpen() && mMenuBar->IsActive()) {
|
||||
ToggleMenuActiveState(ByKeyboard::No);
|
||||
mAccessKeyDown = 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
|
||||
// the pressing accesskey.
|
||||
mAccessKeyDown = false;
|
||||
|
|
@ -419,13 +410,13 @@ nsresult nsMenuBarListener::OnWindowDeactivated(Event* aEvent) {
|
|||
return NS_OK; // means I am NOT consuming event
|
||||
}
|
||||
|
||||
bool nsMenuBarListener::IsMenuOpen() const {
|
||||
auto* activeChild = mContent->GetActiveMenuChild();
|
||||
bool MenuBarListener::IsMenuOpen() const {
|
||||
auto* activeChild = mMenuBar->GetActiveMenuChild();
|
||||
return activeChild && activeChild->IsMenuPopupOpen();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
nsresult nsMenuBarListener::MouseDown(Event* aMouseEvent) {
|
||||
nsresult MenuBarListener::MouseDown(Event* aMouseEvent) {
|
||||
// NOTE: MouseDown method listens all phases
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
if (!IsMenuOpen() && mMenuBarFrame->IsActive()) {
|
||||
ToggleMenuActiveState();
|
||||
if (!IsMenuOpen() && mMenuBar->IsActive()) {
|
||||
ToggleMenuActiveState(ByKeyboard::No);
|
||||
}
|
||||
|
||||
return NS_OK; // means I am NOT consuming event
|
||||
|
|
@ -449,18 +440,19 @@ nsresult nsMenuBarListener::MouseDown(Event* aMouseEvent) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult nsMenuBarListener::Fullscreen(Event* aEvent) {
|
||||
if (mMenuBarFrame->IsActive()) {
|
||||
ToggleMenuActiveState();
|
||||
nsresult MenuBarListener::Fullscreen(Event* aEvent) {
|
||||
if (mMenuBar->IsActive()) {
|
||||
ToggleMenuActiveState(ByKeyboard::No);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
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 (!mMenuBarFrame->StyleVisibility()->IsVisible()) {
|
||||
if (!mMenuBar->GetPrimaryFrame() ||
|
||||
!mMenuBar->GetPrimaryFrame()->StyleVisibility()->IsVisible()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
@ -495,3 +487,5 @@ nsMenuBarListener::HandleEvent(Event* aEvent) {
|
|||
MOZ_ASSERT_UNREACHABLE("Unexpected eventType");
|
||||
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/NameSpaceConstants.h"
|
||||
#include "mozilla/dom/AncestorIterator.h"
|
||||
#include "mozilla/dom/XULMenuBarElement.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsCaseTreatment.h"
|
||||
#include "nsChangeHint.h"
|
||||
#include "nsMenuBarFrame.h"
|
||||
#include "nsMenuPopupFrame.h"
|
||||
#include "nsPlaceholderFrame.h"
|
||||
#include "nsPresContext.h"
|
||||
|
|
@ -444,7 +444,8 @@ void XULButtonElement::PostHandleEventForMenus(
|
|||
// If we're open we never deselect. PopupClosed will do as needed.
|
||||
return false;
|
||||
}
|
||||
if (!parent->IsMenuBar()) {
|
||||
auto* menubar = XULMenuBarElement::FromNode(*parent);
|
||||
if (!menubar) {
|
||||
// Don't de-select when not in the menubar.
|
||||
// NOTE(emilio): Behavior from before bug 1811466 is equivalent to
|
||||
// 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
|
||||
// activated by keyboard.
|
||||
nsMenuBarFrame* menubar = do_QueryFrame(parent->GetPrimaryFrame());
|
||||
const bool openedByKey = menubar && menubar->IsActiveByKeyboard();
|
||||
return !openedByKey;
|
||||
return !menubar->IsActiveByKeyboard();
|
||||
}();
|
||||
|
||||
if (shouldDeactivate) {
|
||||
|
|
@ -756,17 +755,11 @@ auto XULButtonElement::GetMenuType() const -> Maybe<MenuType> {
|
|||
}
|
||||
}
|
||||
|
||||
nsMenuBarFrame* XULButtonElement::GetMenuBar(FlushType aFlushType) {
|
||||
XULMenuBarElement* XULButtonElement::GetMenuBar() const {
|
||||
if (!IsMenu()) {
|
||||
return nullptr;
|
||||
}
|
||||
nsIFrame* frame = GetPrimaryFrame(aFlushType);
|
||||
for (; frame; frame = frame->GetParent()) {
|
||||
if (nsMenuBarFrame* menubar = do_QueryFrame(frame)) {
|
||||
return menubar;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
return FirstAncestorOfType<XULMenuBarElement>();
|
||||
}
|
||||
|
||||
XULMenuParentElement* XULButtonElement::GetMenuParent() const {
|
||||
|
|
@ -800,8 +793,8 @@ nsMenuPopupFrame* XULButtonElement::GetMenuPopup(FlushType aFlushType) {
|
|||
return do_QueryFrame(popup->GetPrimaryFrame(aFlushType));
|
||||
}
|
||||
|
||||
bool XULButtonElement::OpenedWithKey() {
|
||||
nsMenuBarFrame* menubar = GetMenuBar(FlushType::Frames);
|
||||
bool XULButtonElement::OpenedWithKey() const {
|
||||
auto* menubar = GetMenuBar();
|
||||
return menubar && menubar->IsActiveByKeyboard();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ namespace mozilla::dom {
|
|||
|
||||
class KeyboardEvent;
|
||||
class XULPopupElement;
|
||||
class XULMenuBarElement;
|
||||
class XULMenuParentElement;
|
||||
|
||||
class XULButtonElement : public nsXULElement {
|
||||
|
|
@ -57,7 +58,7 @@ class XULButtonElement : public nsXULElement {
|
|||
void UnbindFromTree(bool aNullParent) override;
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT bool HandleKeyPress(KeyboardEvent& keyEvent);
|
||||
MOZ_CAN_RUN_SCRIPT bool OpenedWithKey();
|
||||
bool OpenedWithKey() const;
|
||||
// Called to execute our command handler.
|
||||
MOZ_CAN_RUN_SCRIPT void ExecuteMenu(WidgetEvent&);
|
||||
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); }
|
||||
|
||||
private:
|
||||
XULMenuBarElement* GetMenuBar() const;
|
||||
void Blurred();
|
||||
nsMenuBarFrame* GetMenuBar(FlushType aFlushType);
|
||||
enum class MenuType {
|
||||
Checkbox,
|
||||
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/KeyboardEvent.h"
|
||||
#include "mozilla/dom/KeyboardEventBinding.h"
|
||||
#include "nsMenuBarListener.h"
|
||||
#include "nsXULPopupManager.h"
|
||||
#include "nsMenuPopupFrame.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -5,20 +5,20 @@
|
|||
|
||||
#include "XULMenuParentElement.h"
|
||||
#include "XULButtonElement.h"
|
||||
#include "XULMenuBarElement.h"
|
||||
#include "XULPopupElement.h"
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
#include "mozilla/StaticAnalysisFunctions.h"
|
||||
#include "mozilla/TextEvents.h"
|
||||
#include "mozilla/dom/DocumentInlines.h"
|
||||
#include "mozilla/dom/KeyboardEvent.h"
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsMenuBarFrame.h"
|
||||
#include "nsMenuPopupFrame.h"
|
||||
#include "nsString.h"
|
||||
#include "nsStringFwd.h"
|
||||
#include "nsUTF8Utils.h"
|
||||
#include "nsXULElement.h"
|
||||
#include "nsMenuBarListener.h"
|
||||
#include "nsXULPopupManager.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
|
@ -127,8 +127,9 @@ void XULMenuParentElement::SetActiveMenuChild(XULButtonElement* aChild,
|
|||
}
|
||||
mActiveItem = nullptr;
|
||||
|
||||
if (nsMenuBarFrame* f = do_QueryFrame(GetPrimaryFrame())) {
|
||||
f->SetActive(!!aChild);
|
||||
if (auto* menuBar = XULMenuBarElement::FromNode(*this)) {
|
||||
// KnownLive because `this` is known-live by definition.
|
||||
MOZ_KnownLive(menuBar)->SetActive(!!aChild);
|
||||
}
|
||||
|
||||
if (!aChild) {
|
||||
|
|
@ -388,4 +389,10 @@ XULButtonElement* XULMenuParentElement::FindMenuWithShortcut(
|
|||
return foundMenuBeforeCurrent;
|
||||
}
|
||||
|
||||
void XULMenuParentElement::HandleEnterKeyPress(WidgetEvent& aEvent) {
|
||||
if (RefPtr child = GetActiveMenuChild()) {
|
||||
child->HandleEnterKeyPress(aEvent);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ class XULMenuParentElement : public nsXULElement {
|
|||
XULButtonElement* FindMenuWithShortcut(KeyboardEvent&) const;
|
||||
XULButtonElement* FindMenuWithShortcut(const nsAString& aString,
|
||||
bool& aDoAction) const;
|
||||
MOZ_CAN_RUN_SCRIPT void HandleEnterKeyPress(WidgetEvent&);
|
||||
|
||||
NS_IMPL_FROMNODE_HELPER(XULMenuParentElement,
|
||||
IsAnyOfXULElements(nsGkAtoms::menupopup,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#include "XULMenuParentElement.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsMenuBarListener.h"
|
||||
#include "nsNameSpaceManager.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsMenuPopupFrame.h"
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ EXPORTS.mozilla.dom += [
|
|||
"XULBroadcastManager.h",
|
||||
"XULButtonElement.h",
|
||||
"XULFrameElement.h",
|
||||
"XULMenuBarElement.h",
|
||||
"XULMenuElement.h",
|
||||
"XULMenuParentElement.h",
|
||||
"XULPersist.h",
|
||||
|
|
@ -35,6 +36,7 @@ EXPORTS.mozilla.dom += [
|
|||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
"MenuBarListener.cpp",
|
||||
"nsXULCommandDispatcher.cpp",
|
||||
"nsXULContentSink.cpp",
|
||||
"nsXULContentUtils.cpp",
|
||||
|
|
@ -46,6 +48,7 @@ UNIFIED_SOURCES += [
|
|||
"XULBroadcastManager.cpp",
|
||||
"XULButtonElement.cpp",
|
||||
"XULFrameElement.cpp",
|
||||
"XULMenuBarElement.cpp",
|
||||
"XULMenuElement.cpp",
|
||||
"XULMenuParentElement.cpp",
|
||||
"XULPersist.cpp",
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include "XULButtonElement.h"
|
||||
#include "XULFrameElement.h"
|
||||
#include "XULMenuElement.h"
|
||||
#include "XULMenuBarElement.h"
|
||||
#include "XULPopupElement.h"
|
||||
#include "XULResizerElement.h"
|
||||
#include "XULTextElement.h"
|
||||
|
|
@ -185,7 +186,7 @@ nsXULElement* nsXULElement::Construct(
|
|||
|
||||
if (nodeInfo->Equals(nsGkAtoms::menubar)) {
|
||||
auto* nim = nodeInfo->NodeInfoManager();
|
||||
return new (nim) XULMenuParentElement(nodeInfo.forget());
|
||||
return new (nim) XULMenuBarElement(nodeInfo.forget());
|
||||
}
|
||||
|
||||
if (nodeInfo->Equals(nsGkAtoms::menu) ||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@
|
|||
#include "mozilla/Unused.h"
|
||||
#include "RetainedDisplayListBuilder.h"
|
||||
#include "nsAbsoluteContainingBlock.h"
|
||||
#include "nsMenuBarListener.h"
|
||||
#include "nsCSSPseudoElements.h"
|
||||
#include "nsCheckboxRadioFrame.h"
|
||||
#include "nsCRT.h"
|
||||
|
|
@ -221,8 +220,6 @@ nsIFrame* NS_NewMenuPopupFrame(PresShell* aPresShell, ComputedStyle* aStyle);
|
|||
nsIFrame* NS_NewMenuFrame(PresShell* aPresShell, ComputedStyle* aStyle,
|
||||
uint32_t aFlags);
|
||||
|
||||
nsIFrame* NS_NewMenuBarFrame(PresShell* aPresShell, ComputedStyle* aStyle);
|
||||
|
||||
nsIFrame* NS_NewTreeBodyFrame(PresShell* aPresShell, ComputedStyle* aStyle);
|
||||
|
||||
nsHTMLScrollFrame* NS_NewHTMLScrollFrame(PresShell* aPresShell,
|
||||
|
|
@ -4155,8 +4152,6 @@ nsCSSFrameConstructor::FindXULTagData(const Element& aElement,
|
|||
nsCSSFrameConstructor::FindXULLabelOrDescriptionData),
|
||||
#ifdef XP_MACOSX
|
||||
SIMPLE_TAG_CHAIN(menubar, nsCSSFrameConstructor::FindXULMenubarData),
|
||||
#else
|
||||
SIMPLE_XUL_CREATE(menubar, NS_NewMenuBarFrame),
|
||||
#endif /* XP_MACOSX */
|
||||
SIMPLE_XUL_CREATE(iframe, NS_NewSubDocumentFrame),
|
||||
SIMPLE_XUL_CREATE(editor, NS_NewSubDocumentFrame),
|
||||
|
|
@ -4209,9 +4204,7 @@ nsCSSFrameConstructor::FindXULMenubarData(const Element& aElement,
|
|||
}
|
||||
}
|
||||
|
||||
static constexpr FrameConstructionData sMenubarData =
|
||||
SIMPLE_XUL_FCDATA(NS_NewMenuBarFrame);
|
||||
return &sMenubarData;
|
||||
return nullptr;
|
||||
}
|
||||
#endif /* XP_MACOSX */
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,6 @@ FRAME_CLASSES = [
|
|||
Frame("nsMathMLmunderoverFrame", "None", NOT_LEAF),
|
||||
Frame("nsMathMLsemanticsFrame", "None", NOT_LEAF),
|
||||
Frame("nsMathMLTokenFrame", "None", NOT_LEAF),
|
||||
Frame("nsMenuBarFrame", "Box", NOT_LEAF),
|
||||
Frame("nsMenuPopupFrame", "MenuPopup", NOT_LEAF),
|
||||
Frame("nsMeterFrame", "Meter", LEAF),
|
||||
Frame("nsNumberControlFrame", "TextInput", LEAF),
|
||||
|
|
|
|||
|
|
@ -25,8 +25,6 @@ UNIFIED_SOURCES += [
|
|||
"nsBoxLayoutState.cpp",
|
||||
"nsImageBoxFrame.cpp",
|
||||
"nsLeafBoxFrame.cpp",
|
||||
"nsMenuBarFrame.cpp",
|
||||
"nsMenuBarListener.cpp",
|
||||
"nsMenuPopupFrame.cpp",
|
||||
"nsRepeatService.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 "nsViewManager.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "nsMenuBarFrame.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsFrameManager.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
|
|
@ -2028,10 +2027,8 @@ nsIFrame* nsMenuPopupFrame::GetCurrentMenuItemFrame() const {
|
|||
|
||||
void nsMenuPopupFrame::HandleEnterKeyPress(WidgetEvent& aEvent) {
|
||||
mIncrementalString.Truncate();
|
||||
if (RefPtr menu = GetCurrentMenuItem()) {
|
||||
// Give it to the child.
|
||||
menu->HandleEnterKeyPress(aEvent);
|
||||
}
|
||||
RefPtr popup = &PopupElement();
|
||||
popup->HandleEnterKeyPress(aEvent);
|
||||
}
|
||||
|
||||
XULButtonElement* nsMenuPopupFrame::FindMenuWithShortcut(
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
#include "nsIContent.h"
|
||||
#include "nsNameSpaceManager.h"
|
||||
#include "nsBoxLayoutState.h"
|
||||
#include "nsMenuBarListener.h"
|
||||
#include "nsString.h"
|
||||
#include "nsITheme.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "XULButtonElement.h"
|
||||
#include "XULMenuParentElement.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/FlushType.h"
|
||||
|
|
@ -14,8 +13,6 @@
|
|||
#include "nsISound.h"
|
||||
#include "nsXULPopupManager.h"
|
||||
#include "nsMenuPopupFrame.h"
|
||||
#include "nsMenuBarFrame.h"
|
||||
#include "nsMenuBarListener.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsXULElement.h"
|
||||
#include "nsIDOMXULCommandDispatcher.h"
|
||||
|
|
@ -50,6 +47,7 @@
|
|||
#include "mozilla/dom/PopupPositionedEventBinding.h"
|
||||
#include "mozilla/dom/XULCommandEvent.h"
|
||||
#include "mozilla/dom/XULMenuElement.h"
|
||||
#include "mozilla/dom/XULMenuBarElement.h"
|
||||
#include "mozilla/dom/XULPopupElement.h"
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
#include "mozilla/EventStateManager.h"
|
||||
|
|
@ -77,6 +75,17 @@ static_assert(KeyboardEvent_Binding::DOM_VK_HOME ==
|
|||
KeyboardEvent_Binding::DOM_VK_END + 5,
|
||||
"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] = {
|
||||
{
|
||||
eNavigationDirection_Last, // KeyboardEvent_Binding::DOM_VK_END
|
||||
|
|
@ -707,7 +716,7 @@ nsMenuChainItem* nsXULPopupManager::GetRollupItem(RollupKind aKind) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void nsXULPopupManager::SetActiveMenuBar(nsMenuBarFrame* aMenuBar,
|
||||
void nsXULPopupManager::SetActiveMenuBar(XULMenuBarElement* aMenuBar,
|
||||
bool aActivate) {
|
||||
if (aActivate) {
|
||||
mActiveMenuBar = aMenuBar;
|
||||
|
|
@ -2010,7 +2019,7 @@ void nsXULPopupManager::UpdateKeyboardListeners() {
|
|||
}
|
||||
isForMenu = item->GetPopupType() == PopupType::Menu;
|
||||
} else if (mActiveMenuBar) {
|
||||
newTarget = mActiveMenuBar->GetContent()->GetComposedDoc();
|
||||
newTarget = mActiveMenuBar->GetComposedDoc();
|
||||
isForMenu = true;
|
||||
}
|
||||
|
||||
|
|
@ -2209,7 +2218,7 @@ bool nsXULPopupManager::HandleShortcutNavigation(KeyboardEvent& aKeyEvent,
|
|||
}
|
||||
|
||||
if (mActiveMenuBar) {
|
||||
RefPtr menubar = &mActiveMenuBar->MenubarElement();
|
||||
RefPtr menubar = mActiveMenuBar;
|
||||
if (RefPtr result = menubar->FindMenuWithShortcut(aKeyEvent)) {
|
||||
result->OpenMenuPopup(true);
|
||||
return true;
|
||||
|
|
@ -2222,7 +2231,7 @@ bool nsXULPopupManager::HandleShortcutNavigation(KeyboardEvent& aKeyEvent,
|
|||
if (nsCOMPtr<nsISound> sound = do_GetService("@mozilla.org/sound;1")) {
|
||||
sound->Beep();
|
||||
}
|
||||
mActiveMenuBar->SetActive(false);
|
||||
menubar->SetActive(false);
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
|
|
@ -2264,7 +2273,10 @@ bool nsXULPopupManager::HandleKeyboardNavigation(uint32_t aKeyCode) {
|
|||
if (item) {
|
||||
itemFrame = item->Frame();
|
||||
} else if (mActiveMenuBar) {
|
||||
itemFrame = mActiveMenuBar;
|
||||
itemFrame = mActiveMenuBar->GetPrimaryFrame();
|
||||
if (!itemFrame) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -2301,7 +2313,7 @@ bool nsXULPopupManager::HandleKeyboardNavigation(uint32_t aKeyCode) {
|
|||
if (!mActiveMenuBar) {
|
||||
return false;
|
||||
}
|
||||
RefPtr menubar = XULMenuParentElement::FromNode(mActiveMenuBar->GetContent());
|
||||
RefPtr menubar = mActiveMenuBar;
|
||||
if (NS_DIRECTION_IS_INLINE(theDirection)) {
|
||||
RefPtr prevActiveItem = menubar->GetActiveMenuChild();
|
||||
const bool open = prevActiveItem && prevActiveItem->IsMenuPopupOpen();
|
||||
|
|
@ -2460,7 +2472,8 @@ bool nsXULPopupManager::HandleKeyboardEventWithKeyCode(
|
|||
if (aTopVisibleMenuItem) {
|
||||
HidePopup(aTopVisibleMenuItem->Content(), {HidePopupOption::IsRollup});
|
||||
} else if (mActiveMenuBar) {
|
||||
mActiveMenuBar->MenuClosed();
|
||||
RefPtr menubar = mActiveMenuBar;
|
||||
menubar->MenuClosed();
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -2476,7 +2489,8 @@ bool nsXULPopupManager::HandleKeyboardEventWithKeyCode(
|
|||
Rollup({});
|
||||
break;
|
||||
} else if (mActiveMenuBar) {
|
||||
mActiveMenuBar->MenuClosed();
|
||||
RefPtr menubar = mActiveMenuBar;
|
||||
menubar->MenuClosed();
|
||||
break;
|
||||
}
|
||||
// Intentional fall-through to RETURN case
|
||||
|
|
@ -2490,7 +2504,8 @@ bool nsXULPopupManager::HandleKeyboardEventWithKeyCode(
|
|||
if (aTopVisibleMenuItem) {
|
||||
aTopVisibleMenuItem->Frame()->HandleEnterKeyPress(*event);
|
||||
} else if (mActiveMenuBar) {
|
||||
mActiveMenuBar->HandleEnterKeyPress(*event);
|
||||
RefPtr menubar = mActiveMenuBar;
|
||||
menubar->HandleEnterKeyPress(*event);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -2541,8 +2556,7 @@ nsresult nsXULPopupManager::UpdateIgnoreKeys(bool aIgnoreKeys) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsPopupState nsXULPopupManager::GetPopupState(
|
||||
mozilla::dom::Element* aPopupElement) {
|
||||
nsPopupState nsXULPopupManager::GetPopupState(Element* aPopupElement) {
|
||||
if (mNativeMenu && mNativeMenu->Element()->Contains(aPopupElement)) {
|
||||
if (aPopupElement != mNativeMenu->Element()) {
|
||||
// Submenu state is stored in mNativeMenuSubmenuStates.
|
||||
|
|
@ -2621,7 +2635,8 @@ nsresult nsXULPopupManager::KeyDown(KeyboardEvent* aKeyEvent) {
|
|||
if (item && !item->Frame()->IsMenuList()) {
|
||||
Rollup({});
|
||||
} else if (mActiveMenuBar) {
|
||||
mActiveMenuBar->MenuClosed();
|
||||
RefPtr menubar = mActiveMenuBar;
|
||||
menubar->MenuClosed();
|
||||
}
|
||||
|
||||
// Clear the item to avoid bugs as it may have been deleted during
|
||||
|
|
|
|||
|
|
@ -12,23 +12,19 @@
|
|||
#define nsXULPopupManager_h__
|
||||
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/widget/InitData.h"
|
||||
#include "nsHashtablesFwd.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIRollupListener.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "Units.h"
|
||||
#include "nsPoint.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsIReflowCallback.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/widget/InitData.h"
|
||||
#include "mozilla/widget/NativeMenu.h"
|
||||
#include "Units.h"
|
||||
|
||||
// XXX Avoid including this here by moving function bodies to the cpp file.
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
|
@ -54,9 +50,9 @@
|
|||
*/
|
||||
|
||||
class nsContainerFrame;
|
||||
class nsMenuPopupFrame;
|
||||
class nsMenuBarFrame;
|
||||
class nsITimer;
|
||||
class nsIDocShellTreeItem;
|
||||
class nsMenuPopupFrame;
|
||||
class nsPIDOMWindowOuter;
|
||||
class nsRefreshDriver;
|
||||
|
||||
|
|
@ -67,6 +63,7 @@ class Event;
|
|||
class KeyboardEvent;
|
||||
class UIEvent;
|
||||
class XULButtonElement;
|
||||
class XULMenuBarElement;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
@ -178,17 +175,6 @@ enum class HidePopupOption : uint8_t {
|
|||
|
||||
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
|
||||
* 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
|
||||
// aMenuBar isn't currently active, yet another menu bar is, that menu bar
|
||||
// will remain active.
|
||||
void SetActiveMenuBar(nsMenuBarFrame* aMenuBar, bool aActivate);
|
||||
void SetActiveMenuBar(mozilla::dom::XULMenuBarElement* aMenuBar,
|
||||
bool aActivate);
|
||||
|
||||
struct MayShowMenuResult {
|
||||
const bool mIsNative = false;
|
||||
|
|
@ -865,7 +852,7 @@ class nsXULPopupManager final : public nsIDOMEventListener,
|
|||
nsCOMPtr<nsIWidget> mWidget;
|
||||
|
||||
// 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
|
||||
// popup, which keeps alive all their parents.
|
||||
|
|
|
|||
Loading…
Reference in a new issue