Let the macOS manage your window menu

The Window Menu under macOS Big Sur provides the options to make a window fill half the screen or when multiple displays are connected, the option to move the window between the screens.

There is actually very little code involved in activating this feature and once configured, the macOS will even automatically add and remove windows to the menu as needed.

For this code to work, find your “Window” menu in the Xojo IDE. Make sure that it is named “WindowMenu”, then switch to the Open event of your application.

IF YOU HAVE THE OHANAWARE APP KIT

Append the following code to the open event of the App object, after you’ve called OAK.init.

#if targetMacOS then
  windowMenu.makeWindowMenu( true )
#endif

This function will also create the Minimize and Zoom / Center menuitems for you, which are then auto managed (by OAK) so you don’t need to add code to each window to respond to these items.

WITHOUT OHANAWARE’S APP KIT

If you don’t have the Ohanaware App Kit, you can still get the macOS to manage the Window menu for you. You’ll have to handle the Minimize and Zoom / Center menuitems yourself. Add the following block of code to the Open event of your application.

#if targetMacOS then
  // --- This code snippet was made from the Ohanaware App Kit 2021 - ohanaware.com
  // --- Basically, we grab the NSMenu instance of the windowMenu item, tell Apple's App Kit to use that for the Window menu.
  
  declare Function NSClassFromString               lib "Foundation"                          ( className as CFStringRef ) as integer
  declare Function NSMenuitem_Submenu              lib "AppKit" selector "submenu"           ( NSMenuitemInstance as integer ) as integer
  declare Sub      NSApplication_setWindowsMenu    lib "AppKit" selector "setWindowsMenu:"   ( NSApplicationInstance as integer, inNSMenuitem as integer )
  declare function NSApplication_sharedApplication lib "AppKit" selector "sharedApplication" ( NSApplicationClass as integer ) as integer
  
  Dim subMenuRef as integer = NSMenuitem_Submenu( windowMenu.handle( menuitem.handleType.CocoaNSMenuItem ) )
  NSApplication_setWindowsMenu( NSApplication_sharedApplication( NSClassFromString( "NSApplication" ) ), subMenuRef )
#endif

The Ohanaware App Kit 2021 includes more code like this, which will help you to build better Mac apps with Xojo. Get the new 2021 version as part of the Omegabundle 2021 http://www.omegabundle.net.

To see what’s new in the Ohanaware App Kitt (for 2021), check out https://ohanaware.com/appkit/ or What's Included

10 Likes

If you don’t have the excellent App Kit from Ohanaware, or are publishing to Windows rather than MAC, it is possible to achieve an acceptable version of this “Window Menu” (Required for acceptance to the Mac App Store) as follows:

Add the Menu Handlers:

Window2

If the window is called ‘AddDataWindow’, for example

MinimizeItem code is

AddDataWIndow.Minimize
Return True

M_Randall (The one with the :heavy_check_mark:︎ Randall)

AddDataWIndow.Restore
Return True

WindowTileLeft

// move window to left of screen

Var myBounds As New Rect
myBounds.Left = 0
myBounds.Top = AddDataWIndow.top
myBounds.Height = AddDataWIndow.Height + 20
myBounds.Width = AddDataWIndow.Width
AddDataWIndow.Bounds = myBounds
Return True

WindowTileRight
// move window to Right of screen

Var myBounds As New Rect
myBounds.Left = Screen.ScreenAt(0).AvailableWidth - AddDataWIndow.Width
myBounds.Top = AddDataWIndow.top
myBounds.Height = AddDataWIndow.Height + 20
myBounds.Width = AddDataWIndow.Width
AddDataWIndow.Bounds = myBounds
Return True

zoomItem

AddDataWindow.Maximize()
Return True

MinimizeItem

AddDataWIndow.Minimize
Return True

I Hope this is of some use. The code could probably be improved, but it worked for me when I needed to have may application approved for the Mac App Store.

4 Likes

Thank you Sam! This is awesome and lets me get rid of a bunch of code in my desktop template and apps for handling windows in the Windows menu.

1 Like

Unfortunately, this line breaks under API 2, with a ‘There is more than one method with this name but this does not match any of the available signatures.’ message

Dim subMenuRef as integer = NSMenuitem_Submenu( windowMenu.handle( menuitem.handleType.CocoaNSMenuItem ) )

Updated code for API2

#if targetMacOS then
  // --- This code snippet was made from the Ohanaware App Kit 2021 - ohanaware.com
  // --- Basically, we grab the NSMenu instance of the windowMenu item, tell Apple's App Kit to use that for the Window menu.
  
  declare Function NSClassFromString               lib "Foundation"                          ( className as CFStringRef ) as integer
  declare Function NSMenuitem_Submenu              lib "AppKit" selector "submenu"           ( NSMenuitemInstance as Ptr ) as integer
  declare Sub      NSApplication_setWindowsMenu    lib "AppKit" selector "setWindowsMenu:"   ( NSApplicationInstance as integer, inNSMenuitem as integer )
  declare function NSApplication_sharedApplication lib "AppKit" selector "sharedApplication" ( NSApplicationClass as integer ) as integer
  
  Dim subMenuRef as integer = NSMenuitem_Submenu( windowMenu.handle )
  NSApplication_setWindowsMenu( NSApplication_sharedApplication( NSClassFromString( "NSApplication" ) ), subMenuRef )
#endif