如何使用 IOKit 在 macOS 中以编程方式更改鼠标设置

How to change mouse settings programmatically in macOS using IOKit

函数 IOHIDGetAccelerationWithKeyIOHIDSetAccelerationWithKey 自 macOS 10.12 以来已弃用,因此我尝试使用其他 IO* 方法实现相同的功能。

我从未使用过 IOKit,因此,我所能做的就是 google 函数并尝试让它工作。 现在我发现了这个:Can't edit IORegistryEntry,其中有一个如何更改 TrackpadThreeFingerSwipe 属性 的示例,但是它使用的函数不是为我定义的:getEVSHandle。谷歌搜索只显示它应该 在 MachineSettings 框架 中找到,但是我似乎无法在 Xcode 11 中添加任何 "MachineSettings" 框架。

我该怎么办?当前代码如下:

#import <Foundation/Foundation.h>
#import <IOKit/hidsystem/IOHIDLib.h>

int main(int argc, const char * argv[]) {
   @autoreleasepool {
      NSInteger value = -65536;
      CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberNSIntegerType, &value);
      CFMutableDictionaryRef propertyDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, NULL, NULL);
      CFDictionarySetValue(propertyDict, @"HIDMouseAcceleration", number);

      io_connect_t connect = getEVSHandle(); // ???

      if (!connect)
      {
          NSLog(@"Unable to get EVS handle");
      }

      res = IOConnectSetCFProperties(connect, propertyDict);

      if (res != KERN_SUCCESS)
      {
         NSLog(@"Failed to set mouse acceleration (%d)", res);
      }

      IOObjectRelease(service);

      CFRelease(propertyDict);
   }
   return 0;
}

以下作品(使用 Xcode 11.2 / macOS 10.15 测试)

#import <Foundation/Foundation.h>
#import <IOKit/hidsystem/IOHIDLib.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        io_service_t service = IORegistryEntryFromPath(kIOMasterPortDefault, 
            kIOServicePlane ":/IOResources/IOHIDSystem");

        NSDictionary *parameters = (__bridge NSDictionary *)IORegistryEntryCreateCFProperty(service, 
            CFSTR(kIOHIDParametersKey), kCFAllocatorDefault, kNilOptions);
        NSLog(@"%@", parameters);

        NSMutableDictionary *newParameters = [parameters mutableCopy];
        newParameters[@"HIDMouseAcceleration"] = @(12345);

        kern_return_t result = IORegistryEntrySetCFProperty(service,  
            CFSTR(kIOHIDParametersKey), (__bridge CFDictionaryRef)newParameters);
        NSLog(kIOReturnSuccess == result ? @"Updated" : @"Failed");

        IOObjectRelease(service);
    }
    return 0;
}