3

我正在研究用于 Parallels 开发的 OSX 键盘重新映射器 Karabiner。根据this issue,最好通过向Apple提交错误来解决。

什么是替代(如果有)支持的 API 来创建这样的功能?

4

2 回答 2

1

正如pkamb在 OP 链接到的 github 问题上所指出的(自他发布以来添加),Apple技术说明 TN2450记录了正确的 API:

IOKit HID API 可用于密钥重新映射。用户将提供 HID 事件系统将应用于键盘的键重新映射字典。
清单 3:使用 IOKit HID API 的键重映射。// 用 Xcode 8.2.1 编译

#import <Foundation/Foundation.h>
#import <IOKit/hidsystem/IOHIDEventSystemClient.h>
#import <IOKit/hidsystem/IOHIDServiceClient.h>
#import <IOKit/hid/IOHIDUsageTables.h>

int main(int argc, char *argv[])
{
    IOHIDEventSystemClientRef system;
    CFArrayRef services;

    uint64_t aKey = 0x700000004;
    uint64_t bKey = 0x700000005;

    NSArray *map = @[
                     @{@kIOHIDKeyboardModifierMappingSrcKey:@(aKey),
                        @kIOHIDKeyboardModifierMappingDstKey:@(bKey)},
                     @{@kIOHIDKeyboardModifierMappingSrcKey:@(bKey),
                        @kIOHIDKeyboardModifierMappingDstKey:@(aKey)},
                     ];

    system = IOHIDEventSystemClientCreateSimpleClient(kCFAllocatorDefault);
    services = IOHIDEventSystemClientCopyServices(system);
    for(CFIndex i = 0; i < CFArrayGetCount(services); i++) {
        IOHIDServiceClientRef service = (IOHIDServiceClientRef)CFArrayGetValueAtIndex(services, i);
        if(IOHIDServiceClientConformsTo(service, kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard)) {
            IOHIDServiceClientSetProperty(service, CFSTR(kIOHIDUserKeyUsageMapKey), (CFArrayRef)map);
        }
    }

    CFRelease(services);
    CFRelease(system);

    return 0;
}

示例:
如果您尝试重新映射外部 USB 键盘上的命令/选项/控制键,请enum查看IOHIDUsageTables.h. 例如,可以使用以下映射重新映射 Z-88 键盘以匹配 MacBookPro 上的按键布局:

NSArray *remap = @[
  @{@kIOHIDKeyboardModifierMappingSrcKey:@(0x7000000E3),
    @kIOHIDKeyboardModifierMappingDstKey:@(0x7000000E2)},
  @{@kIOHIDKeyboardModifierMappingSrcKey:@(0x7000000E2),
    @kIOHIDKeyboardModifierMappingDstKey:@(0x7000000E3)},
  @{@kIOHIDKeyboardModifierMappingSrcKey:@(0x7000000E6),
    @kIOHIDKeyboardModifierMappingDstKey:@(0x7000000E7)},
  @{@kIOHIDKeyboardModifierMappingSrcKey:@(0x700000065),
    @kIOHIDKeyboardModifierMappingDstKey:@(0x7000000E6)}
];
  • LeftGUI (E3) → LeftAlt (E2)
  • LeftAlt (E2) → LeftGUI (E3)
  • RightAlt (E6) → RightGUI (E7)
  • 应用程序 (65) → RightAlt (E6)

要撤消映射,请将相同的键映射回其原始值。使用上面的例子:

NSArray *unmap = @[
  @{@kIOHIDKeyboardModifierMappingSrcKey:@(0x7000000E3),
    @kIOHIDKeyboardModifierMappingDstKey:@(0x7000000E3)},
  @{@kIOHIDKeyboardModifierMappingSrcKey:@(0x7000000E2),
    @kIOHIDKeyboardModifierMappingDstKey:@(0x7000000E2)},
  @{@kIOHIDKeyboardModifierMappingSrcKey:@(0x7000000E6),
    @kIOHIDKeyboardModifierMappingDstKey:@(0x7000000E6)},
  @{@kIOHIDKeyboardModifierMappingSrcKey:@(0x700000065),
    @kIOHIDKeyboardModifierMappingDstKey:@(0x700000065)}
];
于 2020-06-03T07:08:34.520 回答
-1

尽管文档和用户界面简陋,但Karabiner-Elements是可靠且多功能的,对于正在进行的工作是可以原谅的。有许多有用的示例,例如,这个需要专用工具和 Karabiner 错误日志来生成棘手的 JSON 规则。任何键都可以同时是修饰键和常规键、运行程序等。GitHub 上的公共域。

于 2020-06-03T05:44:43.633 回答