Bug 1741089 - Make async OpenMenu simpler/sound. r=mstange

There's only one caller of it and it's not sound: The runnable captures a
raw frame pointer etc. Instead, just do a dispatch to the main thread
and call OpenMenu there. This simplifies the following patch.

Differential Revision: https://phabricator.services.mozilla.com/D131082
This commit is contained in:
Emilio Cobos Álvarez 2021-11-16 15:43:38 +00:00
parent f4838a045c
commit 3cf56f8e1f
6 changed files with 24 additions and 32 deletions

View File

@ -58,7 +58,7 @@ void XULPopupElement::OpenPopup(Element* aAnchorElement,
if (!aAnchorElement && position.IsEmpty() && GetPrimaryFrame()) {
nsMenuFrame* menu = do_QueryFrame(GetPrimaryFrame()->GetParent());
if (menu) {
pm->ShowMenu(menu->GetContent(), false, false);
pm->ShowMenu(menu->GetContent(), false);
return;
}
}

View File

@ -458,7 +458,7 @@ void nsXULElement::OpenMenu(bool aOpenFlag) {
if (pm) {
if (aOpenFlag) {
// Nothing will happen if this element isn't a menu.
pm->ShowMenu(this, false, false);
pm->ShowMenu(this, false);
} else {
// Nothing will happen if this element isn't a menu.
pm->HideMenu(this);

View File

@ -260,7 +260,9 @@ class nsMenuBarSwitchMenu : public Runnable {
if (mNewMenu && weakMenuBar.IsAlive()) menubar->SetStayActive(false);
}
if (mNewMenu) pm->ShowMenu(mNewMenu, mSelectFirstItem, false);
if (mNewMenu) {
pm->ShowMenu(mNewMenu, mSelectFirstItem);
}
return NS_OK;
}

View File

@ -613,12 +613,18 @@ nsresult nsMenuFrame::AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
void nsMenuFrame::OpenMenu(bool aSelectFirstItem) {
if (!mContent) return;
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
if (pm) {
if (nsXULPopupManager* pm = nsXULPopupManager::GetInstance()) {
pm->KillMenuTimer();
// This opens the menu asynchronously
pm->ShowMenu(mContent, aSelectFirstItem, true);
}
// Open the menu asynchronously.
mContent->OwnerDoc()->Dispatch(
TaskCategory::Other,
NS_NewRunnableFunction(
"AsyncOpenMenu", [content = RefPtr{mContent.get()}, aSelectFirstItem] {
if (nsXULPopupManager* pm = nsXULPopupManager::GetInstance()) {
pm->ShowMenu(content, aSelectFirstItem);
}
}));
}
void nsMenuFrame::CloseMenu(bool aDeselectMenu) {

View File

@ -687,8 +687,7 @@ static CloseMenuMode GetCloseMenuMode(nsIContent* aMenu) {
}
}
void nsXULPopupManager::ShowMenu(nsIContent* aMenu, bool aSelectFirstItem,
bool aAsynchronous) {
void nsXULPopupManager::ShowMenu(nsIContent* aMenu, bool aSelectFirstItem) {
if (mNativeMenu && aMenu->IsElement() &&
mNativeMenu->Element()->Contains(aMenu)) {
mNativeMenu->OpenSubmenu(aMenu->AsElement());
@ -728,22 +727,8 @@ void nsXULPopupManager::ShowMenu(nsIContent* aMenu, bool aSelectFirstItem,
// there is no trigger event for menus
popupFrame->InitializePopup(aMenu, nullptr, position, 0, 0,
MenuPopupAnchorType_Node, true);
if (aAsynchronous) {
nsCOMPtr<nsIRunnable> event =
NS_NewRunnableFunction("BeginShowingPopup", [=]() {
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
if (pm) {
PendingPopup pendingPopup(popupFrame->GetContent(), nullptr);
pm->BeginShowingPopup(pendingPopup, parentIsContextMenu,
aSelectFirstItem);
}
});
aMenu->OwnerDoc()->Dispatch(TaskCategory::Other, event.forget());
} else {
PendingPopup pendingPopup(popupFrame->GetContent(), nullptr);
BeginShowingPopup(pendingPopup, parentIsContextMenu, aSelectFirstItem);
}
PendingPopup pendingPopup(popupFrame->GetContent(), nullptr);
BeginShowingPopup(pendingPopup, parentIsContextMenu, aSelectFirstItem);
}
void nsXULPopupManager::ShowPopup(nsIContent* aPopup,
@ -2207,7 +2192,7 @@ bool nsXULPopupManager::HandleShortcutNavigation(KeyboardEvent* aKeyEvent,
nsMenuFrame* menuToOpen = result->Enter(evt);
if (menuToOpen) {
nsCOMPtr<nsIContent> content = menuToOpen->GetContent();
ShowMenu(content, true, false);
ShowMenu(content, true);
}
}
return true;
@ -2306,7 +2291,7 @@ bool nsXULPopupManager::HandleKeyboardNavigation(uint32_t aKeyCode) {
// Open the menu and select its first item.
if (currentMenu) {
nsCOMPtr<nsIContent> content = currentMenu->GetContent();
ShowMenu(content, true, false);
ShowMenu(content, true);
}
return true;
}
@ -2353,7 +2338,7 @@ bool nsXULPopupManager::HandleKeyboardNavigationInPopup(
!currentMenu->IsDisabled()) {
// The menu is not yet open. Open it and select the first item.
nsCOMPtr<nsIContent> content = currentMenu->GetContent();
ShowMenu(content, true, false);
ShowMenu(content, true);
return true;
}
}
@ -2491,7 +2476,7 @@ bool nsXULPopupManager::HandleKeyboardEventWithKeyCode(
}
if (menuToOpen) {
nsCOMPtr<nsIContent> content = menuToOpen->GetContent();
ShowMenu(content, true, false);
ShowMenu(content, true);
}
break;
}

View File

@ -470,10 +470,9 @@ class nsXULPopupManager final : public nsIDOMEventListener,
/**
* Open a <menu> given its content node. If aSelectFirstItem is
* set to true, the first item on the menu will automatically be
* selected. If aAsynchronous is true, the event will be dispatched
* asynchronously. This should be true when called from frame code.
* selected.
*/
void ShowMenu(nsIContent* aMenu, bool aSelectFirstItem, bool aAsynchronous);
void ShowMenu(nsIContent* aMenu, bool aSelectFirstItem);
/**
* Open a popup, either anchored or unanchored. If aSelectFirstItem is