You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中如何在App获焦点时跨所有窗口监听NSEvent

在macOS App获焦时全局监听按键(多窗口场景)

核心方案

直接利用NSApplication的本地事件监听机制,在App层面拦截所有按键事件——当App处于活跃状态(获焦)时,所有按键事件会先经过这个监听,无需为每个窗口/视图单独配置,完美覆盖多窗口场景。

实现步骤

  1. 在AppDelegate中注册本地事件监听器,指定监听keyDown(或keyUp)事件;
  2. 实现事件处理逻辑,按需处理普通按键或组合键;
  3. 控制事件是否继续传递给窗口/视图(返回原事件则传递,返回nil则截断)。

Swift 代码示例

import Cocoa

@main
class AppDelegate: NSObject, NSApplicationDelegate {

    func applicationDidFinishLaunching(_ aNotification: Notification) {
        // 注册本地按键事件监听,仅在App活跃时触发
        NSEvent.addLocalMonitorForEvents(matching: .keyDown) { event in
            self.handleKeyDown(event)
            // 返回event让后续窗口/视图处理,返回nil则截断事件
            return event
        }
    }
    
    private func handleKeyDown(_ event: NSEvent) {
        // 获取按键字符(忽略修饰键)和修饰键组合
        let keyChar = event.charactersIgnoringModifiers ?? ""
        let modifiers = event.modifierFlags.intersection(.deviceIndependentFlagsMask)
        
        print("按键: \(keyChar) | 修饰键: \(modifiers)")
        
        // 示例:处理Command+C组合键
        if modifiers.contains(.command) && keyChar == "c" {
            print("捕获到Command+C")
            // 若要阻止系统默认复制行为,可将上方return event改为return nil
        }
        
        // 示例:处理方向键(通过keyCode判断)
        switch event.keyCode {
        case 123: print("左方向键")
        case 124: print("右方向键")
        default: break
        }
    }
}

Objective-C 代码示例

#import "AppDelegate.h"

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // 注册本地按键事件监听
    [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskKeyDown handler:^NSEvent * _Nullable(NSEvent * _Nonnull event) {
        [self handleKeyDown:event];
        return event; // 返回事件让后续处理,nil则截断
    }];
}

- (void)handleKeyDown:(NSEvent *)event {
    NSString *keyChar = [event charactersIgnoringModifiers];
    NSEventModifierFlags modifiers = [event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
    
    NSLog(@"按键: %@ | 修饰键: %lu", keyChar, (unsigned long)modifiers);
    
    // 处理Command+C组合键
    if ((modifiers & NSEventModifierFlagCommand) && [keyChar isEqualToString:@"c"]) {
        NSLog(@"捕获到Command+C");
    }
    
    // 处理方向键
    switch (event.keyCode) {
        case 123: NSLog(@"左方向键"); break;
        case 124: NSLog(@"右方向键"); break;
        default: break;
    }
}

@end

关键说明

  • 无需系统权限:addLocalMonitorForEvents是App内部监听,仅对当前App生效,不需要 accessibility 权限(区别于全局系统监听);
  • 事件传递控制:返回原事件可让窗口/视图继续处理默认逻辑,返回nil则完全拦截事件;
  • 支持多事件类型:可修改matching参数监听.keyUp等其他事件类型。

内容的提问来源于stack exchange,提问作者gcstr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 14:45:32