mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 23:35:34 +00:00
Bug 1705842 - Allow opening empty menus, by putting a placeholder item in place. r=harry
This is exercised by one of the subtests of browser/components/extensions/test/browser/browser_ext_menus_replace_menu.js : The menu is opened while it's empty, and then the content items are added asynchronously while the menu is open. If we try to open an NSMenu with zero NSMenuItems, macOS immediately closes the menu after opening it. With a placeholder item it stays open as expected. Differential Revision: https://phabricator.services.mozilla.com/D112458
This commit is contained in:
parent
01f82d18dd
commit
a29fcf0959
@ -203,6 +203,12 @@ class nsMenuX final : public nsMenuParentX,
|
||||
// popuphiding/popuphidden events.
|
||||
void FlushMenuClosedRunnable();
|
||||
|
||||
// Make sure the NSMenu contains at least one item, even if mVisibleItemsCount is zero.
|
||||
// Otherwise it won't open.
|
||||
void InsertPlaceholderIfNeeded();
|
||||
// Remove the placeholder before adding an item to mNativeNSMenu.
|
||||
void RemovePlaceholderIfPresent();
|
||||
|
||||
nsCOMPtr<nsIContent> mContent; // XUL <menu> or <menupopup>
|
||||
|
||||
// Contains nsMenuX and nsMenuItemX objects
|
||||
|
@ -97,12 +97,7 @@ nsMenuX::nsMenuX(nsMenuParentX* aParent, nsMenuGroupOwnerX* aMenuGroupOwner, nsI
|
||||
NS_ASSERTION(mMenuGroupOwner, "No menu owner given, must have one");
|
||||
mMenuGroupOwner->RegisterForContentChanges(mContent, this);
|
||||
|
||||
if (nsMenuUtilsX::NodeIsHiddenOrCollapsed(mContent)) {
|
||||
mVisible = false;
|
||||
}
|
||||
if (mContent->GetChildCount() == 0) {
|
||||
mVisible = false;
|
||||
}
|
||||
mVisible = !nsMenuUtilsX::NodeIsHiddenOrCollapsed(mContent);
|
||||
|
||||
NSString* newCocoaLabelString = nsMenuUtilsX::GetTruncatedCocoaLabel(mLabel);
|
||||
mNativeMenuItem = [[NSMenuItem alloc] initWithTitle:newCocoaLabelString
|
||||
@ -214,6 +209,7 @@ void nsMenuX::AddMenuChild(MenuChild&& aChild) {
|
||||
[](const RefPtr<nsMenuItemX>& aMenuItem) { return aMenuItem->NativeNSMenuItem(); });
|
||||
|
||||
if (isVisible) {
|
||||
RemovePlaceholderIfPresent();
|
||||
[mNativeMenu addItem:nativeItem];
|
||||
++mVisibleItemsCount;
|
||||
}
|
||||
@ -690,10 +686,38 @@ void nsMenuX::RebuildMenu() {
|
||||
}
|
||||
} // for each menu item
|
||||
|
||||
InsertPlaceholderIfNeeded();
|
||||
|
||||
gConstructingMenu = false;
|
||||
mNeedsRebuild = false;
|
||||
}
|
||||
|
||||
void nsMenuX::InsertPlaceholderIfNeeded() {
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if ([mNativeMenu numberOfItems] == 0) {
|
||||
MOZ_RELEASE_ASSERT(mVisibleItemsCount == 0);
|
||||
NSMenuItem* item = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
|
||||
item.enabled = NO;
|
||||
item.view = [[[NSView alloc] initWithFrame:NSMakeRect(0, 0, 150, 1)] autorelease];
|
||||
[mNativeMenu addItem:item];
|
||||
[item release];
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
void nsMenuX::RemovePlaceholderIfPresent() {
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (mVisibleItemsCount == 0 && [mNativeMenu numberOfItems] == 1) {
|
||||
// Remove the placeholder.
|
||||
[mNativeMenu removeItemAtIndex:0];
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
void nsMenuX::SetRebuild(bool aNeedsRebuild) {
|
||||
if (!gConstructingMenu) {
|
||||
mNeedsRebuild = aNeedsRebuild;
|
||||
@ -975,6 +999,7 @@ void nsMenuX::MenuChildChangedVisibility(const MenuChild& aChild, bool aIsVisibl
|
||||
if (aIsVisible) {
|
||||
MOZ_RELEASE_ASSERT(!nativeItem.menu,
|
||||
"The native item should not be in a menu while it is hidden");
|
||||
RemovePlaceholderIfPresent();
|
||||
NSInteger insertionPoint = CalculateNativeInsertionPoint(aChild);
|
||||
[mNativeMenu insertItem:nativeItem atIndex:insertionPoint];
|
||||
mVisibleItemsCount++;
|
||||
@ -983,6 +1008,7 @@ void nsMenuX::MenuChildChangedVisibility(const MenuChild& aChild, bool aIsVisibl
|
||||
"The native item should be in this menu while it is visible");
|
||||
[mNativeMenu removeItem:nativeItem];
|
||||
mVisibleItemsCount--;
|
||||
InsertPlaceholderIfNeeded();
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
|
Loading…
Reference in New Issue
Block a user