Make the "About" menu item in the Mac OS X application menu work like the Prefs and Quit menu item. Fixes non-functional about menu item in Venkman. b=369767 r=smorgan sr=pinkerton
authorjoshmoz@gmail.com
Tue, 27 Mar 2007 15:40:27 -0700
changeset 164 d2ae6d75735f4c127f11c95bf833c2ea1d980a00
parent 163 b56a4cec418c6a420c3e45d9bad4db2327a94313
child 165 4ac3a5d84dd1a1b3274d47d5c8b206a714ec78bc
push idunknown
push userunknown
push dateunknown
reviewerssmorgan, pinkerton
bugs369767
milestone1.9a4pre
Make the "About" menu item in the Mac OS X application menu work like the Prefs and Quit menu item. Fixes non-functional about menu item in Venkman. b=369767 r=smorgan sr=pinkerton
widget/src/cocoa/nsMenuBarX.h
widget/src/cocoa/nsMenuBarX.mm
--- a/widget/src/cocoa/nsMenuBarX.h
+++ b/widget/src/cocoa/nsMenuBarX.h
@@ -150,18 +150,19 @@ protected:
     NSMenuItem* nsMenuBarX::CreateNativeAppMenuItem(nsIMenu* inMenu, const nsAString& nodeID, SEL action,
                                                     int tag, NativeMenuItemTarget* target);
     nsresult CreateApplicationMenu(nsIMenu* inMenu);
 
     nsHashtable             mObserverTable;       // stores observers for content change notification
 
     nsCOMArray<nsIMenu>     mMenusArray;          // holds refs
     nsCOMPtr<nsIContent>    mMenuBarContent;      // menubar content node, strong ref
-    nsCOMPtr<nsIContent>    mPrefItemContent;     // on X, holds the content node for the prefs item that has
-                                                  // been removed from the menubar
+    nsCOMPtr<nsIContent>    mAboutItemContent;    // holds the content node for the about item that has
+                                                  //   been removed from the menubar
+    nsCOMPtr<nsIContent>    mPrefItemContent;     // as above, but for prefs
     nsCOMPtr<nsIContent>    mQuitItemContent;     // as above, but for quit
     nsIWidget*              mParent;              // weak ref
     PRBool                  mIsMenuBarAdded;
     PRUint32                mCurrentCommandID;    // unique command id (per menu-bar) to give to next item that asks
 
 
     nsWeakPtr               mDocShellWeakRef;     // weak ref to docshell
     nsIDocument*            mDocument;            // pointer to document
--- a/widget/src/cocoa/nsMenuBarX.mm
+++ b/widget/src/cocoa/nsMenuBarX.mm
@@ -74,18 +74,19 @@ NativeMenuItemTarget* nsMenuBarX::sNativ
 NSWindow* nsMenuBarX::sEventTargetWindow = nil;
 NSMenu* sApplicationMenu = nil;
 BOOL gSomeMenuBarPainted = NO;
 
 // We keep references to the first quit and pref item content nodes we find, which
 // will be from the hidden window. We use these when the document for the current
 // window does not have a quit or pref item. We don't need strong refs here because
 // these items are always strong ref'd by their owning menu bar (instance variable).
