1

I did some research and it looks like this is stored in the IORegistry under ":/IOResources/HIDSystem" as "HIDMouseAcceleration".

Can these be set from a user program using the IORegistry API?

Any other ways to programmatically change the mouse system preferences settings?

My choice of programming language is C. The approach needs to work on OS X v10.11+.

Thanks.

Hari Mahadevan
  • 920
  • 7
  • 14
  • 1
    [This answer](https://apple.stackexchange.com/a/77212/50698) shows how to do it from the command line and from `AppleScript` (or whatever that language is), so you could call the programs via `system`... – Ken Y-N Jan 25 '19 at 04:49
  • Thanks. That's good to know. But this solution may not be viable as it would require the user to enable Accessibility (from Security & Privacy -> Privacy) for Script Editor. Or perhaps if I run the script as a root from a daemon, this privilege is implicit? Does any program do this? – Hari Mahadevan Jan 25 '19 at 05:54
  • 1
    [Here's some Objective-C](https://stackoverflow.com/a/3693349/1270789) that does `defaults write` to different keys, so hopefully you can hack something up from that base and the single program can be given the necessary execution rights. (Note, I'm skilled at Google, not OSX, so please don't ask me any more details!) – Ken Y-N Jan 25 '19 at 06:16
  • @KenY-N Thanks for the quick response. And no I won't ask anything directly(I didn't do that earlier either:-)) But I must say, your Google skills seem to be far superior to mine! – Hari Mahadevan Jan 25 '19 at 07:37

1 Answers1

1

Yes, it's possible. Here's some rough code to do it:

io_object_t hidSystemParametersConnection = IO_OBJECT_NULL;

// We're looking for a service of the IOHIDSystem class
CFMutableDictionaryRef classesToMatch = IOServiceMatching("IOHIDSystem");
if (!classesToMatch)
    /* handle failure */;

// The following call implicitly releases classesToMatch
io_iterator_t matchingServicesIterator = IO_OBJECT_NULL;
IOReturn ret = IOServiceGetMatchingServices(kIOMasterPortDefault, classesToMatch, &matchingServicesIterator);
if (ret != kIOReturnSuccess)
    /* handle failure */;

io_object_t service;
while ((service = IOIteratorNext(matchingServicesIterator)))
{
    // Open the parameters connection to the HIDSystem service
    ret = IOServiceOpen(service, mach_task_self(), kIOHIDParamConnectType, &hidSystemParametersConnection);
    IOObjectRelease(service);

    if (ret == kIOReturnSuccess && hidSystemParametersConnection != IO_OBJECT_NULL)
        break;
}

IOObjectRelease(matchingServicesIterator);

CFTypeRef value;
ret = IOHIDCopyCFTypeParameter(hidSystemParametersConnection, CFSTR(kIOHIDPointerAccelerationKey), &value);
if (ret != kIOReturnSuccess || !value)
    /* handle failure */;

if (CFGetTypeID(value) != CFNumberGetTypeID())
{
    CFRelease(value);
    /* handle wrong type */
}

NSNumber* accel = CFBridgingRelease(value);
double newAccel = accel.doubleValue / 2;

ret = IOHIDSetCFTypeParameter(hidSystemParametersConnection, CFSTR(kIOHIDPointerAccelerationKey), (__bridge CFTypeRef)@(newAccel));
if (ret != kIOReturnSuccess)
    /* handle failure */;

IOServiceClose(hidSystemParametersConnection);

The various parameter keys are defined and lightly documented in IOKit.framework/Headers/hid/IOHIDProperties.h and IOKit.framework/Headers/hidsystem/IOHIDParameter.h. I would test thoroughly with as much different hardware and configurations in System Preferences as you can, to see exactly which parameters are relevant and what their values mean.

Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
  • Thanks a lot! Will try it out and let you know. – Hari Mahadevan Jan 25 '19 at 07:40
  • Yes that does work. However, the mouse system preferences controls for the settings are not updated as these values are changed externally. I guess it doesn't have a notification callback for changes to these values. – Hari Mahadevan Jan 28 '19 at 07:03