Subject: Re: bug#4513: NS: File menu missing

From: David Reitter <[email-masked]>
Date: Wed, 23 Sep 2009 17:55:58 -0400

On Sep 21, 2009, at 9:00 PM, Adrian Robert wrote:
>> The file menu is missing; its contents are in the application menu  
>> (titled "Emacs"), and the usual contents of the application menu  
>> are completely gone.
>>
>> So I've got "Emacs Edit Options"
>
> Very odd.  I have not made any changes that I *think* could affect  
> this.  Have not seen the bug (10.4) -- even tried setting my lang to  
> German, but it might be I need to do another bootstrap build or  
> something.  There look like there were a lot of menu-related changes  
> in the lisp subdirectory on 2009-09-17.

OK, so it seems to me that the culprit may be:

       [menu clear];

in ns_update_menubar.

Removing the [menu clear] brings the File menu back.

I can't find the implementation of EmacsMenu's -clear, and it is not  
documented as a NSMenu (or NSObject) function.
This makes me think it's something undocumented implemented by the  
AppKit framework.  Didn't manage to class-dump that framework.

If the behavior of -clear has changed in the 10.6 SDK in this respect,  
I would not be surprised if, when compiled on 10.6, it may link  
against the new behavior (clearing everything), and when compiled on  
10.5, it's the old one.

If OS X forces the first menu to be the application name (and I think  
it does, see Info.plist setting), then we get the behavior I'm  
observing.

The patch below seems to do the job.  Hope this works in Nextstep as  
well.
I'll check that in unless you see a problem.

diff --git a/src/nsterm.h b/src/nsterm.h
index 96f65d2..c4935f2 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -118,7 +118,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/ 
 >.  */
  - (NSMenuItem *)addItemWithWidgetValue: (void *)wvptr;
  - (void)fillWithWidgetValue: (void *)wvptr;
  - (EmacsMenu *)addSubmenuWithTitle: (char *)title forFrame: (struct  
frame *)f;
-- (void) clear;
  - (Lisp_Object)runMenuAt: (NSPoint)p forFrame: (struct frame *)f
                   keymaps: (int)keymaps;
  @end
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 98a086b..f63852c 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -440,7 +440,10 @@ ns_update_menubar (struct frame *f, int deep_p,  
EmacsMenu *submenu)
              }
          }

-      [menu clear];
+      /* clear menu, leaving the first item (application menu) */
+      for (i = [menu numberOfItems]-1; i>0 ; i--)
+	[menu removeItemAtIndex:1];
+
        for (i = 0; i < XVECTOR (items)->size; i += 4)
  	{
  	  string = XVECTOR (items)->contents[i + 1];