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

如何在macOS通过特定按键绑定获取激活文本框最后N个字符?

实现macOS全局快捷键捕获任意文本框最后N个字符

要实现按下指定快捷键(如Ctrl+S)时捕获当前激活文本框的最后N个字符,需要结合全局快捷键监听、Accessibility API操作文本选中范围和选中文本获取三个核心环节,以下是具体实现方案:

一、全局快捷键注册

首先注册全局快捷键监听,捕获用户的按键组合触发事件。使用NSEvent.addGlobalMonitorForEvents实现全局范围的按键监听,注意需要请求用户授予辅助功能权限。

import Cocoa
import ApplicationServices

class ShortcutManager {
    static let shared = ShortcutManager()
    
    private init() {
        registerGlobalShortcut()
    }
    
    private func registerGlobalShortcut() {
        // 监听Ctrl+S快捷键(keyCode 1对应S,mask包含control)
        NSEvent.addGlobalMonitorForEvents(matching: .keyDown) { event in
            if event.keyCode == 1 && event.modifierFlags.contains(.control) {
                self.captureLastNCharacters(n: 200)
            }
        }
    }
    
    private func captureLastNCharacters(n: Int) {
        guard let focusedElement = self.getFocusedTextElement() else { return }
        guard self.selectLastNCharacters(in: focusedElement, count: n) else { return }
        let capturedText = self.getSelectedText(from: focusedElement)
        print("捕获到的文本:\(capturedText ?? "无")")
    }
}

二、获取聚焦的文本元素

通过Accessibility API获取当前系统中聚焦的UI元素,验证其是否为可编辑文本元素:

extension ShortcutManager {
    private func getFocusedTextElement() -> AXUIElement? {
        let systemWideElement = AXUIElementCreateSystemWide()
        var focusedElement: AnyObject?
        let error = AXUIElementCopyAttributeValue(systemWideElement, kAXFocusedUIElementAttribute as CFString, &focusedElement)
        
        guard error == .success, let element = focusedElement as? AXUIElement else {
            return nil
        }
        
        // 验证元素是否为启用状态的可编辑文本
        var isEnabled: AnyObject?
        if AXUIElementCopyAttributeValue(element, kAXEnabledAttribute as CFString, &isEnabled) == .success,
           let enabled = isEnabled as? Bool, enabled {
            return element
        }
        return nil
    }
}

三、选中文本框的最后N个字符

通过Accessibility API获取文本总长度,计算选中范围并设置到目标元素:

extension ShortcutManager {
    private func selectLastNCharacters(in element: AXUIElement, count: Int) -> Bool {
        // 获取文本总长度
        var textLength: AnyObject?
        guard AXUIElementCopyAttributeValue(element, kAXNumberOfCharactersAttribute as CFString, &textLength) == .success,
              let length = textLength as? Int else {
            return false
        }
        
        // 计算选中起始位置:文本长度小于N时从0开始
        let start = max(0, length - count)
        let selectedRange = CFRange(location: start, length: length - start)
        
        // 设置选中范围
        guard let rangeValue = AXValueCreate(.range, &selectedRange) else { return false }
        let error = AXUIElementSetAttributeValue(element, kAXSelectedTextRangeAttribute as CFString, rangeValue)
        
        return error == .success
    }
}

四、获取选中的文本

整合并优化你提供的选中文本获取逻辑:

extension ShortcutManager {
    private func getSelectedText(from element: AXUIElement) -> String? {
        var selectedText: AnyObject?
        let error = AXUIElementCopyAttributeValue(element, kAXSelectedTextAttribute as CFString, &selectedText)
        return error == .success ? selectedText as? String : nil
    }
}

权限说明

  • 运行应用前,需在系统偏好设置 > 安全性与隐私 > 隐私 > 辅助功能中添加你的应用,否则Accessibility API无法正常调用。
  • 首次运行时系统会弹出权限请求提示,点击"打开偏好设置"完成授权即可。

使用方式

在应用启动时初始化ShortcutManager:

@main
class AppDelegate: NSObject, NSApplicationDelegate {
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        _ = ShortcutManager.shared
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 12:22:29