Kevin,
thanks a lot for a quick answer!
What does this cooperation actually involve?
The applications communicate (through DO) and perform tasks as needed. Typically, the standard application (SA) sends requests to the login item (LI), which contains most of the GUI, whenever the user selects a menu item.
Is it just that they both run at the same time
When the problem with non-functional hidden menu happens, they do.
Sometimes only LI runs (when the user quits SA), but of course, there's no menu in this case and thus no problem either.
they're cooperatively interacting with the same underlying data
In fact the data is not shared; LI manages it, and if need be (e.g., to validate menu items), it sends the current state to SA through DO.
To be frank tho, I can't really see how this could be relevant to the problem that the menu of SA does not unhide properly when SA is the menu owner and the pointer goes up.
are they directly manipulating each other interfaces
Not sure what does this mean :( The apps communicate through DO, which affect both the GUIs:
- when the user selects a menu item in SA, it (usually, not always — e.g., About... is solved completely SA-side) sends an appropriate request to LI, which updates its GUI accordingly
- LI validates menu items for SA based on the current data and application state
None of this though actually happens in the simplest case when the problem happens. No menu (and essentially no SA/LI functionality) is really used. The typical scenario is
- LI runs and does nothing
- SA is launched, connects to LI and asks it to show the main window, which LI does (now, SA is menu owner, LI frontmost, all works well; when the pointer goes up, SA menu shows all right)
- SA is deactivated. Another application (e.g., System Settings, Console, Xcode, whatever) is frontmost/menu owner. When the pointer goes up, the menu of the other app shows
- LI is re-activated e.g., by clicking to its main window title bar. When it gets
didBecomeActive
, it checks whether SA happens to be the menu owner, and if not, it activates SA (to make it menu owner) - When SA gets
didBecomeActive
, it activates LI (to make it frontmost)
Now, SA is the menu owner and LI frontmost. Nevertheless, (pretty often) when the pointer goes up, nothing happens — the SA menu is not shown.
does your main app always operate as a standard application
Yes, SA is normal application and never changes its presentationOptions
(nor does other tricks like that).
Which process logged that state?
I wrote a very simple independent application which does nothing but
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSWorkspace *wsp=NSWorkspace.sharedWorkspace;
NSLog(@"menu owner: “%@” front: “%@”", wsp.menuBarOwningApplication.localizedName, wsp.frontmostApplication.localizedName);
[self performSelector:_cmd withObject:nil afterDelay:5];
}
I keep it running and observe its log.
Do you have logging from both process at the same time so that you can see what they both "thought"?
Yes, aside of the above, both LI and SA happen to log when they get didBecomeActive
, and those logs show that the steps 4 and 5 above do happen all right.