1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
9 #import <Cocoa/Cocoa.h>
11 #include "mozilla/UniquePtr.h"
12 #include "mozilla/WeakPtr.h"
14 #include "nsISupports.h"
15 #include "nsMenuParentX.h"
16 #include "nsChangeObserver.h"
21 class nsMenuGroupOwnerX
;
31 } // namespace mozilla
33 // ApplicationMenuDelegate is used to receive Cocoa notifications.
34 @interface ApplicationMenuDelegate
: NSObject
<NSMenuDelegate
> {
35 nsMenuBarX
* mApplicationMenu
; // weak ref
37 - (id
)initWithApplicationMenu
:(nsMenuBarX
*)aApplicationMenu
;
40 // Objective-C class used to allow us to intervene with keyboard event handling.
41 // We allow mouse actions to work normally.
42 @interface GeckoNSMenu
: NSMenu
{
44 - (BOOL
)performSuperKeyEquivalent
:(NSEvent
*)aEvent
;
47 // Objective-C class used as action target for menu items
48 @interface NativeMenuItemTarget
: NSObject
{
50 - (IBAction
)menuItemHit
:(id
)aSender
;
53 // Objective-C class used for menu items on the Services menu to allow Gecko
54 // to override their standard behavior in order to stop key equivalents from
55 // firing in certain instances.
56 @interface GeckoServicesNSMenuItem
: NSMenuItem
{
60 - (void)_doNothing
:(id
)aSender
;
63 // Objective-C class used as the Services menu so that Gecko can override the
64 // standard behavior of the Services menu in order to stop key equivalents
65 // from firing in certain instances.
66 @interface GeckoServicesNSMenu
: NSMenu
{
68 - (void)addItem
:(NSMenuItem
*)aNewItem
;
69 - (NSMenuItem
*)addItemWithTitle
:(NSString
*)aString
71 keyEquivalent
:(NSString
*)aKeyEquiv
;
72 - (void)insertItem
:(NSMenuItem
*)aNewItem atIndex
:(NSInteger
)aIndex
;
73 - (NSMenuItem
*)insertItemWithTitle
:(NSString
*)aString
75 keyEquivalent
:(NSString
*)aKeyEquiv
76 atIndex
:(NSInteger
)aIndex
;
77 - (void)_overrideClassOfMenuItem
:(NSMenuItem
*)aMenuItem
;
80 // Once instantiated, this object lives until its DOM node or its parent window is destroyed.
81 // Do not hold references to this, they can become invalid any time the DOM node can be destroyed.
82 class nsMenuBarX
: public nsMenuParentX
, public nsChangeObserver
, public mozilla::SupportsWeakPtr
{
84 explicit nsMenuBarX(mozilla::dom::Element
* aElement
);
86 NS_INLINE_DECL_REFCOUNTING(nsMenuBarX
)
88 static NativeMenuItemTarget
* sNativeEventTarget
;
89 static nsMenuBarX
* sLastGeckoMenuBarPainted
;
91 // The following content nodes have been removed from the menu system.
92 // We save them here for use in command handling.
93 RefPtr
<nsIContent
> mAboutItemContent
;
94 RefPtr
<nsIContent
> mPrefItemContent
;
95 RefPtr
<nsIContent
> mAccountItemContent
;
96 RefPtr
<nsIContent
> mQuitItemContent
;
99 NS_DECL_CHANGEOBSERVER
102 nsMenuBarX
* AsMenuBar() override
{ return this; }
105 uint32_t GetMenuCount();
106 bool MenuContainsAppMenu();
107 nsMenuX
* GetMenuAt(uint32_t aIndex
);
108 nsMenuX
* GetXULHelpMenu();
109 void SetSystemHelpMenu();
111 void ForceUpdateNativeMenuAt(const nsAString
& aIndexString
);
112 void ForceNativeMenuReload(); // used for testing
113 static void ResetNativeApplicationMenu();
114 void SetNeedsRebuild();
115 void ApplicationMenuOpened();
116 bool PerformKeyEquivalent(NSEvent
* aEvent
);
117 GeckoNSMenu
* NativeNSMenu() { return mNativeMenu
; }
120 void MenuChildChangedVisibility(const MenuChild
& aChild
, bool aIsVisible
) override
;
123 virtual ~nsMenuBarX();
125 void ConstructNativeMenus();
126 void ConstructFallbackNativeMenus();
127 void InsertMenuAtIndex(RefPtr
<nsMenuX
>&& aMenu
, uint32_t aIndex
);
128 void RemoveMenuAtIndex(uint32_t aIndex
);
129 RefPtr
<mozilla::dom::Element
> HideItem(mozilla::dom::Document
* aDocument
, const nsAString
& aID
);
130 void AquifyMenuBar();
131 NSMenuItem
* CreateNativeAppMenuItem(nsMenuX
* aMenu
, const nsAString
& aNodeID
, SEL aAction
,
132 int aTag
, NativeMenuItemTarget
* aTarget
);
133 void CreateApplicationMenu(nsMenuX
* aMenu
);
135 // Calculates the index at which aChild's NSMenuItem should be inserted into our NSMenu.
136 // The order of NSMenuItems in the NSMenu is the same as the order of nsMenuX objects in
137 // mMenuArray; there are two differences:
138 // - mMenuArray contains both visible and invisible menus, and the NSMenu only contains visible
140 // - Our NSMenu may also contain an item for the app menu, whereas mMenuArray never does.
141 // So the insertion index is equal to the number of visible previous siblings of aChild in
142 // mMenuArray, plus one if the app menu is present.
143 NSInteger
CalculateNativeInsertionPoint(nsMenuX
* aChild
);
145 RefPtr
<nsIContent
> mContent
;
146 RefPtr
<nsMenuGroupOwnerX
> mMenuGroupOwner
;
147 nsTArray
<RefPtr
<nsMenuX
>> mMenuArray
;
148 GeckoNSMenu
* mNativeMenu
; // root menu, representing entire menu bar
150 ApplicationMenuDelegate
* mApplicationMenuDelegate
;
153 #endif // nsMenuBarX_h_