1
votes

Is there a way to close the NSComboBox popup programmatically?

There seem to be a bug with NSComboBox when the popup is open, and the control get's removed and then released. For some reason, the dealloc of the NSComboBox doesn't clear the popup before destructing.

Edit: Just to clarify - this bug only happens when the popup list is opened. Otherwise the control is released properly and cleanly.

Edit Edit: This is how to reproduce it.

  • Create a new Cocoa application.
  • Turn off automatic reference counting.
  • In @(applicationDidFinishLaunching) create a new NSComboBox and store it to a member.
  • Add the combo box to the window's contentView.
  • Create a new menu item with a keyboard shortcut and bind to a selector.
  • In the menu item's selector: remove the combo box from the view and release the member. Don't forget to set it back to nil.
  • Run the application.
  • Click on the combo box to show the popup up.
  • Use the shortcut to remove the combo box.
1
I would assume that calling abortEditing would close it. I'm not sure what you are saying about "not clearing the popup before destructing". the popup is part of the NSComboBox so surely that must be released. are you somehow retaining it?Brad Allred
Yes, you are right that the control should destroy the popup when released, but it isn't - which I think it's a bug. It's easy to replicate with a clean project.AndyTang
@(abortEditing) does work! However it leaves the popup hanging around as it hasn't closed it - but it doesn't crash anymore since it's not trying to access something that's already been removed due to @(abortEditing) cleaning some things up.AndyTang
so at first i thought this could be solved by using removeFromSuperviewWithoutNeedingDisplay and autorelease instead of release, but that didnt work... curiousBrad Allred
I suspect the popup has a unretained pointer back to the NSComboBox which isn't being cleaned up on dealloc. I guess Combo Box are not commonly used in OSX, in favour of the NSPopupButtons.AndyTang

1 Answers

-2
votes

You can perform a check in your code or grey out menu items by using the NSComboBox delegate methods -comboBoxWillPopUp: and -comboBoxWillDismiss: to control a BOOL.

The BOOL property can be used to control enabling of the menu item.

Set the delegate of the combo box.

To the interface of the delegate add

@property BOOL itemEnabled;

and to the implementation add

- (void)comboBoxWillPopUp:(NSNotification *)notification {
    self.itemEnabled = NO;
}
- (void)comboBoxWillDismiss:(NSNotification *)notification {
    self.itemEnabled = YES; //re-enabled when dismissed
}

Set initial value of itemEnabled to YES.

In the xib bind the Enabled attribute of the menu item to the delegate and the Model Key Path set to self.itemEnabled