如何在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
相关产品推荐
相关产品推荐

