Bug 1151345 - Firefox app menu sometimes contains only "Quit" on OS X. r=spohl a=lhenry
authorSteven Michaud <smichaud@pobox.com>
Tue, 16 Jun 2015 15:12:47 -0500
changeset 275088 73a10017683c4c6c6f3b8a91b5cd79ae9a71b1d6
parent 275087 9c1c61548c328d0643cb52022a48be35c9ae4cf1
child 275089 3830ac632774795e022cd4ae3a69f7d8ff5613be
push id863
push userraliiev@mozilla.com
push dateMon, 03 Aug 2015 13:22:43 +0000
treeherdermozilla-release@f6321b14228d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersspohl, lhenry
bugs1151345
milestone40.0a2
Bug 1151345 - Firefox app menu sometimes contains only "Quit" on OS X. r=spohl a=lhenry
widget/cocoa/nsAppShell.mm
widget/cocoa/nsMenuBarX.h
widget/cocoa/nsMenuBarX.mm
--- a/widget/cocoa/nsAppShell.mm
+++ b/widget/cocoa/nsAppShell.mm
@@ -23,16 +23,17 @@
 #include "nsIWindowMediator.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsObjCExceptions.h"
 #include "nsCocoaFeatures.h"
 #include "nsCocoaUtils.h"
 #include "nsChildView.h"
+#include "nsMenuBarX.h"
 #include "nsToolkit.h"
 #include "TextInputHandler.h"
 #include "mozilla/HangMonitor.h"
 #include "GeckoProfiler.h"
 #include "pratom.h"
 
 #include <IOKit/pwr_mgt/IOPMLib.h>
 #include "nsIDOMWakeLockListener.h"
@@ -642,16 +643,17 @@ nsAppShell::Run(void)
 {
   NS_ASSERTION(!mStarted, "nsAppShell::Run() called multiple times");
   if (mStarted || mTerminated)
     return NS_OK;
 
   mStarted = true;
 
   AddScreenWakeLockListener();
+  nsMenuBarX::ResetNativeApplicationMenu();
 
   NS_OBJC_TRY_ABORT([NSApp run]);
 
   RemoveScreenWakeLockListener();
 
   return NS_OK;
 }
 
--- a/widget/cocoa/nsMenuBarX.h
+++ b/widget/cocoa/nsMenuBarX.h
@@ -121,16 +121,17 @@ public:
   nsMenuX*          GetXULHelpMenu();
   void              SetSystemHelpMenu();
   nsresult          Paint(bool aDelayed = false);
   void              PaintMenuBarAfterDelay();
   void              ResetAwaitingDelayedPaint() { mAwaitingDelayedPaint = false; }
   void              ForceUpdateNativeMenuAt(const nsAString& indexString);
   void              ForceNativeMenuReload(); // used for testing
   static char       GetLocalizedAccelKey(const char *shortcutID);
+  static void       ResetNativeApplicationMenu();
 
 protected:
   void              ConstructNativeMenus();
   void              ConstructFallbackNativeMenus();
   nsresult          InsertMenuAtIndex(nsMenuX* aMenu, uint32_t aIndex);
   void              RemoveMenuAtIndex(uint32_t aIndex);
   void              HideItem(nsIDOMDocument* inDoc, const nsAString & inID, nsIContent** outHiddenNode);
   void              AquifyMenuBar();
--- a/widget/cocoa/nsMenuBarX.mm
+++ b/widget/cocoa/nsMenuBarX.mm
@@ -181,23 +181,16 @@ void nsMenuBarX::ConstructFallbackNative
 
   sApplicationMenu = [[[[NSApp mainMenu] itemAtIndex:0] submenu] retain];
   NSMenuItem* quitMenuItem = [[[NSMenuItem alloc] initWithTitle:labelStr
                                                   action:@selector(menuItemHit:)
                                                   keyEquivalent:keyStr] autorelease];
   [quitMenuItem setTarget:nsMenuBarX::sNativeEventTarget];
   [quitMenuItem setTag:eCommand_ID_Quit];
   [sApplicationMenu addItem:quitMenuItem];
-
-  // Add debug logging to help decipher bug 1151345.
-#if !defined(RELEASE_BUILD) || defined(DEBUG)
-  NSLog(@"nsMenuBarX::ConstructFallbackNativeMenus(): labelUTF16 %s, keyUTF16 %s",
-        NS_ConvertUTF16toUTF8(labelUTF16).get(),
-        NS_ConvertUTF16toUTF8(keyUTF16).get());
-#endif
 }
 
 uint32_t nsMenuBarX::GetMenuCount()
 {
   return mMenuArray.Length();
 }
 
 bool nsMenuBarX::MenuContainsAppMenu()
