3

I'm experience some event handling issues when attempting to use arrow keys without modifiers as key equivalents for menu items in the main menu bar. The problem I'm experiencing is that the main menu bar is handling the key down event as a key equivalent event before a tableView is able to. When the tableView is the first responder, the up/down arrow keys do not change the tableView's selection but rather trigger the key equivalent in the main menu bar.

The reason for this is that the incoming keyDown event for an arrow key is first passed to performKeyEquivalent on the target window, which in turns passes that event down the chain. NSTableView does not respond to this so the event bubbles back up to the application where it next dispatches it to the main menu, via performKeyEquivalent, and thus the event is consumed.

If the main menu does not have a key equivalent, then the event goes back to the window and down the chain via keyDown, which the tableView does respond to and correctly handles.

This is documented by Apple (more or less) in their Event Handling Guide.

Is there a proper way to handle key equivalents like arrow keys without modifiers such that they both appear in the menu item when it's being displayed, but are also properly consumed by any subviews that might handle them?

I've tried various tricks, but each one has numerous pros-and-cons:

NSMenu delegate

One can implement menuHasKeyEquivalent but it appears that you have to implement that for the entire main menu. While you could easily filter out the arrow keys, you also have to validate every other key equivalent, which isn't very practical.

Subclass NSApplication

You can override sendEvent: in NSApplication but the logic for keeping track of where you are in the event handling chain gets a bit hairy.

NSEvent tap

Similar to subclassing NSApplication. Things are a bit cleaner here because I can cheat and have the event tap a bit closer to the tableView, but you're still left with a lot of logic to determine when the tap should consume the event and "force-feed" it to the tableView versus when you should let the event be handled normally.

I'm curious if anyone has any suggestions on how best to implement an arrow key as a key equivalent when no modifiers are present and a tableView might be present.

(macOS 10.11+)

kennyc
  • 5,490
  • 5
  • 34
  • 57
  • I've experienced the same issue. You may want to take a look at https://stackoverflow.com/q/61839795/3272409 where there is more discussion about this problem. The solution I've gone for was to not use key equivalents but register the arrow keys in the `keyDown(with:)` method. This solved the issue for me. – Codey May 19 '20 at 07:32

0 Answers0