Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 329456

Summary: Add API to access the application menu (Mac) and system menu (win32/gtk)
Product: [Eclipse Project] Platform Reporter: Scott Kovatch <skovatch>
Component: SWTAssignee: Scott Kovatch <skovatch>
Status: RESOLVED FIXED QA Contact: Silenio Quarti <Silenio_Quarti>
Severity: enhancement    
Priority: P3 CC: bsd, eclipse.felipe, prakash, pwebster, tom.schindl
Version: 3.6Flags: Silenio_Quarti: review+
Target Milestone: 3.7 M6   
Hardware: All   
OS: Mac OS X   
Whiteboard:
Bug Depends on:    
Bug Blocks: 153761, 337482    
Attachments:
Description Flags
Cocoa implementation
none
Cocoa implementation
none
Modified test case
none
Implementation for non-cocoa platforms
none
Cocoa implementation
none
Implementation for non-cocoa platforms
none
implementation for all platforms
none
testcase none

Description Scott Kovatch CLA 2010-11-04 12:40:14 EDT
On the Mac developers want control over the application menu. They want to set the about menu text, enable/disable/hide the preferences item, and add items to the application menu. They also want to listen for selections on those items. In other words, treat it like any other Menu in the application.

Likewise, on Win32 or Linux, you can access the system menu of a window and listen to each of its items, as well as add items to the menu.

On the Mac the only way to do this right now is via the eAWT package from Apple. This works correctly now, in 3.7, but using it loads the AWT, which shouldn't be necessary just to listen to some menu items that the SWT creates anyway.

On Windows or GTK the system menu is not accessible without going to the PI. I know it can be done on Win32 as we already modify it for TOOL and child windows. We don't do it in GTK but I'm pretty sure I saw API somewhere to get at the system menu.
Comment 1 Scott Kovatch CLA 2010-11-10 19:29:43 EST
Created attachment 182863 [details]
Cocoa implementation

Cocoa implementation implementing Menu.findItem, Display.getAppMenu(), MenuItem.get/setId. I'll attach a test case shortly.
Comment 2 Scott Kovatch CLA 2010-11-10 20:25:47 EST
Created attachment 182865 [details]
Cocoa implementation

Small fix  -- not comparing NSMenuItems properly.
Comment 3 Scott Kovatch CLA 2010-11-11 12:09:28 EST
Created attachment 182921 [details]
Modified test case

This snippet uses the new API to modify the application menu and listen for selections on application menu items. It also blocks the Hide and Hide Others as a demonstration.
Comment 4 Prakash Rangaraj CLA 2010-11-17 06:45:42 EST
Scott,

    The API looks good. (See Bug# 153761) Is this bug targeted for M4?
Comment 5 Scott Kovatch CLA 2010-11-17 13:26:43 EST
I hope to get this into 3.7m4. The findItem/getId/setId API is trivial on all other platforms.

(moving to Cocoa so I don't lose it.)
Comment 6 Scott Kovatch CLA 2010-12-02 19:20:09 EST
Created attachment 184428 [details]
Implementation for non-cocoa platforms

setId/getId, findItem for all other platforms.
Comment 7 Scott Kovatch CLA 2010-12-02 19:27:29 EST
M4 is coming up next week, so it will be reviewed for m5.
Comment 8 Prakash Rangaraj CLA 2011-01-21 01:11:13 EST
Is this going into M5?
Comment 9 Scott Kovatch CLA 2011-02-09 14:32:41 EST
Waiting on review -- would be good to get this in for 3.7.
Comment 10 Scott Kovatch CLA 2011-02-15 18:22:55 EST
Created attachment 189059 [details]
Cocoa implementation

Updated after code review. Greatly simplified creating placeholder MenuItems that correspond to application menu items. Also sync item text and accelerator with existing native values.
Comment 11 Scott Kovatch CLA 2011-02-15 18:24:25 EST
Created attachment 189060 [details]
Implementation for non-cocoa platforms

Updated after comments from review. Added getAppMenu for all other platforms.
Comment 12 Thomas Schindl CLA 2011-02-16 06:11:12 EST
Brian - This be interesting for our e4.cocoa.renderer stuff
Comment 13 Brian de Alwis CLA 2011-02-17 14:38:15 EST
(In reply to comment #12)
> Brian - This be interesting for our e4.cocoa.renderer stuff

Definitely!  The Cocoa support is significantly trimmed down and now generalizes to other platforms.

Scott, do consumers need to do to embed the application name in the appropriate menu items?  E.g., "About Eclipse" or "Quit Eclipse"?  Or are these items populated by the Display.setAppName()?
Comment 14 Scott Kovatch CLA 2011-02-17 15:04:01 EST
(In reply to comment #13)
> Scott, do consumers need to do to embed the application name in the appropriate
> menu items?  E.g., "About Eclipse" or "Quit Eclipse"?  Or are these items
> populated by the Display.setAppName()?

As long as you call setAppName before you create the Display they will be populated for you automatically. The application menu is created during creation of the Display.
Comment 15 Silenio Quarti CLA 2011-03-03 10:57:39 EST
Created attachment 190280 [details]
implementation for all platforms

This is the final API. We decide to keep this new API consistent with other methods in display that return system-provide resources (getSystemFont(), getSystemColor(), etc).   The new API is Display.getSystemMenu(). We plan to add Shell.getSystemMenu(), but this might not happen for 3.7.

We are also renaming Display.getAppMenuBar() to Display.getMenuBar(). The original name for this was Display.getAppMenu(), but we would be adding a new concept to the toolkit API that is not necessary ("App"). See bug#338825.

I also changed the constants in SWT from MENU_ITEM_* to ID_*.  Shorter names and they IDs after all.
Comment 16 Silenio Quarti CLA 2011-03-03 11:13:29 EST
Created attachment 190283 [details]
testcase

updated testcase
Comment 17 Silenio Quarti CLA 2011-03-03 11:24:37 EST
Menu.findItem() is also not necessary. Application can easily get the appropriate item using Menu.getItem()/Menu.getItems() and MenuItem.getID().
Comment 18 Silenio Quarti CLA 2011-03-03 11:27:56 EST
Added bug#338831 to address the remaining API in Shell (Shell.getSystemMenu()).
Comment 19 Silenio Quarti CLA 2011-03-03 11:28:16 EST
Fixed > 20110303.
Comment 20 Silenio Quarti CLA 2011-03-03 11:28:59 EST
Thanks Scott.
Comment 21 Scott Kovatch CLA 2011-03-03 11:42:31 EST
(In reply to comment #15)
> Created attachment 190280 [details]
> implementation for all platforms
> 
> This is the final API. We decide to keep this new API consistent with other
> methods in display that return system-provide resources (getSystemFont(),
> getSystemColor(), etc).   The new API is Display.getSystemMenu(). We plan to
> add Shell.getSystemMenu(), but this might not happen for 3.7.

> We are also renaming Display.getAppMenuBar() to Display.getMenuBar(). The
> original name for this was Display.getAppMenu(), but we would be adding a new
> concept to the toolkit API that is not necessary ("App"). See bug#338825.

Fair enough. 'Display' === 'application', certainly on Cocoa and Carbon, so that makes sense.

I will update my EclipseCon talk, since I know it has the old names.

Thanks for getting this checked in! I know this was a pain point for many Mac developers.