@@ -499,16 +492,24 @@ char nsMenuBarX::GetLocalizedAccelKey(co
   if (strlen(keyASCPtr) != sizeof(char))
     return 0;
   // Make sure retval is lower case.
   char retval = tolower(keyASCPtr[0]);
 
   return retval;
 }
 
+/* static */
+void nsMenuBarX::ResetNativeApplicationMenu()
+{
+  [sApplicationMenu removeAllItems];
+  [sApplicationMenu release];
+  sApplicationMenu = nil;
+}
+
 // Hide the item in the menu by setting the 'hidden' attribute. Returns it in |outHiddenNode| so
 // the caller can hang onto it if they so choose. It is acceptable to pass nsull
 // for |outHiddenNode| if the caller doesn't care about the hidden node.
 void nsMenuBarX::HideItem(nsIDOMDocument* inDoc, const nsAString & inID, nsIContent** outHiddenNode)
 {
   nsCOMPtr<nsIDOMElement> menuItem;
   inDoc->GetElementById(inID, getter_AddRefs(menuItem));  
   nsCOMPtr<nsIContent> menuContent(do_QueryInterface(menuItem));
@@ -554,55 +555,38 @@ void nsMenuBarX::AquifyMenuBar()
 }
 
 // for creating menu items destined for the Application menu
 NSMenuItem* nsMenuBarX::CreateNativeAppMenuItem(nsMenuX* inMenu, const nsAString& nodeID, SEL action,
                                                 int tag, NativeMenuItemTarget* target)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
-  // Add debug logging to help decipher bug 1151345.
-#if !defined(RELEASE_BUILD) || defined(DEBUG)
-  NS_ConvertUTF16toUTF8 nodeID_UTF8(nodeID);
-#endif
-
   nsCOMPtr<nsIDocument> doc = inMenu->Content()->GetUncomposedDoc();
   if (!doc) {
-#if !defined(RELEASE_BUILD) || defined(DEBUG)
-    NSLog(@"nsMenuBarX::CreateNativeAppMenuItem(1): nodeID %s, doc is null!",
-          nodeID_UTF8.get());
-#endif
     return nil;
   }
 
   nsCOMPtr<nsIDOMDocument> domdoc(do_QueryInterface(doc));
   if (!domdoc) {
-#if !defined(RELEASE_BUILD) || defined(DEBUG)
-    NSLog(@"nsMenuBarX::CreateNativeAppMenuItem(2): nodeID %s, domdoc is null!",
-          nodeID_UTF8.get());
-#endif
     return nil;
   }
 
   // Get information from the gecko menu item
   nsAutoString label;
   nsAutoString modifiers;
   nsAutoString key;
   nsCOMPtr<nsIDOMElement> menuItem;
   domdoc->GetElementById(nodeID, getter_AddRefs(menuItem));
   if (menuItem) {
     menuItem->GetAttribute(NS_LITERAL_STRING("label"), label);
     menuItem->GetAttribute(NS_LITERAL_STRING("modifiers"), modifiers);
     menuItem->GetAttribute(NS_LITERAL_STRING("key"), key);
   }
   else {
-#if !defined(RELEASE_BUILD) || defined(DEBUG)
-    NSLog(@"nsMenuBarX::CreateNativeAppMenuItem(3): nodeID %s, menuItem is null!",
-          nodeID_UTF8.get());
-#endif
     return nil;
   }
 
   // Get more information about the key equivalent. Start by
   // finding the key node we need.
   NSString* keyEquiv = nil;
   unsigned int macKeyModifiers = 0;
   if (!key.IsEmpty()) {
@@ -639,25 +623,16 @@ NSMenuItem* nsMenuBarX::CreateNativeAppM
   [newMenuItem setTag:tag];
   [newMenuItem setTarget:target];
   [newMenuItem setKeyEquivalentModifierMask:macKeyModifiers];
 
   MenuItemInfo * info = [[MenuItemInfo alloc] initWithMenuGroupOwner:this];
   [newMenuItem setRepresentedObject:info];
   [info release];
 
-#if !defined(RELEASE_BUILD) || defined(DEBUG)
-  if (!newMenuItem) {
-    NSLog(@"nsMenuBarX::CreateNativeAppMenuItem(4): nodeID %s, label %s, modifiers %s, key %s, newMenuItem is null!",
-          nodeID_UTF8.get(),
-          NS_ConvertUTF16toUTF8(label).get(),
-          NS_ConvertUTF16toUTF8(modifiers).get(),
-          NS_ConvertUTF16toUTF8(key).get());
-  }
-#endif
   return newMenuItem;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 // build the Application menu shared by all menu bars
 nsresult nsMenuBarX::CreateApplicationMenu(nsMenuX* inMenu)
 {