@@ -52,6 +52,7 @@ public final class AppKitBackend: AppBackend {
5252 defer: true
5353 )
5454 window. delegate = window. resizeDelegate
55+
5556 return window
5657 }
5758
@@ -99,6 +100,71 @@ public final class AppKitBackend: AppBackend {
99100 window. makeKeyAndOrderFront ( nil )
100101 }
101102
103+ private static func renderSubmenu( _ submenu: ResolvedMenu . Submenu ) -> NSMenuItem {
104+ let renderedMenu = NSMenu ( )
105+ for item in submenu. content. items {
106+ switch item {
107+ case . button( let label, let action) :
108+ // Custom subclass is used to keep strong reference to action
109+ // wrapper.
110+ let renderedItem = NSCustomMenuItem (
111+ title: label,
112+ action: nil ,
113+ keyEquivalent: " "
114+ )
115+ if let action {
116+ let wrappedAction = Action ( action)
117+ renderedItem. actionWrapper = wrappedAction
118+ renderedItem. action = #selector( wrappedAction. run)
119+ renderedItem. target = wrappedAction
120+ }
121+ renderedMenu. addItem ( renderedItem)
122+ case . submenu( let submenu) :
123+ renderedMenu. addItem ( renderSubmenu ( submenu) )
124+ }
125+ }
126+
127+ let menuItem = NSMenuItem ( )
128+ menuItem. title = submenu. label
129+ menuItem. submenu = renderedMenu
130+ return menuItem
131+ }
132+
133+ /// The submenu pointed to by `helpMenu` still appears in `menuBar`. It's
134+ /// whichever submenu has the name 'Help'.
135+ private static func renderMenuBar(
136+ _ submenus: [ ResolvedMenu . Submenu ]
137+ ) -> ( menuBar: NSMenu , helpMenu: NSMenu ? ) {
138+ let menuBar = NSMenu ( )
139+
140+ // The first menu item is special and always takes on the name of the
141+ // app. For now just create a dummy item for it.
142+ let dummy = NSMenuItem ( )
143+ dummy. submenu = NSMenu ( )
144+ menuBar. addItem ( dummy)
145+
146+ var helpMenu : NSMenu ?
147+ for submenu in submenus {
148+ let renderedSubmenu = renderSubmenu ( submenu)
149+ menuBar. addItem ( renderedSubmenu)
150+
151+ if submenu. label == " Help " {
152+ helpMenu = renderedSubmenu. submenu
153+ }
154+ }
155+
156+ return ( menuBar, helpMenu)
157+ }
158+
159+ public func setApplicationMenu( _ submenus: [ ResolvedMenu . Submenu ] ) {
160+ let ( menuBar, helpMenu) = Self . renderMenuBar ( submenus)
161+ NSApplication . shared. mainMenu = menuBar
162+
163+ // We point the app's `helpMenu` at whichever submenu is named 'Help'
164+ // (if any) so that AppKit can install its help menu search function.
165+ NSApplication . shared. helpMenu = helpMenu
166+ }
167+
102168 public func runInMainThread( action: @escaping ( ) -> Void ) {
103169 DispatchQueue . main. async {
104170 action ( )
@@ -826,10 +892,8 @@ final class Action: NSObject {
826892 }
827893
828894 @objc func run( ) {
829- print ( " Running action " )
830895 action ( )
831896 }
832-
833897}
834898
835899class NSCustomTableView : NSTableView {
0 commit comments