mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
Bug 1705120 - Notify nsMenuX observers when a menu item is about to be activated, and supply the activated DOM element. r=harry
Differential Revision: https://phabricator.services.mozilla.com/D114434
This commit is contained in:
parent
65997668d2
commit
607f63b94a
@ -49,6 +49,8 @@ class NativeMenuMac : public NativeMenu,
|
||||
// nsMenuX::Observer
|
||||
void OnMenuWillOpen(mozilla::dom::Element* aPopupElement) override;
|
||||
void OnMenuDidOpen(mozilla::dom::Element* aPopupElement) override;
|
||||
void OnMenuWillActivateItem(mozilla::dom::Element* aPopupElement,
|
||||
mozilla::dom::Element* aMenuItemElement) override;
|
||||
void OnMenuClosed(mozilla::dom::Element* aPopupElement) override;
|
||||
|
||||
NSMenu* NativeNSMenu() { return mMenu ? mMenu->NativeNSMenu() : nil; }
|
||||
|
@ -192,6 +192,9 @@ void NativeMenuMac::OnMenuDidOpen(dom::Element* aPopupElement) {
|
||||
}
|
||||
}
|
||||
|
||||
void NativeMenuMac::OnMenuWillActivateItem(mozilla::dom::Element* aPopupElement,
|
||||
mozilla::dom::Element* aMenuItemElement) {}
|
||||
|
||||
void NativeMenuMac::OnMenuClosed(dom::Element* aPopupElement) {
|
||||
// Our caller isn't keeping us alive, so make sure we stay alive throughout this function in case
|
||||
// one of the observer notifications destroys us.
|
||||
@ -309,14 +312,16 @@ void NativeMenuMac::ActivateItem(dom::Element* aItemElement, Modifiers aModifier
|
||||
aRv.ThrowInvalidStateError("Menu containing menu item is not open");
|
||||
return;
|
||||
}
|
||||
Maybe<nsMenuX::MenuChild> item = menu->GetItemForElement(aItemElement);
|
||||
if (!item || !item->is<RefPtr<nsMenuItemX>>()) {
|
||||
Maybe<nsMenuX::MenuChild> child = menu->GetItemForElement(aItemElement);
|
||||
if (!child || !child->is<RefPtr<nsMenuItemX>>()) {
|
||||
aRv.ThrowInvalidStateError("Could not find the supplied menu item");
|
||||
return;
|
||||
}
|
||||
|
||||
menu->ActivateItemAfterClosing(std::move(item->as<RefPtr<nsMenuItemX>>()),
|
||||
ConvertModifierFlags(aModifiers), aButton);
|
||||
RefPtr<nsMenuItemX> item = std::move(child->as<RefPtr<nsMenuItemX>>());
|
||||
NSMenuItem* nativeItem = [item->NativeNSMenuItem() retain];
|
||||
|
||||
menu->ActivateItemAfterClosing(std::move(item), ConvertModifierFlags(aModifiers), aButton);
|
||||
|
||||
// Notify the entire menu structure that the menu is closing in response to ActivateItem.
|
||||
mMenu->MenuClosed(true);
|
||||
@ -328,6 +333,13 @@ void NativeMenuMac::ActivateItem(dom::Element* aItemElement, Modifiers aModifier
|
||||
// handler, at least on macOS 11. However, the resulting MenuClosed call will not do anything
|
||||
// because we already called MenuClosed above.
|
||||
[mMenu->NativeNSMenu() cancelTrackingWithoutAnimation];
|
||||
|
||||
// Call OnWillActivateItem at the end, to match the order of calls that happen when a user
|
||||
// activates a menu item in the real world: -[MenuDelegate menu:willActivateItem:] runs after
|
||||
// menuDidClose.
|
||||
menu->OnWillActivateItem(nativeItem);
|
||||
|
||||
[nativeItem release];
|
||||
}
|
||||
|
||||
void NativeMenuMac::OpenSubmenu(dom::Element* aMenuElement) {
|
||||
|
@ -47,6 +47,10 @@ class nsMenuXObserver {
|
||||
// No strong reference is held to the observer during the call.
|
||||
virtual void OnMenuDidOpen(mozilla::dom::Element* aPopupElement) = 0;
|
||||
|
||||
// Called before a menu item is activated.
|
||||
virtual void OnMenuWillActivateItem(mozilla::dom::Element* aPopupElement,
|
||||
mozilla::dom::Element* aMenuItemElement) = 0;
|
||||
|
||||
// Called when a menu in this menu subtree closed, after popuphidden.
|
||||
// No strong reference is held to the observer during the call.
|
||||
virtual void OnMenuClosed(mozilla::dom::Element* aPopupElement) = 0;
|
||||
@ -79,6 +83,8 @@ class nsMenuX final : public nsMenuParentX,
|
||||
// nsMenuXObserver, to forward notifications from our children to our observer.
|
||||
void OnMenuWillOpen(mozilla::dom::Element* aPopupElement) override;
|
||||
void OnMenuDidOpen(mozilla::dom::Element* aPopupElement) override;
|
||||
void OnMenuWillActivateItem(mozilla::dom::Element* aPopupElement,
|
||||
mozilla::dom::Element* aMenuItemElement) override;
|
||||
void OnMenuClosed(mozilla::dom::Element* aPopupElement) override;
|
||||
|
||||
bool IsVisible() const { return mVisible; }
|
||||
@ -138,6 +144,10 @@ class nsMenuX final : public nsMenuParentX,
|
||||
// mNativeMenu.
|
||||
void OnHighlightedItemChanged(const mozilla::Maybe<uint32_t>& aNewHighlightedIndex);
|
||||
|
||||
// Called from the menu delegate before an item anywhere in this menu is activated.
|
||||
// Called after MenuClosed().
|
||||
void OnWillActivateItem(NSMenuItem* aItem);
|
||||
|
||||
void SetRebuild(bool aMenuEvent);
|
||||
void SetupIcon();
|
||||
nsIContent* Content() { return mContent; }
|
||||
|
@ -189,6 +189,13 @@ void nsMenuX::OnMenuDidOpen(dom::Element* aPopupElement) {
|
||||
}
|
||||
}
|
||||
|
||||
void nsMenuX::OnMenuWillActivateItem(dom::Element* aPopupElement, dom::Element* aMenuItemElement) {
|
||||
RefPtr<nsMenuX> kungFuDeathGrip(this);
|
||||
if (mObserver) {
|
||||
mObserver->OnMenuWillActivateItem(aPopupElement, aMenuItemElement);
|
||||
}
|
||||
}
|
||||
|
||||
void nsMenuX::OnMenuClosed(dom::Element* aPopupElement) {
|
||||
RefPtr<nsMenuX> kungFuDeathGrip(this);
|
||||
if (mObserver) {
|
||||
@ -681,6 +688,22 @@ void nsMenuX::OnHighlightedItemChanged(const Maybe<uint32_t>& aNewHighlightedInd
|
||||
mHighlightedItemIndex = aNewHighlightedIndex;
|
||||
}
|
||||
|
||||
void nsMenuX::OnWillActivateItem(NSMenuItem* aItem) {
|
||||
if (!mIsOpenForGecko) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mMenuGroupOwner && mObserver) {
|
||||
nsMenuItemX* item = mMenuGroupOwner->GetMenuItemForCommandID(uint32_t(aItem.tag));
|
||||
if (item && item->Content()->IsElement()) {
|
||||
RefPtr<dom::Element> itemElement = item->Content()->AsElement();
|
||||
if (nsCOMPtr<nsIContent> popupContent = GetMenuPopupContent()) {
|
||||
mObserver->OnMenuWillActivateItem(popupContent->AsElement(), itemElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nsMenuX::RebuildMenu() {
|
||||
MOZ_RELEASE_ASSERT(mNeedsRebuild);
|
||||
gConstructingMenu = true;
|
||||
@ -1159,6 +1182,13 @@ void nsMenuX::Dump(uint32_t aIndent) const {
|
||||
|
||||
// This is called after menuDidClose:.
|
||||
- (void)menu:(NSMenu*)aMenu willActivateItem:(NSMenuItem*)aItem {
|
||||
if (!mGeckoMenu) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Hold a strong reference to mGeckoMenu while calling its methods.
|
||||
RefPtr<nsMenuX> geckoMenu = mGeckoMenu;
|
||||
geckoMenu->OnWillActivateItem(aItem);
|
||||
}
|
||||
|
||||
@end
|
||||
|
Loading…
Reference in New Issue
Block a user