Bug 1151345 - Firefox app menu sometimes contains only "Quit" on OS X. r=spohl
authorSteven Michaud <smichaud@pobox.com>
Wed, 03 Jun 2015 16:19:51 -0500 (2015-06-03)
changeset 247063 0c9e32f0a414336522a7d5291b609d9a382e2961
parent 247062 e8d023189937e5e376b41000aaee5f57e7e0eeed
child 247064 d1e89b1e03d619dd0f64cd0a84e49554d94f2dcb
push id28852
push userryanvm@gmail.com
push dateThu, 04 Jun 2015 12:39:12 +0000 (2015-06-04)
treeherdermozilla-central@b2ad2f9f8e53 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersspohl
bugs1151345
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1151345 - Firefox app menu sometimes contains only "Quit" on OS X. r=spohl
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)
 {