Reputation: 61483
I'm looking at Karabiner, the OSX keyboard remapper for Parallels development. According to this issue this is best fixed by filing a bug with Apple.
What is the alternative (if any) supported API to create such a functionality?
Upvotes: 3
Views: 389
Reputation: 90671
As noted by pkamb on the github issue that OP linked to (added since he posted), Apple technote TN2450 documents the proper API:
The IOKit HID APIs can be used for key remapping. The user will provide a dictionary of key remapping that the HID event system will apply to the keyboard.
Listing 3 : Key Remapping using IOKit HID APIs. // compiled with 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; }
Example:
If you are trying to re-map the command / option / control keys on an external USB keyboard, take a look at the enum
's defined in IOHIDUsageTables.h
. For example, a Z-88 keyboard can be remapped to match the key layout on a MacBookPro using this mapping:
NSArray *remap = @[
@{@kIOHIDKeyboardModifierMappingSrcKey:@(0x7000000E3),
@kIOHIDKeyboardModifierMappingDstKey:@(0x7000000E2)},
@{@kIOHIDKeyboardModifierMappingSrcKey:@(0x7000000E2),
@kIOHIDKeyboardModifierMappingDstKey:@(0x7000000E3)},
@{@kIOHIDKeyboardModifierMappingSrcKey:@(0x7000000E6),
@kIOHIDKeyboardModifierMappingDstKey:@(0x7000000E7)},
@{@kIOHIDKeyboardModifierMappingSrcKey:@(0x700000065),
@kIOHIDKeyboardModifierMappingDstKey:@(0x7000000E6)}
];
To undo a mapping, map the same keys back to their original values. Using the above example:
NSArray *unmap = @[
@{@kIOHIDKeyboardModifierMappingSrcKey:@(0x7000000E3),
@kIOHIDKeyboardModifierMappingDstKey:@(0x7000000E3)},
@{@kIOHIDKeyboardModifierMappingSrcKey:@(0x7000000E2),
@kIOHIDKeyboardModifierMappingDstKey:@(0x7000000E2)},
@{@kIOHIDKeyboardModifierMappingSrcKey:@(0x7000000E6),
@kIOHIDKeyboardModifierMappingDstKey:@(0x7000000E6)},
@{@kIOHIDKeyboardModifierMappingSrcKey:@(0x700000065),
@kIOHIDKeyboardModifierMappingDstKey:@(0x700000065)}
];
Upvotes: 1
Reputation: 1093
Karabiner-Elements is solid and versatile despite the sketchy documentation and user interface, excusable for a work in progress. There are many useful examples, e.g., this one which required dedicated tools and the Karabiner error log to generate the tricky JSON rules. Any key can be both a modifier and regular key, run a program, etc., all at once. Public domain on GitHub.
Upvotes: -1