Search code examples
macoscocoanspopover

Is there a way to programmatically close all open NSPopovers on key event, instead of mouse event?


My Cocoa application can have several popovers that open.
If you click anywhere else, the currently opened popover will close (normal behavior)

However, we also have a hotkey that changes the state of the application, and we would like the popovers to close, similar to how a mouse event would close it.

Some of the popovers have textfields for user input, and I don't want to just override my popover class to listen for this specific hotkey to close, but that's the only idea I have right now


Solution

  • Came up with an interesting solution that actually is pretty safe, as far as the application state goes.

    I traverse the responder chain, looking for NSPopover, and if I find one, I pass the -cancelOperation message (which is sent on ESC key pressed)

    This safely closes my popovers

     +   NSWindowController* windowController = [MyMainWindowController sharedWindowController];
     +   NSResponder *responder = [[windowController window] firstResponder];
     +   while ((responder = [responder nextResponder]))
     +   {
     +      if( [responder isKindOfClass:[NSPopover class]] )
     +      {
     +         [[windowController window] cancelOperation:nil];
     +         break;
     +      }
     +   }