Bug 34572 Comment 22 Edit History

Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.

I have started looking into this a bit.

I think the outline of the work would be roughly the following:
 - Decide which of our non-native menus we want to be native. I'm aware of the following categories:
   - Context menus
   - <select> popups
   - Bookmarks folders in the bookmarks toolbar
   - (Other types of panels / popups, such as arrow panels or tooltips, are out of scope for this bug.)
 - Decide what to do about various cases where our fake menus have "extra powers" compared to native menus. More on this below.
 - Create an API in widget/cocoa that allows opening a menu at a given coordinate for a given menupopup DOM node. We already have similar APIs for [the main menu bar](https://searchfox.org/mozilla-central/rev/6bb59b783b193f06d6744c5ccaac69a992e9ee7b/widget/nsINativeMenuService.h#30-34), for [the application menu and Dock menu](https://searchfox.org/mozilla-central/rev/6bb59b783b193f06d6744c5ccaac69a992e9ee7b/widget/nsIStandaloneNativeMenu.idl#16-21), and for [menus for system status bar icons](https://searchfox.org/mozilla-central/rev/6bb59b783b193f06d6744c5ccaac69a992e9ee7b/widget/nsISystemStatusBar.idl#16-28).
 - Hook into the various DOM APIs and nsXULPopupManager APIs that open menus, and call the new API on macOS instead of opening a fake menu.
 - Implement various custom menu item NSView subclasses for various special things (see below).
 - Make sure the various events that our front-end code expects are fired appropriately, e.g. `popupshowing`, `popupshown`, `popuphiding`, `popuphidden`.
 - Make sure DOM modifications are handled appropriately.
 - Make sure any custom menu items are accessible.
 - Check for performance problems. Maybe avoid layout work for native menus by making the "fake" menupopup `display:none`.
 - Deal with fallout in our automated tests. Any test that wants to interact with a context menu programmatically probably needs to disabled on macOS.

## Notes on customizability

Native menus allow for a certain degree of customization by the app, via custom NSViews that are shown instead of menu items. So that means, for each horizontal row in a menu, we have the choice between two options:
 - A native menu item, which can have a label, an icon, a checkmark, a submenu, and a shortcut key annotation. These menu items are displayed with the native style for the OS. Their styling cannot be customized, but we also do not need to maintain them because they automatically adopt the updated look of any new macOS versions.
 - Or a custom view. These views occupy the full width of the menu, and a custom height. They can have arbitrary content and user input handling. Any text styling, hover effects, click handling, flashing effects etc needs to be implemented manually. If there are visual elements in custom views that are intended to match the OS native look, then the code for these visual elements needs to be updated whenever a new macOS version with an updated look is released.

## Notes on "extra powers"

I'm aware of three features our fake menus have, which I don't think we can replicate in native menus:
 - Handling of arbitrary modifier keys when clicking menu items: For example, if you click a bookmarks folder in the Bookmarks toolbar to display the folder contents in a menu, and then hold the Cmd key while clicking a bookmark item, the item will load in a new tab. If you try the same in a native menu, for example in the Bookmarks menu from the menubar, then the Cmd key is ignored and the clicked bookmark will open in the current tab.
 - "Menus on menus": For example, if you click a bookmarks folder in the Bookmarks toolbar, and then right-click a bookmark in the menu, you get a context menu that is displayed on top of the bookmarks folder popup. This is not possible with native menus - you cannot stack native menus, and you cannot right-click native menu items. (Or rather, right-clicking a native menu item will activate that item.)
 - Drag and drop of menu items: In bookmarks folder menus from the Bookmarks Toolbar, you can move and reorder bookmarks using drag and drop, even across different folders and submenus. This is not possible in native menus.

For these reasons, I think we should keep using custom menus for bookmarks folders in the Bookmarks Toolbar. We may want to update their styling to be explicitly different from native menus, so that users can have the right expectations for what they can do with them.
Also, for right-click context menus *inside* the custom bookmark folder menus, we can definitely use a native menu for the context menu.
As an alternative, we could decide to drop all this extra functionality on macOS. For example, Safari doesn't let you do any of the abovementioned things in their bookmarks toolbar.

## Notes on "special things"

Most of our context menus only use basic menu elements and should easily work as native menus. However, we would need custom NSView implementations for the following:

 - For context menus:
   - The main content area context menus has a row at the top that shows four big icons: back, forward, refresh, bookmark. If we want to keep this custom icon row, we cannot use native menu items for these buttons, but we can implement the icon row with a custom view. This will require manually handling hover effects (including OS-specific visual styling of those hover effects) and click handling, including the flashing animation when an icon is clicked. The rest of the menu can be standard menu items.
 - For <select> popups:
   - If we decide to use native menus for <select> popups, we will probably need custom views for `<optgroup>` headers, and for items with custom styling (fonts, font styles, text color, background color). It's worth looking at Chrome's code for this (I haven't done that yet).
 - For bookmark folders from the bookmarks toolbar:
    - If we really want to use native menus for them, and keep their current feature set, then we'd need to do a ton of custom work here. I recommend against it. Let's keep using fake menus for them for now.
I have started looking into this a bit.

I think the outline of the work would be roughly the following:
 - Decide which of our non-native menus we want to be native. I'm aware of the following categories:
   - Context menus
   - <select> popups
   - Bookmarks folders in the bookmarks toolbar
   - (Other types of panels / popups, such as arrow panels or tooltips, are out of scope for this bug.)
 - Decide what to do about various cases where our fake menus have "extra powers" compared to native menus. More on this below.
 - Create an API in widget/cocoa that allows opening a menu at a given coordinate for a given menupopup DOM node. We already have similar APIs for [the main menu bar](https://searchfox.org/mozilla-central/rev/6bb59b783b193f06d6744c5ccaac69a992e9ee7b/widget/nsINativeMenuService.h#30-34), for [the application menu and Dock menu](https://searchfox.org/mozilla-central/rev/6bb59b783b193f06d6744c5ccaac69a992e9ee7b/widget/nsIStandaloneNativeMenu.idl#16-21), and for [menus for system status bar icons](https://searchfox.org/mozilla-central/rev/6bb59b783b193f06d6744c5ccaac69a992e9ee7b/widget/nsISystemStatusBar.idl#16-28).
 - Hook into the various DOM APIs and nsXULPopupManager APIs that open menus, and call the new API on macOS instead of opening a fake menu.
 - Implement various custom menu item NSView subclasses for various special things (see below).
 - Make sure the various events that our front-end code expects are fired appropriately, e.g. `popupshowing`, `popupshown`, `popuphiding`, `popuphidden`.
 - Make sure DOM modifications are handled appropriately.
 - Make sure any custom menu items are accessible.
 - Check for performance problems. Maybe avoid layout work for native menus by making the "fake" menupopup `display:none`.
 - Deal with fallout in our automated tests. Any test that wants to interact with a context menu programmatically probably needs to disabled on macOS.

## Notes on customizability

Native menus allow for a certain degree of customization by the app, via custom NSViews that are shown instead of menu items. So that means, for each horizontal row in a menu, we have the choice between two options:
 - A native menu item, which can have a label, an icon, a checkmark, a submenu, and a shortcut key annotation. These menu items are displayed with the native style for the OS. Their styling cannot be customized, but we also do not need to maintain them because they automatically adopt the updated look of any new macOS versions.
 - Or a custom view. These views occupy the full width of the menu, and a custom height. They can have arbitrary content and user input handling. Any text styling, hover effects, click handling, flashing effects etc needs to be implemented manually. If there are visual elements in custom views that are intended to match the OS native look, then the code for these visual elements needs to be updated whenever a new macOS version with an updated look is released.

## Notes on "extra powers"

I'm aware of three features our fake menus have, which I don't think we can replicate in native menus:
 - Handling of arbitrary modifier keys when clicking menu items: For example, if you click a bookmarks folder in the Bookmarks toolbar to display the folder contents in a menu, and then hold the Cmd key while clicking a bookmark item, the item will load in a new tab. If you try the same in a native menu, for example in the Bookmarks menu from the menubar, then the Cmd key is ignored and the clicked bookmark will open in the current tab.
 - "Menus on menus": For example, if you click a bookmarks folder in the Bookmarks toolbar, and then right-click a bookmark in the menu, you get a context menu that is displayed on top of the bookmarks folder popup. This is not possible with native menus - you cannot stack native menus, and you cannot right-click native menu items. (Or rather, right-clicking a native menu item will activate that item.)
 - Drag and drop of menu items: In bookmarks folder menus from the Bookmarks Toolbar, you can move and reorder bookmarks using drag and drop, even across different folders and submenus. This is not possible in native menus.

For these reasons, I think we should keep using custom menus for bookmarks folders in the Bookmarks Toolbar. We may want to update their styling to be explicitly different from native menus, so that users can have the right expectations for what they can do with them.
Also, for right-click context menus *inside* the custom bookmark folder menus, we can definitely use a native menu for the context menu.
As an alternative, we could decide to drop all this extra functionality on macOS. For example, Safari doesn't let you do any of the abovementioned things in their bookmarks toolbar.

## Notes on "special things"

Most of our context menus only use basic menu elements and should easily work as native menus. However, we would need custom NSView implementations for the following:

 - For context menus:
   - The main content area context menu has a row at the top that shows four big icons: back, forward, refresh, bookmark. If we want to keep this custom icon row, we cannot use native menu items for these buttons, but we can implement the icon row with a custom view. This will require manually handling hover effects (including OS-specific visual styling of those hover effects) and click handling, including the flashing animation when an icon is clicked. The rest of the menu can be standard menu items.
 - For <select> popups:
   - If we decide to use native menus for <select> popups, we will probably need custom views for `<optgroup>` headers, and for items with custom styling (fonts, font styles, text color, background color). It's worth looking at Chrome's code for this (I haven't done that yet).
 - For bookmark folders from the bookmarks toolbar:
    - If we really want to use native menus for them, and keep their current feature set, then we'd need to do a ton of custom work here. I recommend against it. Let's keep using fake menus for them for now.
I have started looking into this a bit.

I think the outline of the work would be roughly the following:
 - Decide which of our non-native menus we want to be native. I'm aware of the following categories:
   - Context menus
   - <select> popups
   - Bookmarks folders in the bookmarks toolbar
   - (Other types of panels / popups, such as arrow panels or tooltips, are out of scope for this bug.)
 - Decide what to do about various cases where our fake menus have "extra powers" compared to native menus. More on this below.
 - Create an API in widget/cocoa that allows opening a menu at a given coordinate for a given menupopup DOM node. We already have similar APIs for [the main menu bar](https://searchfox.org/mozilla-central/rev/6bb59b783b193f06d6744c5ccaac69a992e9ee7b/widget/nsINativeMenuService.h#30-34), for [the application menu and Dock menu](https://searchfox.org/mozilla-central/rev/6bb59b783b193f06d6744c5ccaac69a992e9ee7b/widget/nsIStandaloneNativeMenu.idl#16-21), and for [menus for system status bar icons](https://searchfox.org/mozilla-central/rev/6bb59b783b193f06d6744c5ccaac69a992e9ee7b/widget/nsISystemStatusBar.idl#16-28).
 - Hook into the various DOM APIs and nsXULPopupManager APIs that open menus, and call the new API on macOS instead of opening a fake menu.
 - Implement various custom menu item NSView subclasses for various special things (see below).
 - Make sure the various events that our front-end code expects are fired appropriately, e.g. `popupshowing`, `popupshown`, `popuphiding`, `popuphidden`.
 - Make sure DOM modifications are handled appropriately.
 - Make sure any custom menu items are accessible.
 - Check for performance problems. Maybe avoid layout work for native menus by making the "fake" menupopup `display:none`.
 - Deal with fallout in our automated tests. Any test that wants to interact with a context menu programmatically probably needs to disabled on macOS.

## Notes on customizability

Native menus allow for a certain degree of customization by the app, via custom NSViews that are shown instead of menu items. So that means, for each horizontal row in a menu, we have the choice between two options:
 - A native menu item, which can have a label, an icon, a checkmark, a submenu, and a shortcut key annotation. These menu items are displayed with the native style for the OS. Their styling cannot be customized, but we also do not need to maintain them because they automatically adopt the updated look of any new macOS versions.
 - Or a custom view. These views occupy the full width of the menu, and a custom height. They can have arbitrary content and user input handling. Any text styling, hover effects, click handling, flashing effects etc needs to be implemented manually. If there are visual elements in custom views that are intended to match the OS native look, then the code for these visual elements needs to be updated whenever a new macOS version with an updated look is released.

## Notes on "extra powers"

I'm aware of three features our fake menus have, which I don't think we can replicate in native menus:
 - ~~Handling of arbitrary modifier keys when clicking menu items: For example, if you click a bookmarks folder in the Bookmarks toolbar to display the folder contents in a menu, and then hold the Cmd key while clicking a bookmark item, the item will load in a new tab. If you try the same in a native menu, for example in the Bookmarks menu from the menubar, then the Cmd key is ignored and the clicked bookmark will open in the current tab.~~ Edit: This appears to be wrong, see the comments below. It looks like we can handle arbitrary modifier keys. But Cmd may not be the best choice for opening something in a new tab.
 - "Menus on menus": For example, if you click a bookmarks folder in the Bookmarks toolbar, and then right-click a bookmark in the menu, you get a context menu that is displayed on top of the bookmarks folder popup. This is not possible with native menus - you cannot stack native menus, and you cannot right-click native menu items. (Or rather, right-clicking a native menu item will activate that item.)
 - Drag and drop of menu items: In bookmarks folder menus from the Bookmarks Toolbar, you can move and reorder bookmarks using drag and drop, even across different folders and submenus. This is not possible in native menus.

For these reasons, I think we should keep using custom menus for bookmarks folders in the Bookmarks Toolbar. We may want to update their styling to be explicitly different from native menus, so that users can have the right expectations for what they can do with them.
Also, for right-click context menus *inside* the custom bookmark folder menus, we can definitely use a native menu for the context menu.
As an alternative, we could decide to drop all this extra functionality on macOS. For example, Safari doesn't let you do any of the abovementioned things in their bookmarks toolbar.

## Notes on "special things"

Most of our context menus only use basic menu elements and should easily work as native menus. However, we would need custom NSView implementations for the following:

 - For context menus:
   - The main content area context menu has a row at the top that shows four big icons: back, forward, refresh, bookmark. If we want to keep this custom icon row, we cannot use native menu items for these buttons, but we can implement the icon row with a custom view. This will require manually handling hover effects (including OS-specific visual styling of those hover effects) and click handling, including the flashing animation when an icon is clicked. The rest of the menu can be standard menu items.
 - For <select> popups:
   - If we decide to use native menus for <select> popups, we will probably need custom views for `<optgroup>` headers, and for items with custom styling (fonts, font styles, text color, background color). It's worth looking at Chrome's code for this (I haven't done that yet).
 - For bookmark folders from the bookmarks toolbar:
    - If we really want to use native menus for them, and keep their current feature set, then we'd need to do a ton of custom work here. I recommend against it. Let's keep using fake menus for them for now.
I have started looking into this a bit.

I think the outline of the work would be roughly the following:
 - Decide which of our non-native menus we want to be native. I'm aware of the following categories:
   - Context menus
   - <select> popups
   - Bookmarks folders in the bookmarks toolbar
   - (Other types of panels / popups, such as arrow panels or tooltips, are out of scope for this bug.)
 - Decide what to do about various cases where our fake menus have "extra powers" compared to native menus. More on this below.
 - Create an API in widget/cocoa that allows opening a menu at a given coordinate for a given menupopup DOM node. We already have similar APIs for [the main menu bar](https://searchfox.org/mozilla-central/rev/6bb59b783b193f06d6744c5ccaac69a992e9ee7b/widget/nsINativeMenuService.h#30-34), for [the application menu and Dock menu](https://searchfox.org/mozilla-central/rev/6bb59b783b193f06d6744c5ccaac69a992e9ee7b/widget/nsIStandaloneNativeMenu.idl#16-21), and for [menus for system status bar icons](https://searchfox.org/mozilla-central/rev/6bb59b783b193f06d6744c5ccaac69a992e9ee7b/widget/nsISystemStatusBar.idl#16-28).
 - Hook into the various DOM APIs and nsXULPopupManager APIs that open menus, and call the new API on macOS instead of opening a fake menu.
 - Implement various custom menu item NSView subclasses for various special things (see below).
 - Make sure the various events that our front-end code expects are fired appropriately, e.g. `popupshowing`, `popupshown`, `popuphiding`, `popuphidden`.
 - Make sure DOM modifications are handled appropriately.
 - Make sure any custom menu items are accessible.
 - Check for performance problems. Maybe avoid layout work for native menus by making the "fake" menupopup `display:none`.
 - Deal with fallout in our automated tests. Any test that wants to interact with a context menu programmatically probably needs to disabled on macOS.

## Notes on customizability

Native menus allow for a certain degree of customization by the app, via custom NSViews that are shown instead of menu items. So that means, for each horizontal row in a menu, we have the choice between two options:
 - A native menu item, which can have a label, an icon, a checkmark, a submenu, and a shortcut key annotation. These menu items are displayed with the native style for the OS. Their styling cannot be customized, but we also do not need to maintain them because they automatically adopt the updated look of any new macOS versions. (Edit: As noted by Ken below, it is possible to set custom text styling by using an NSAttributedString as the label.)
 - Or a custom view. These views occupy the full width of the menu, and a custom height. They can have arbitrary content and user input handling. Any text styling, hover effects, click handling, flashing effects etc needs to be implemented manually. If there are visual elements in custom views that are intended to match the OS native look, then the code for these visual elements needs to be updated whenever a new macOS version with an updated look is released.

## Notes on "extra powers"

I'm aware of three features our fake menus have, which I don't think we can replicate in native menus:
 - ~~Handling of arbitrary modifier keys when clicking menu items: For example, if you click a bookmarks folder in the Bookmarks toolbar to display the folder contents in a menu, and then hold the Cmd key while clicking a bookmark item, the item will load in a new tab. If you try the same in a native menu, for example in the Bookmarks menu from the menubar, then the Cmd key is ignored and the clicked bookmark will open in the current tab.~~ Edit: This appears to be wrong, see the comments below. It looks like we can handle arbitrary modifier keys. But Cmd may not be the best choice for opening something in a new tab.
 - "Menus on menus": For example, if you click a bookmarks folder in the Bookmarks toolbar, and then right-click a bookmark in the menu, you get a context menu that is displayed on top of the bookmarks folder popup. This is not possible with native menus - you cannot stack native menus, and you cannot right-click native menu items. (Or rather, right-clicking a native menu item will activate that item.)
 - Drag and drop of menu items: In bookmarks folder menus from the Bookmarks Toolbar, you can move and reorder bookmarks using drag and drop, even across different folders and submenus. This is not possible in native menus.

For these reasons, I think we should keep using custom menus for bookmarks folders in the Bookmarks Toolbar. We may want to update their styling to be explicitly different from native menus, so that users can have the right expectations for what they can do with them.
Also, for right-click context menus *inside* the custom bookmark folder menus, we can definitely use a native menu for the context menu.
As an alternative, we could decide to drop all this extra functionality on macOS. For example, Safari doesn't let you do any of the abovementioned things in their bookmarks toolbar.

## Notes on "special things"

Most of our context menus only use basic menu elements and should easily work as native menus. However, we would need custom NSView implementations for the following:

 - For context menus:
   - The main content area context menu has a row at the top that shows four big icons: back, forward, refresh, bookmark. If we want to keep this custom icon row, we cannot use native menu items for these buttons, but we can implement the icon row with a custom view. This will require manually handling hover effects (including OS-specific visual styling of those hover effects) and click handling, including the flashing animation when an icon is clicked. The rest of the menu can be standard menu items.
 - For <select> popups:
   - If we decide to use native menus for <select> popups, we will probably need custom views for `<optgroup>` headers, and for items with custom styling (fonts, font styles, text color, background color). It's worth looking at Chrome's code for this (I haven't done that yet).
 - For bookmark folders from the bookmarks toolbar:
    - If we really want to use native menus for them, and keep their current feature set, then we'd need to do a ton of custom work here. I recommend against it. Let's keep using fake menus for them for now.
I have started looking into this a bit.

I think the outline of the work would be roughly the following:
 - Decide which of our non-native menus we want to be native. I'm aware of the following categories:
   - Context menus
   - <select> popups
   - Bookmarks folders in the bookmarks toolbar
   - (Other types of panels / popups, such as arrow panels or tooltips, are out of scope for this bug.)
 - Decide what to do about various cases where our fake menus have "extra powers" compared to native menus. More on this below.
 - Create an API in widget/cocoa that allows opening a menu at a given coordinate for a given menupopup DOM node. We already have similar APIs for [the main menu bar](https://searchfox.org/mozilla-central/rev/6bb59b783b193f06d6744c5ccaac69a992e9ee7b/widget/nsINativeMenuService.h#30-34), for [the application menu and Dock menu](https://searchfox.org/mozilla-central/rev/6bb59b783b193f06d6744c5ccaac69a992e9ee7b/widget/nsIStandaloneNativeMenu.idl#16-21), and for [menus for system status bar icons](https://searchfox.org/mozilla-central/rev/6bb59b783b193f06d6744c5ccaac69a992e9ee7b/widget/nsISystemStatusBar.idl#16-28).
 - Hook into the various DOM APIs and nsXULPopupManager APIs that open menus, and call the new API on macOS instead of opening a fake menu.
 - Implement various custom menu item NSView subclasses for various special things (see below).
 - Make sure the various events that our front-end code expects are fired appropriately, e.g. `popupshowing`, `popupshown`, `popuphiding`, `popuphidden`.
 - Make sure DOM modifications are handled appropriately.
 - Make sure any custom menu items are accessible.
 - Check for performance problems. Maybe avoid layout work for native menus by making the "fake" menupopup `display:none`.
 - Deal with fallout in our automated tests. Any test that wants to interact with a context menu programmatically probably needs to disabled on macOS.

## Notes on customizability

Native menus allow for a certain degree of customization by the app, via custom NSViews that are shown instead of menu items. So that means, for each horizontal row in a menu, we have the choice between two options:
 - A native menu item, which can have a label, an icon, a checkmark, a submenu, and a shortcut key annotation. These menu items are displayed with the native style for the OS. Their styling cannot be customized, but we also do not need to maintain them because they automatically adopt the updated look of any new macOS versions. (Edit: As noted by Ken below, it is possible to set custom text styling by using an NSAttributedString as the label.)
 - Or a custom view. These views occupy the full width of the menu, and a custom height. They can have arbitrary content and user input handling. Any text styling, hover effects, click handling, flashing effects etc needs to be implemented manually. If there are visual elements in custom views that are intended to match the OS native look, then the code for these visual elements needs to be updated whenever a new macOS version with an updated look is released.

## Notes on "extra powers"

I'm aware of three features our fake menus have, which I don't think we can replicate in native menus:
 - ~~Handling of arbitrary modifier keys when clicking menu items: For example, if you click a bookmarks folder in the Bookmarks toolbar to display the folder contents in a menu, and then hold the Cmd key while clicking a bookmark item, the item will load in a new tab. If you try the same in a native menu, for example in the Bookmarks menu from the menubar, then the Cmd key is ignored and the clicked bookmark will open in the current tab.~~ Edit: This appears to be wrong, see the comments below. It looks like we can handle arbitrary modifier keys.
 - "Menus on menus": For example, if you click a bookmarks folder in the Bookmarks toolbar, and then right-click a bookmark in the menu, you get a context menu that is displayed on top of the bookmarks folder popup. This is not possible with native menus - you cannot stack native menus, and you cannot right-click native menu items. (Or rather, right-clicking a native menu item will activate that item.)
 - Drag and drop of menu items: In bookmarks folder menus from the Bookmarks Toolbar, you can move and reorder bookmarks using drag and drop, even across different folders and submenus. This is not possible in native menus.

For these reasons, I think we should keep using custom menus for bookmarks folders in the Bookmarks Toolbar. We may want to update their styling to be explicitly different from native menus, so that users can have the right expectations for what they can do with them.
Also, for right-click context menus *inside* the custom bookmark folder menus, we can definitely use a native menu for the context menu.
As an alternative, we could decide to drop all this extra functionality on macOS. For example, Safari doesn't let you do any of the abovementioned things in their bookmarks toolbar.

## Notes on "special things"

Most of our context menus only use basic menu elements and should easily work as native menus. However, we would need custom NSView implementations for the following:

 - For context menus:
   - The main content area context menu has a row at the top that shows four big icons: back, forward, refresh, bookmark. If we want to keep this custom icon row, we cannot use native menu items for these buttons, but we can implement the icon row with a custom view. This will require manually handling hover effects (including OS-specific visual styling of those hover effects) and click handling, including the flashing animation when an icon is clicked. The rest of the menu can be standard menu items.
 - For <select> popups:
   - If we decide to use native menus for <select> popups, we will probably need custom views for `<optgroup>` headers, and for items with custom styling (fonts, font styles, text color, background color). It's worth looking at Chrome's code for this (I haven't done that yet).
 - For bookmark folders from the bookmarks toolbar:
    - If we really want to use native menus for them, and keep their current feature set, then we'd need to do a ton of custom work here. I recommend against it. Let's keep using fake menus for them for now.
I have started looking into this a bit.

I think the outline of the work would be roughly the following:
 - Decide which of our non-native menus we want to be native. I'm aware of the following categories:
   - Context menus
   - <select> popups
   - Bookmarks folders in the bookmarks toolbar
   - (Other types of panels / popups, such as arrow panels or tooltips, are out of scope for this bug.)
 - Decide what to do about various cases where our fake menus have "extra powers" compared to native menus. More on this below.
 - Create an API in widget/cocoa that allows opening a menu at a given coordinate for a given menupopup DOM node. We already have similar APIs for [the main menu bar](https://searchfox.org/mozilla-central/rev/6bb59b783b193f06d6744c5ccaac69a992e9ee7b/widget/nsINativeMenuService.h#30-34), for [the application menu and Dock menu](https://searchfox.org/mozilla-central/rev/6bb59b783b193f06d6744c5ccaac69a992e9ee7b/widget/nsIStandaloneNativeMenu.idl#16-21), and for [menus for system status bar icons](https://searchfox.org/mozilla-central/rev/6bb59b783b193f06d6744c5ccaac69a992e9ee7b/widget/nsISystemStatusBar.idl#16-28).
 - Hook into the various DOM APIs and nsXULPopupManager APIs that open menus, and call the new API on macOS instead of opening a fake menu.
 - Implement various custom menu item NSView subclasses for various special things (see below).
 - Make sure the various events that our front-end code expects are fired appropriately, e.g. `popupshowing`, `popupshown`, `popuphiding`, `popuphidden`.
 - Make sure DOM modifications are handled appropriately.
 - Make sure any custom menu items are accessible.
 - Check for performance problems. Maybe avoid layout work for native menus by making the "fake" menupopup `display:none`.
 - Deal with fallout in our automated tests. Any test that wants to interact with a context menu programmatically probably needs to disabled on macOS.

## Notes on customizability

Native menus allow for a certain degree of customization by the app, via custom NSViews that are shown instead of menu items. So that means, for each horizontal row in a menu, we have the choice between two options:
 - A native menu item, which can have a label, an icon, a checkmark, a submenu, and a shortcut key annotation. These menu items are displayed with the native style for the OS. Their styling cannot be customized, but we also do not need to maintain them because they automatically adopt the updated look of any new macOS versions. (Edit: As noted by Ken below, it is possible to set custom text styling by using an NSAttributedString as the label.)
 - Or a custom view. These views occupy the full width of the menu, and a custom height. They can have arbitrary content and user input handling. Any text styling, hover effects, click handling, flashing effects etc needs to be implemented manually. If there are visual elements in custom views that are intended to match the OS native look, then the code for these visual elements needs to be updated whenever a new macOS version with an updated look is released.

## Notes on "extra powers"

I'm aware of three features our fake menus have, which I don't think we can replicate in native menus:
 - ~~Handling of arbitrary modifier keys when clicking menu items: For example, if you click a bookmarks folder in the Bookmarks toolbar to display the folder contents in a menu, and then hold the Cmd key while clicking a bookmark item, the item will load in a new tab. If you try the same in a native menu, for example in the Bookmarks menu from the menubar, then the Cmd key is ignored and the clicked bookmark will open in the current tab.~~ Edit: This appears to be wrong, see the comments below. It looks like we can handle arbitrary modifier keys on native menu items.
 - "Menus on menus": For example, if you click a bookmarks folder in the Bookmarks toolbar, and then right-click a bookmark in the menu, you get a context menu that is displayed on top of the bookmarks folder popup. This is not possible with native menus - you cannot stack native menus, and you cannot right-click native menu items. (Or rather, right-clicking a native menu item will activate that item.)
 - Drag and drop of menu items: In bookmarks folder menus from the Bookmarks Toolbar, you can move and reorder bookmarks using drag and drop, even across different folders and submenus. This is not possible in native menus.

For these reasons, I think we should keep using custom menus for bookmarks folders in the Bookmarks Toolbar. We may want to update their styling to be explicitly different from native menus, so that users can have the right expectations for what they can do with them.
Also, for right-click context menus *inside* the custom bookmark folder menus, we can definitely use a native menu for the context menu.
As an alternative, we could decide to drop all this extra functionality on macOS. For example, Safari doesn't let you do any of the abovementioned things in their bookmarks toolbar.

## Notes on "special things"

Most of our context menus only use basic menu elements and should easily work as native menus. However, we would need custom NSView implementations for the following:

 - For context menus:
   - The main content area context menu has a row at the top that shows four big icons: back, forward, refresh, bookmark. If we want to keep this custom icon row, we cannot use native menu items for these buttons, but we can implement the icon row with a custom view. This will require manually handling hover effects (including OS-specific visual styling of those hover effects) and click handling, including the flashing animation when an icon is clicked. The rest of the menu can be standard menu items.
 - For <select> popups:
   - If we decide to use native menus for <select> popups, we will probably need custom views for `<optgroup>` headers, and for items with custom styling (fonts, font styles, text color, background color). It's worth looking at Chrome's code for this (I haven't done that yet).
 - For bookmark folders from the bookmarks toolbar:
    - If we really want to use native menus for them, and keep their current feature set, then we'd need to do a ton of custom work here. I recommend against it. Let's keep using fake menus for them for now.

Back to Bug 34572 Comment 22