NSView 无法抓取 Ctrl+Tab Keydown 事件

NSView cannot grab Ctrl+Tab Keydown event

在我的 Mac 应用程序中,我监听按键事件并将它们传递给内部客户端,具体取决于修饰符和键码。

目前,我面临的问题是无法获取 "Ctrl+Tab" 事件。似乎 "App" 本身试图处理这个问题,这对于基于选项卡的应用程序很有意义。所以我禁用了 Tabbing 模式,但 Ctrl+Tab 仍然不会触发 KeyDown 事件。关键代码和修饰符的任何其他组合似乎都可以通过。

关于如何为 Ctrl+Tab 触发按下事件的任何建议?

在我的测试中,NSView-keyDown: 方法似乎没有在 NSView 子类上调用控制选项卡键事件。但是,您可以使用 NSApplication 子类在应用程序级别拦截它们:

@interface MyApplication: NSApplication
@end

@implementation MyApplication

- (void)sendEvent:(NSEvent *)event {
    if (event.type == NSEventTypeKeyDown &&
        [event.charactersIgnoringModifiers isEqualToString:@"\t"] &&
        (event.modifierFlags & NSEventModifierFlagDeviceIndependentFlagsMask) == NSEventModifierFlagControl) {
        NSLog(@"ctrl-tab");
    }

    [super sendEvent:event];
}

@end

使用

override func viewDidLoad() {
    super.viewDidLoad()

    NSEvent.addLocalMonitorForEvents(matching: .keyDown) {
        if self.myKeyDown(with: [=10=]) {
            return nil
        } else {
            return [=10=]
        }
    }
}

func myKeyDown(with event: NSEvent) -> Bool {
    // handle keyDown only if current window has focus, i.e. is keyWindow
    guard let locWindow = self.view.window,
          NSApplication.shared.keyWindow === locWindow else {
        return false
    }

    switch event.specialKey {

    case NSEvent.SpecialKey.tab:
        // your event for tab action
        return true
    default:
        break
    }
    return false
}

如果需要快捷键

func myKeyDown(with event: NSEvent) -> Bool {
    // handle keyDown only if current window has focus, i.e. is keyWindow
    guard let locWindow = self.view.window,
          NSApplication.shared.keyWindow === locWindow else {
        return false
    }

    switch event.specialKey {
    case NSEvent.SpecialKey.tab:
        // your code for tab action
        return true
    default:
        break
    }

    switch event.modifierFlags.intersection(.deviceIndependentFlagsMask) {
    case [.command]:
        switch event.charactersIgnoringModifiers! {
        case "w":
            // your code for cmd+w action (example)
            break
        default:
            break
        }
    }
    return false
}