-static nsIContent* sQuitItemContent = nsnull;
-static nsIContent* sPrefItemContent = nsnull;
+static nsIContent* sAboutItemContent = nsnull;
+static nsIContent* sPrefItemContent  = nsnull;
+static nsIContent* sQuitItemContent  = nsnull;
 
 // Special command IDs that we know Mac OS X does not use for anything else. We use
 // these in place of carbon's IDs for these commands in order to stop Carbon from
 // messing with our event handlers. See bug 346883.
 enum {
   eCommand_ID_About = 1,
   eCommand_ID_Prefs = 2,
   eCommand_ID_Quit  = 3,
@@ -114,16 +115,18 @@ nsMenuBarX::nsMenuBarX()
 
 
 nsMenuBarX::~nsMenuBarX()
 {
   mMenusArray.Clear(); // release all menus
 
   // the quit/pref items of a random window might have been used if there was no
   // hidden window, thus we need to invalidate the weak references.
+  if (sAboutItemContent == mAboutItemContent)
+    sAboutItemContent = nsnull;
   if (sQuitItemContent == mQuitItemContent)
     sQuitItemContent = nsnull;
   if (sPrefItemContent == mPrefItemContent)
     sPrefItemContent = nsnull;
 
   // make sure we unregister ourselves as a document observer
   if (mDocument)
     mDocument->RemoveMutationObserver(this);
@@ -245,16 +248,21 @@ nsMenuBarX::RegisterAsDocumentObserver(n
 // means removing 'Quit' from the file menu and 'Preferences' from the edit menu, along
 // with their various separators (if present).
 //
 void
 nsMenuBarX::AquifyMenuBar()
 {
   nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(mMenuBarContent->GetDocument()));
   if (domDoc) {
+    // remove the "About..." menu item
+    HideItem(domDoc, NS_LITERAL_STRING("aboutName"), getter_AddRefs(mAboutItemContent));
+    if (!sAboutItemContent)
+      sAboutItemContent = mAboutItemContent;
+
     // remove quit item and its separator
     HideItem(domDoc, NS_LITERAL_STRING("menu_FileQuitSeparator"), nsnull);
     HideItem(domDoc, NS_LITERAL_STRING("menu_FileQuitItem"), getter_AddRefs(mQuitItemContent));
     if (!sQuitItemContent)
       sQuitItemContent = mQuitItemContent;
     
     // remove prefs item and its separator, but save off the pref content node
     // so we can invoke its command later.
@@ -309,16 +317,28 @@ nsMenuBarX::CommandEventHandler(EventHan
   OSErr err1 = ::GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand,
                                    NULL, sizeof(HICommand), NULL, &command);
   if (err1)
     return handled;
   
   nsMenuBarX* self = NS_REINTERPRET_CAST(nsMenuBarX*, userData);
 
   switch (command.commandID) {
+    case eCommand_ID_About:
+    {
+      nsIContent* mostSpecificContent = sAboutItemContent;
+      if (self->mAboutItemContent)
+        mostSpecificContent = self->mAboutItemContent;
+      
+      nsEventStatus status = self->ExecuteCommand(mostSpecificContent);
+      if (status == nsEventStatus_eConsumeNoDefault) // event handled, no other processing
+        handled = noErr;
+      break;
+    }
+
     case eCommand_ID_Prefs:
     {
       nsIContent* mostSpecificContent = sPrefItemContent;
       if (self->mPrefItemContent)
         mostSpecificContent = self->mPrefItemContent;
       
       nsEventStatus status = self->ExecuteCommand(mostSpecificContent);
       if (status == nsEventStatus_eConsumeNoDefault) // event handled, no other processing
@@ -339,35 +359,16 @@ nsMenuBarX::CommandEventHandler(EventHan
         nsEventStatus status = self->ExecuteCommand(mostSpecificContent);
         if (status == nsEventStatus_eConsumeNoDefault) // event handled, no other processing
           handled = noErr;
       }
       else {
         [NSApp terminate:nil];
         handled = noErr;
       }
-
-      break;
-    }
-
-    case eCommand_ID_About:
-    {
-      // the 'about' command is special because we don't have a
-      // nsIMenu or nsIMenuItem for the application menu. Grovel for the
-      // content node with an id of "aboutName" and call it
-      // directly.
-      nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(self->mDocument);
-      if (domDoc) {
-        nsCOMPtr<nsIDOMElement> domElement;
-        domDoc->GetElementById(NS_LITERAL_STRING("aboutName"),
-                               getter_AddRefs(domElement));
-        nsCOMPtr<nsIContent> aboutContent(do_QueryInterface(domElement));
-        self->ExecuteCommand(aboutContent);
-      }
-      handled = noErr;
       break;
     }
 
     default:
     {
       // given the commandID, look it up in our hashtable and dispatch to
       // that content node. Recall that we store weak pointers to the content
       // nodes in the hash table.