1

I have a Qt-based GUI program that runs under MacOS/X, and I'd like to be able to change the label of that program's first menu-header, i.e. the label circled in red in this screenshot:

Example Apple program label with menu-label in question circled

Is there a programmatic way to do that? An objective-C/"native" solution would be sufficient, assuming no Qt-based solution exists.

Some background info (for those who rightly suspect an X/Y issue here): My MacOS/X software distribution includes several different Qt-based programs, and in order to avoid having to distribute multiple redundant copies of the shared libraries they all use, and avoid having to write a custom installer, all of the executables are placed into the Contents/MacOS subfolder of the same .app bundle, as shown in this screenshot:

MacOS .app folder software distribution layout

To run the software, the user clicks on the .app-folder's icon to launch the "main" application, and then there are various buttons/menus in that GUI that can launch the "other" applications as child processes as necessary; and that all works well, except that the child processes' first menu's label is always shown as the name of the "main" application (as listed in CFBundleExecutable tag in the bundle's Info.plist file) rather than the child-program's own name, and I'd like to be able to change that so it shows its own program-name instead.

Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234

1 Answers1

1

The following code (Swift, should be trivial to port to ObjC) changes the menu's name:

NSApp.mainMenu?.item(at: 0)?.submenu?.title = "child-program-name"

However, with this approach the menu is no longer displayed in bold once the name is changed since it doesn't match the app's name. In fact, even when changed back to the app's name the menu title is no longer bold. This seems to be a long-standing problem; see set titles of items in my app's main menu?. Unfortunately NSMenu doesn't have an attributedTitle property like NSMenuItem.

sbooth
  • 16,646
  • 2
  • 55
  • 81
  • Hmm, I can set the title-string in the NSMenu object (see code in my next comment) and it does change the string returned by `[appMenu title]` but it doesn't seem to affect the on-screen menu label. I wonder if Apple has hard-coded the menu name in recent versions of the OS to thwart shenanigans? – Jeremy Friesner Feb 25 '21 at 05:39
  • Here's the Objective-C++ code I used (sorry for the poor formatting): `#import #import void set_menu_program_name(const char * newName) { NSMenu *mainMenu = [[NSApplication sharedApplication] mainMenu]; NSMenu *appMenu = [[mainMenu itemAtIndex:0] submenu]; [appMenu setTitle:[[NSString alloc] initWithUTF8String:newName]]; }` – Jeremy Friesner Feb 25 '21 at 05:39
  • Interestingly the code you posted works for me (called from `-applicationDidFinishLaunching:` although I don't know if that matters) on macOS 11.2.1. I remember seeing some old threads where people said they needed to add a nonprinting character at the end of the title to get it to display, which doesn't make sense but could be worth a try. What macOS version are you running? – sbooth Feb 25 '21 at 14:39
  • Ah, yes, calling it from `-applicationDidFinishLaunching:` does work as expected (even without a non-printing character added), thanks! Of course, in a Qt app, `-applicationDidFinishLaunching:` isn't easily modifiable, but I can work on that as a separate problem. – Jeremy Friesner Feb 25 '21 at 15:59
  • Notes for posterity: I was able to get this to work in my Qt program by doing a `QTimer::singleShot(1, this, SLOT(MyHackSlotMethod()));` from my window-class's `showEvent()` method, and then calling the Objective-C++ function I posted in my comment above from `MyHackSlotMethod()`. Note that the `set_menu_program_name()` function works to change the menu-title to any string *except* the string that is the name of the executable file (i.e. any string except the one I wanted to use)... so I ended up working around that by adding a space to the end of the string, as @sbooth suggested. – Jeremy Friesner Feb 25 '21 at 22:14