I'm investigating an issue on Mac OS X 10.8, and I am at the end of my wits. I'm not sure what to do next.
The application is 32 bit and has some Carbon calls in it.
Here is the problem: when I right-click the application icon in the dock, select the menu item "Hide", then, after the application has hidden, I select the "Show" menu item from the dock, and the problem occurs: the main document window does not appear (the palettes and menu do appear).
At this point, the "Show" menu item does not change to "Hide" even though the palettes have become visible.
I expect that the main document window becomes visible when I select "Show" from the application dock menu. Just like other Mac applications.
When it fails, I can make the main document window visible again if I use the App Exposé gesture on the Trackpad to show the document windows and select the main document window.
It works fine if I launch the application from the Terminal or from Xcode. The document window shows and the dock menu item for my application changes to "Hide" as expected. I launch the app from the terminal by navigating to the parent directory of the *.app, and typing ./MyApp.app/Contents/MacOS/MyApp
.
It fails when I have launched by double-clicking the application icon in the Finder.
My log messages from the application delegate's unhide functions appear when the application is launched from the Terminal and Xcode, but not when launched from the Finder.
– applicationWillUnhide:
– applicationDidUnhide:
I have looked in the Console.app for any exceptions thrown (or any other messages). There are none.
Update:
To try and debug this, I launched from the Finder, and used Xcode to attach to the process.
I had suspected that an exception was being thrown and when I tested it using Xcode's "Exception Breakpoint" as well as putting a breakpoint on objc_exception_throw (just in case), it dd not break when I hide or "show" the application.
I then thought that I needed to prove that the NSApplicationWillUnhideNotification
and NSApplicationDidUnhideNotification
were being sent out. They are when I launch from Xcode or from the Terminal, but if I launch from the Finder, they are not.
I verified this by, after attaching Xcode to the application, putting a breakpoint via "Add Symbolic Breakpoint" for:
-[NSNotificationCenter postNotificationName:object:userInfo]
And then, I added a Debugger Command: "po * (id*) ($esp+12)" to print out the first parameter to that selector (the notification name).
Which I found in an answer posted here, in StackOverflow.
Using that, I can see the notifications that are posted after I choose the "Show" menu item. When I launch from Xcode/Terminal, I see the following notifications posted:
NSApplicationWillUpdateNotification, NSWindowDidUpdateNotification, NSApplicationDidUpdateNotification, ** NSApplicationWillUnhideNotification **, ..., ** NSApplicationDidUnhideNotification **, ..., NSApplicationWillBecomeActiveNotification, ...
NSApplicationWillUnhideNotification
is posted in this situation.
When I launch from the Finder, I see the following notifications are posted:
NSApplicationWillUpdateNotification, NSWindowDidUpdateNotification, NSApplicationDidUpdateNotification, NSApplicationWillBecomeActiveNotification, ...
It does not send the NSApplicationWillUnhideNotification
. Also, when I select "Show" from the Xcode-launched version, I see -[NSApplication _doUnhideWithoutActivation]
in the backtrace. Putting a breakpoint for that function when I attach to the Finder-launched version does not result in a break when I select "Show".
Then, I thought to myself, perhaps the application thinks that it is not hidden.
I have a idle event handler, so from there I printed out the value of [[NSApplication sharedApplicaton] isHidden]
while I Hide and "Show" the application.
For the problem situation, when the application is not hidden, it prints out NO
for isHidden
. When the application becomes hidden, it prints out YES
for isHidden
. When I select "Show" from the dock menu, it continues to print out NO
for isHidden
. It knows that it is hidden, but part of the application has been activated: the NSPanels
and the NSMenuBar
appear.
I can see the document window by entering into the application Exposé mode, and clicking the document window will make the window appear, but the dock menu item is still "Show" and isHidden
is still YES
.
The unhide mechanism works fine for a sample application, so I'm pretty sure that our code is doing something to shut this off.
I wonder what would be different between an application launched from the Terminal compared to an application launched from the Finder?
I had the application log the environment variables using [[NSProcessInfo processInfo] environment]
and the only real difference I could see is that PWD exists in the variables for the Terminal application: I cannot see anything in our code that makes use of that.
I had the application log the command-line arguments via [[NSProcessInfo processInfo] arguments]
, and I do see something different in the Finder-launched version. Both the Terminal and Finder launched versions list the path of the binary as the first argument; the Finder also lists a second paramter, "-psn_0_89445704". I have read online that it is something that Mac OS X adds to command-line arguments for GUI applications and I see it added to the command-line arguments for other applications that Hide and Show properly from the Dock menu.
Do you have any other thoughts that may lead me further towards solving this mystery? Thanks for any help or suggestions!