【问题标题】:Simple key remapping using IOKit with Swift使用 IOKit 和 Swift 进行简单的键重映射
【发布时间】:2021-12-26 23:56:39
【问题描述】:

在 macOS 中,IOKitHID API 可用于密钥重新映射。在下面的示例中,A 键被重新映射到 B 键,反之亦然,使用 Objective-C。

是否可以使用最新的 Swift 5.5 以编程方式进行相同的重新映射?如果可以,下面的例子看起来如何用 Swift 重写

或者是否有一种新的、更现代的 API 可以与 Swift 一起使用来完成相同的任务?


#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;
}

【问题讨论】:

    标签: swift objective-c macos hid iokit


    【解决方案1】:

    你可以像这样在 Swift 5.5 中重写你被诅咒的代码:

    import Cocoa
    
    class ViewController: NSViewController {
    
      override func viewDidLoad() {
        super.viewDidLoad()
        
         remapKeys()
      }
    
      func remapKeys() {
        let aKey: UInt64 = 0x700000004
        let bKey: UInt64 = 0x700000005
        
        let map: [[String: UInt64]] = [
          [kIOHIDKeyboardModifierMappingSrcKey:aKey,
           kIOHIDKeyboardModifierMappingDstKey:bKey],
          [kIOHIDKeyboardModifierMappingSrcKey:bKey,
           kIOHIDKeyboardModifierMappingDstKey:aKey],
        ]
        
        let system = IOHIDEventSystemClientCreateSimpleClient(kCFAllocatorDefault)
        let services = IOHIDEventSystemClientCopyServices(system)
        
        for service in services as! [IOHIDServiceClient] {
          if((IOHIDServiceClientConformsTo(service, UInt32((kHIDPage_GenericDesktop)), UInt32(kHIDUsage_GD_Keyboard))) != 0) {
            IOHIDServiceClientSetProperty(service, kIOHIDUserKeyUsageMapKey as CFString, map as CFArray)
          }
        }
      }
    }
    

    如果您创建一个包含这些导入的桥接头:

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

    【讨论】:

    • 我无法让它工作。我确实正确设置了桥接头,但无济于事。
    • 这很奇怪,它对我有用,而且非常非常烦人。你在试什么操作系统?试试我的回购:github.com/rfistman/swift-key-remap
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-20
    • 1970-01-01
    • 1970-01-01
    • 2014-10-08
    相关资源
    最近更新 更多