Problems converting to MacMainMenuBar


#1

Im trying to convert my app (a music composition system called Grace) to use setMacMainMenu(), and am not having much luck. My app has two main types of windows: a singleton ConsoleWindow (built on juce::TextEditor) and any number of CodeEditorWindows (built on juce::CodeEditorCOmponent). In the current working app each window has its own command manager and menubar model. the menu items respond really well to the state of the window (eg region selection and keyboard commands) . Ive tried two different ways to convert this working version to one in which windows dont have menubars but use the MacMainMenu instead. My first attempt is to keep everything the same, except I replace my setMenuBar(this) in the window constructors with a dynamic “menu bar install” using activeWindowStatusChanged() , eg:

void ConsoleWindow::activeWindowStatusChanged()
{
if (isActiveWindow())
MenuBarModel::setMacMainMenu(this);
else
MenuBarModel::setMacMainMenu(0);
}

I do the same for the CodeEditorWindow. It actually appears to work, in the sense that when different windows are selected the menu bar changes and installs the differnt menus. However, the menus dont respond they way they do if the meny is in the window. For example if i lick on the Console window to make it active it does install its mens but if I then select a region in the console window (say) and then click on its Edit menu in the MacMainMenu, then the various copy/paste item in the Edit menu have not adjusted to the fact that there is a region selected in the console. However, if I revernt that menubar back to the constructor way and i dont use the MacMainMenu or activeWindowStatusChanged then the menbar works perfectly.

The first qustion I have is his, how would I “wake up:” the MacMainMenu after a region has been selected in the windows?

THe second question is larger: is this the right way to convert my app? Ive also tried using one app-wide applicationCommandManager and app-wide menubarmodel whose perform() and getCommandInfo() methods use getActiveWIndow() to make the items responsive to the currenly selected window. It also seems to work except that – just like the first method – the mac menubar does not notice when a region has been selected in the active window. There may be other things its not noticing, Im stuck on the edit item for now until I know how to fix it.

sorry for the length, and thanks for any help!
Rick Taube
Assoc. Prof. Composition/Theory
Chair, Composition/Theory Division
School of Music
University of Illinois at Urbana-Champaign
Net: taube@illinois.edu
Fax: 1 217 244 7767
Vox: 1 217 244 2684


#2

Just calling MenuBarModel::menuItemsChanged should do the trick.

I’ve never had a problem with this, but I’ve also never attempted to use multiple command-managers… That’s not really a situation I had in mind when I wrote it, I was expecting apps to just have a single command manager.


#3

Jules, thanks very much for the information, I’ve disappeared the last few days in order to switch my app to use just one global CommandManager and then call getActiveTopLevelWindow() inside getCommanInfo() and perform() to make command attributes responsive to whatever window is currently the active type (Grace has three type of application windows…). For the most part this works quit well and is certainly simpler to understand and maintain moving forward so I thank you for that. I have two remaining issues that I hope you can shed light on:

  1. If I use the setMacMainMenu and call a browseForFileToOpen() under any menu other than the “File” menu (say, my “Audio” menu) then when the choose file and command code is over and my mac menubar is restored, the menu’s label never reverts back to its normal non-selected color (e.g. the “Audio” menu’s label remains highlighted blue, appearing to still be active). Invoking menuItemsChanged() wont fix it. However, if I simply trigger the exact same FIleChooser and app code under a “File” menu command, then the File menu’s label reverts back just fine. Why is there a difference between my File menu and any other menu I have??

  2. In the case of using setMacMainMenuBar, my calling menuItemsChanged() works as you recommended but I really to have to call it after much every command in perform() . However, if I don’t use the MacMainMenuBar and instead put the exact same app-wide MenuBarModel in each window then all the menus do update automatically, and without any need for calling menuItemsChanged() at all. Is it correct to inder that if you use the Mac menubar then you are responsible for updating by hand after each command or the menu wont reflect the current state of the app, whereas if the same MenuBarModel is part of eag window you never have to do it by hand – it seems like its all or nothing?
    Thanks for any comments.
    Rick Taube
    Assoc. Prof. Composition/Theory
    Chair, Composition/Theory Division
    School of Music
    University of Illinois at Urbana-Champaign
    Net: taube@illinois.edu
    Fax: 1 217 244 7767
    Vox: 1 217 244 2684


#4

I really don’t know! But I do know that Apple hard-code some behaviours into the menus based on their names - it sounds to me like they’ve got some kind of special-case hack that’s catching you out here.

Maybe try avoiding it by triggering your file chooser asynchronously - i.e. instead of just showing it, use a CallbackMessage to show it next time around the event-loop, and then hopefully the OS won’t realise that it’s in response to a menu callback.

Well, the only way to ensure that the menu is correct is by calling that method - perhaps when you were using menubars inside the windows, they were just getting repainted as a result of something else, and that’s why they seemed to be updating?


#5

use a CallbackMessage to show it next time around the event-loop,

ah clever, I’m going to rewrite the app’s messaging anyway and I’ll try it then, thanks.
wish you a happy 4th from the colonies!

Rick Taube
Assoc. Prof. Composition/Theory
Chair, Composition/Theory Division
School of Music
University of Illinois at Urbana-Champaign
Net: taube@illinois.edu
Fax: 1 217 244 7767
Vox: 1 217 244 2684