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 for menu items to allow Gecko to override their
41 // standard behavior in order to stop key equivalents from firing in certain
43 @interface GeckoNSMenuItem
: NSMenuItem
{
47 - (void)_doNothing
:(id
)aSender
;
50 // Objective-C class used to allow us to intervene with keyboard event handling,
51 // particularly to stop key equivalents from firing in certain instances. We
52 // allow mouse actions to work normally.
53 @interface GeckoNSMenu
: NSMenu
{
55 - (BOOL
)performSuperKeyEquivalent
:(NSEvent
*)aEvent
;
56 - (void)addItem
:(NSMenuItem
*)aNewItem
;
57 - (NSMenuItem
*)addItemWithTitle
:(NSString
*)aString
59 keyEquivalent
:(NSString
*)aKeyEquiv
;
60 - (void)insertItem
:(NSMenuItem
*)aNewItem atIndex
:(NSInteger
)aIndex
;
61 - (NSMenuItem
*)insertItemWithTitle
:(NSString
*)aString
63 keyEquivalent
:(NSString
*)aKeyEquiv
64 atIndex
:(NSInteger
)aIndex
;
65 - (void)_overrideClassOfMenuItem
:(NSMenuItem
*)aMenuItem
;
68 // Objective-C class used as action target for menu items.
69 @interface NativeMenuItemTarget
: NSObject
{
71 - (IBAction
)menuItemHit
:(id
)aSender
;
74 // Once instantiated, this object lives until its DOM node or its parent window
75 // is destroyed. Do not hold references to this, they can become invalid any
76 // time the DOM node can be destroyed.
77 class nsMenuBarX
: public nsMenuParentX
,
78 public nsChangeObserver
,
79 public mozilla::SupportsWeakPtr
{
81 explicit nsMenuBarX(mozilla::dom::Element
* aElement
);
83 NS_INLINE_DECL_REFCOUNTING(nsMenuBarX
)
85 static NativeMenuItemTarget
* sNativeEventTarget
;
86 static nsMenuBarX
* sLastGeckoMenuBarPainted
;
88 // The following content nodes have been removed from the menu system.
89 // We save them here for use in command handling.
90 RefPtr
<nsIContent
> mAboutItemContent
;
91 RefPtr
<nsIContent
> mPrefItemContent
;
92 RefPtr
<nsIContent
> mAccountItemContent
;
93 RefPtr
<nsIContent
> mQuitItemContent
;
96 NS_DECL_CHANGEOBSERVER
99 nsMenuBarX
* AsMenuBar() override
{ return this; }
102 uint32_t GetMenuCount();
103 bool MenuContainsAppMenu();
104 nsMenuX
* GetMenuAt(uint32_t aIndex
);
105 nsMenuX
* GetXULHelpMenu();
106 void SetSystemHelpMenu();
109 void ForceUpdateNativeMenuAt(const nsAString
& aIndexString
);
110 void ForceNativeMenuReload(); // used for testing
111 static void ResetNativeApplicationMenu();
112 void SetNeedsRebuild();
113 void ApplicationMenuOpened();
114 bool PerformKeyEquivalent(NSEvent
* aEvent
);
115 GeckoNSMenu
* NativeNSMenu() { return mNativeMenu
; }
118 void MenuChildChangedVisibility(const MenuChild
& aChild
,
119 bool aIsVisible
) override
;
122 virtual ~nsMenuBarX();
124 void ConstructNativeMenus();
125 void ConstructFallbackNativeMenus();
126 void InsertMenuAtIndex(RefPtr
<nsMenuX
>&& aMenu
, uint32_t aIndex
);
127 void RemoveMenuAtIndex(uint32_t aIndex
);
128 RefPtr
<mozilla::dom::Element
> HideItem(mozilla::dom::Document
* aDocument
,
129 const nsAString
& aID
);
130 void AquifyMenuBar();
131 NSMenuItem
* CreateNativeAppMenuItem(nsMenuX
* aMenu
, const nsAString
& aNodeID
,
132 SEL aAction
, int aTag
,
133 NativeMenuItemTarget
* aTarget
);
134 void CreateApplicationMenu(nsMenuX
* aMenu
);
136 // Calculates the index at which aChild's NSMenuItem should be inserted into
137 // our NSMenu. The order of NSMenuItems in the NSMenu is the same as the order
138 // of nsMenuX objects in mMenuArray; there are two differences:
139 // - mMenuArray contains both visible and invisible menus, and the NSMenu
140 // only contains visible
142 // - Our NSMenu may also contain an item for the app menu, whereas mMenuArray
144 // So the insertion index is equal to the number of visible previous siblings
145 // of aChild in mMenuArray, plus one if the app menu is present.
146 NSInteger
CalculateNativeInsertionPoint(nsMenuX
* aChild
);
148 RefPtr
<nsIContent
> mContent
;
149 RefPtr
<nsMenuGroupOwnerX
> mMenuGroupOwner
;
150 nsTArray
<RefPtr
<nsMenuX
>> mMenuArray
;
151 GeckoNSMenu
* mNativeMenu
; // root menu, representing entire menu bar
153 ApplicationMenuDelegate
* mApplicationMenuDelegate
;
156 #endif // nsMenuBarX_h_