How do I stop NSMenu eating click events in a fullscreen app?

I have an application that can switch between running in a normal windowed
mode and in fullscreen.  The fullscreen mode uses the recommended techniques
(capturing the display, running its own event loop, etc) and works just
fine, save for one problem: if the user clicks at the top-left of the
screen, the display stops updating, and does not respond until a second
click, at which point the application resumes as normal.

I have determined that the system menu bar is intercepting the click before
it even reaches my own run loop.  I used gdb to break into the app and get a
backtrace while the app was unresponsive.  It shows the app is blocked in
the following Carbon code on the main thread:

#0  0x9260e2fa in mach_msg_trap ()
#1  0x9260ea67 in mach_msg ()
#2  0x965dd00f in __CFRunLoopRun ()
#3  0x965dc0f4 in CFRunLoopRunSpecific ()
#4  0x965dbf21 in CFRunLoopRunInMode ()
#5  0x904820fc in RunCurrentEventLoopInMode ()
#6  0x90481eb1 in ReceiveNextEventCommon ()
#7  0x904be974 in IsUserStillTracking ()
#8  0x9049f776 in TrackMenuCommon ()
#9  0x904973ab in MenuSelectCore ()
#10 0x90496ba4 in _HandleMenuSelection2 ()
#11 0x904969c2 in _HandleMenuSelection ()
#12 0x968d4b3a in _NSHandleCarbonMenuEvent ()
#13 0x968a96e6 in _DPSNextEvent ()
#14 0x968a8976 in -[NSApplication
nextEventMatchingMask:untilDate:inMode:dequeue:] ()
#15 0x00006145 in -[AppDelegate runFullScreen] (self=0x303b40, _cmd=0x5264a)
at AppDelegate.mm:517

So it's entering a nested run loop to handle messages for the menu which
isn't even visible.  It's processing this event and passing it to the Carbon
menu code before I even get a chance to see it.

This exact behaviour occurs with Apple's own OpenGL Fullscreen sample code.

It seems like a bug that nextEvent: would eat these click events when the
app is explicitly in fullscreen mode.  Is this expected behaviour?  Is there
a different run loop mode I should be using for fullscreen?  (All the other
sample code I've looked at uses the normal mode.)

...

So, the obvious solution is to simply hide the menubar before entering
fullscreen, and re-enable it when leaving fullscreen mode.  However, this
doesn't quite work.

In the IBAction method to switch to fullscreen, if I call:

    [NSMenu setMenuVisible:NO];

then this change does not come into effect when going into the fullscreen
run loop, and the same problem occurs.

However, if I leave fullscreen mode and then re-enter fullscreen _without_
re-enabling the menu, the clicks in the top-left are NOT eaten by the menu
bar, and the app works perfectly.

Similarly, using SetSystemUI() behaves in just the same way.

So, how can I ensure the menu bar is actually hidden/disabled when entering
fullscreen mode?

Thanks in advance for any insights...

 :: Gavin
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to