Problems with tearing down an NSStatusItem menu
Problems with tearing down an NSStatusItem menu
- Subject: Problems with tearing down an NSStatusItem menu
- From: Nial Giacomelli <email@hidden>
- Date: Mon, 25 Jul 2011 23:10:48 +0100
I'm working on a GC application that makes use of an NSStatusItem to display
a menu to users. I create the NSStatusItem in my controllers awakeFromNib
method, like so:
self.statusItem = [[NSStatusBar systemStatusBar]
statusItemWithLength:NSVariableStatusItemLength];
[self.statusItem setImage:[NSImage imageNamed:@"StatusIconIdle.png"]];
[self.statusItem setAlternateImage:[NSImage imageNamed:@
"StatusIconSelected.png"]];
[self.statusItem setMenu:statusMenu];
[self.statusItem setHighlightMode:YES];
statusMenu is loaded via NIB and contains a mixture of static NSMenuItems
(setup via IB) and dynamically created NSMenuItem instances. Each dynamic
NSMenuItem is generated during a call to NSMenuDelegate's menuNeedsUpdate
function. These dynamic NSMenuItems are created with submenus which contain
further NSMenuItems with custom views. Here's an example of one such
NSMenuItem:
FileRecordPreviewMenuItemView *previewMenuItemView =
[[FileRecordPreviewMenuItemView alloc] initWithURL:url];
[previewMenuItem setView:previewMenuItemView];
[menu insertItem:previewMenuItem atIndex:[menu numberOfItems]];
Everything works as expected. All menus are rendered correctly, interaction
is absolutely perfect. The issue I'm experiencing is that upon Quitting the
application, I experience a crash and see the following error printed to
Console:
<Error>: kCGErrorIllegalArgument: CGSGetWindowPresenter
<Error>: kCGErrorFailure: Set a breakpoint @ CGErrorBreakpoint() to catch
errors as they are logged.
Setting the requested breakpoint and performing a stack trace returns the
following:
#0 0x00007fff90766dec in CGErrorBreakpoint ()
#1 0x00007fff90766a5a in CGSGlobalErrorv ()
#2 0x00007fff9080e969 in _GetWindowRightHolder ()
#3 0x00007fff8e417deb in _NXPresentsWindow ()
#4 0x00007fff8e417d83 in _NXOrderWindow ()
#5 0x00007fff8e5b936e in -[NSCarbonWindow
_reallyDoOrderWindow:relativeTo:findKey:forCounter:force:isModal:] ()
#6 0x00007fff8e38fc89 in -[NSWindow
_doOrderWindow:relativeTo:findKey:forCounter:force:isModal:] ()
#7 0x00007fff8e38f90f in -[NSWindow orderWindow:relativeTo:] ()
#8 0x00007fff8e50d677 in __-[NSWindow _close]_block_invoke_1 ()
#9 0x00007fff8e50d487 in -[NSWindow _close] ()
#10 0x00007fff8e927a36 in -[NSWindow _closeForTermination] ()
#11 0x00007fff91d219e1 in -[NSObject performSelector:] ()
#12 0x00007fff91d25e22 in -[NSArray makeObjectsPerformSelector:] ()
#13 0x00007fff8e54b92a in -[NSApplication _deallocHardCore:] ()
#14 0x00007fff8e29b72c in -[NSApplication terminate:] ()
#15 0x00007fff91d1a11d in -[NSObject performSelector:withObject:] ()
#16 0x00007fff8e399852 in -[NSApplication sendAction:to:from:] ()
#17 0x00007fff8e48634f in -[NSMenuItem _corePerformAction] ()
#18 0x00007fff8e486086 in -[NSCarbonMenuImpl
performActionWithHighlightingForItemAtIndex:] ()
#19 0x00007fff8e721e9c in -[NSMenu _internalPerformActionForItemAtIndex:] ()
#20 0x00007fff8e5b43f1 in -[NSCarbonMenuImpl
_carbonCommandProcessEvent:handlerCallRef:] ()
#21 0x00007fff8e4000bf in NSSLMMenuEventHandler ()
#22 0x00007fff89e078ec in DispatchEventToHandlers ()
#23 0x00007fff89e06ef8 in SendEventToEventTargetInternal ()
#24 0x00007fff89e1dd03 in SendEventToEventTarget ()
#25 0x00007fff89e64249 in SendHICommandEvent ()
#26 0x00007fff89f4b0f1 in SendMenuCommandWithContextAndModifiers ()
#27 0x00007fff89f915e1 in SendMenuItemSelectedEvent ()
#28 0x00007fff89e5d32d in FinishMenuSelection ()
#29 0x00007fff89f89fed in PopUpMenuSelectCore ()
#30 0x00007fff89f8a2ac in _HandlePopUpMenuSelection7 ()
#31 0x00007fff8e5b70bd in _NSSLMPopUpCarbonMenu3 ()
#32 0x00007fff8e95e02e in _NSPopUpCarbonMenu3 ()
#33 0x00007fff8e5b5222 in -[NSCarbonMenuImpl
popUpMenu:atLocation:width:forView:withSelectedItem:withFont:withFlags:withOptions:]
()
#34 0x00007fff8e8132f6 in +[NSStatusBarButtonCell
popupStatusBarMenu:inRect:ofView:withEvent:] ()
#35 0x00007fff8e8135a1 in -[NSStatusBarButtonCell
trackMouse:inRect:ofView:untilMouseUp:] ()
#36 0x00007fff8e397786 in -[NSControl mouseDown:] ()
#37 0x00007fff8e36266e in -[NSWindow sendEvent:] ()
#38 0x00007fff8e813fb4 in -[NSStatusBarWindow sendEvent:] ()
#39 0x00007fff8e2faf19 in -[NSApplication sendEvent:] ()
#40 0x00007fff8e29142b in -[NSApplication run] ()
#41 0x00007fff8e50f52a in NSApplicationMain ()
#42 0x0000000100001ca0 in start ()
Continuing after the breakpoint is triggered results in the following output
to Console:
<Error>: kCGErrorIllegalArgument: _CGSFindSharedWindow: WID 1758
<Error>: kCGErrorIllegalArgument: CGSOrderWindowListWithGroups: invalid
window ID (1758)
<Error>: kCGErrorIllegalArgument: CGSOrderWindowList: NULL list pointer or
empty list
I've been scratching my head for a good day or so trying to get to the
bottom of this. I noticed a correlation between experiencing the crash on
exit and accessing my NSMenu submenus. If the submenus are displayed, the
application will always crash on exit. If I edit my code so that my submenu
items aren't populated with custom views, the crash never occurs. This led
me to believe that my NSView subclasses were at fault. Unfortunately, this
doesn't seem to be the case. Even when setting a bog standard NSView
instance, I'll receive the crash.
// Crashes
FileRecordPreviewMenuItemView *previewMenuItemView =
[[FileRecordPreviewMenuItemView alloc] initWithURL:url];
[previewMenuItem setView:previewMenuItemView];
[menu insertItem:previewMenuItem atIndex:[menu numberOfItems]];
// If we don't set a custom view for our NSMenuItem, we don't experience a
crash
[menu insertItem:previewMenuItem atIndex:[menu numberOfItems]];
// Unfortunately, even if we set an empty, bog standard NSView, we will
still experience the crash.
NSView *view = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 150, 19)];
[previewMenuItem setView:view];
[menu insertItem:previewMenuItem atIndex:[menu numberOfItems]];
Any help would be greatly appreciated!
Thanks,
Nial
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden