Window list from AXUIElementRef always null on High Sierra - objective-c

After "upgrading" to macOS High Sierra it seems that some code that used to work does no longer. My goal here is just to list out the windows owned by an application. Here is an example:
#import <Foundation/Foundation.h>
#import <CoreFoundation/CoreFoundation.h>
#import <ApplicationServices/ApplicationServices.h>
int main(int argc, const char * argv[]) {
#autoreleasepool {
pid_t myPID = 311;
AXUIElementRef appRef = AXUIElementCreateApplication(myPID);
CFArrayRef windowList;
AXUIElementCopyAttributeValue(appRef, kAXWindowsAttribute, (CFTypeRef *)&windowList);
}
return 0;
}
The issue here specifically is that windowList does not get contain anything no matter what I do. I have tried multiple PIDs, building/running both debug and release builds, and running them with sudo as well.
Any ideas?

Related

How to use -performSelector:withObject:afterDelay in Command Line Tool

I'm trying to use this method on an NSObject in a macOS Command Line Tool.
https://developer.apple.com/documentation/objectivec/nsobject/1416176-performselector?language=objc
This works fine in a normal app but when I try to use it in a Command Line Tool nothings happens. I'm keeping my app running by using dispatch_main(). What else do I need to do to have this method working on an NSObject?
int main(int argc, const char * argv[])
{
#autoreleasepool
{
// ...
}
dispatch_main();
return 0;
}

How to change mouse settings programmatically in macOS using IOKit

The functions IOHIDGetAccelerationWithKey and IOHIDSetAccelerationWithKey are deprecated since macOS 10.12, therefore I am trying to implement the same using other IO*-methods.
I have never worked with IOKit, thus, all I can do is google for functions and try to get it to work.
Now I found this: Can't edit IORegistryEntry which has an example of how to change TrackpadThreeFingerSwipe property, however it is using a function which is not defined for me: getEVSHandle. Googling for it reveals only that it should be Found in the MachineSettings framework, however I can't seem to add any "MachineSettings" framework in Xcode 11.
What should I do? Current code is like:
#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;
}
The following works (tested with 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;
}

How to create my own modifier key using HID on OSX Sierra

Recently Karabiner (the great OSX remapping tool) stopped working on Sierra.
I just read that it is possible to remap keys with HID and I tried the example code below, which remaps a and b. However it's not clear how to create my own modifier key (say Modifier-X), for example TAB to Modifier-X.
Then create mappings such as TAB+X -> Launch Program X , etc...
Karabiner supported this, now Karabiner does not work, so I am trying to find another way to make this happen.
Any suggestions how can this be implemented with HID ?
#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:#(aKey)},
#{#kIOHIDKeyboardModifierMappingSrcKey:#(bKey),
#kIOHIDKeyboardModifierMappingDstKey:#(bKey)},
];
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;
}

Cocoa / OS X: Determine whether the currently selected keyboard has a numeric keypad

How do you determine the PHYSICAL type / layout of a keyboard attached to a Mac? I'm trying to determine whether the currently selected keyboard has a numeric keypad, but can't see an obvious kTISPropertyXXXXXXX to identify the number of keys / layout, a bit of example code.
#import <Foundation/Foundation.h>
#import <Carbon/Carbon.h>
int main(int argc, const char * argv[])
{
#autoreleasepool {
TISInputSourceRef currentKeyLayoutRef;
currentKeyLayoutRef = TISCopyCurrentKeyboardInputSource();
NSLog(#"Basic Info: keyboard_type=%u, layoutName=%#, localizedName=%#, languages: %#\n",
LMGetKbdType(),
TISGetInputSourceProperty(currentKeyLayoutRef, kTISPropertyInputSourceID),
TISGetInputSourceProperty(currentKeyLayoutRef, kTISPropertyLocalizedName),
TISGetInputSourceProperty(currentKeyLayoutRef, kTISPropertyInputSourceLanguages)
);
// NSLog(#"List: %#", TISGetInputSourceProperty(currentKeyLayoutRef, kTISPropertyUnicodeKeyLayoutData));
}
return 0;
}
Any ideas?

Segmentation fault when attemping to print NSString as UTF8String

I have the following objective-c snippet in my hello world example:
//hello.m
#import <Foundation/Foundation.h>
#import "hello.h"
void sayHello()
{
#ifdef FRENCH
NSString *helloWorld = #"Bonjour Monde!\n";
#else
NSString *helloWorld = #"Hello World\n";
#endif
printf("%s", [helloWorld UTF8String]);
}
//main.m
#import <Foundation/Foundation.h>
#import "hello.h"
int main (int argc, const char * argv[])
{
sayHello();
return 0;
}
building this stuff on osx works fine and runs as expected. But when compiling/linking it on ubuntu (using GNUStep) results in an segmentation fault when executing the binary. I nailed it down to the casting operation in the printf statement, but I have no clue what I'm doing wrong here or how I can solve this.
Interesting note: This works fine when using gcc toolchain to build the executable. I just see this issue when building it with clang on ubuntu.
Any help is very much appreciated.
To fix this issue, I ended up changing my code to the following:
...
void sayHello()
{
#ifdef FRENCH
NSString *helloWorld = #"${HELLO_WORLD_FRENCH}\\n";
#else
NSString *helloWorld = #"${HELLO_WORLD}\\n";
#endif
NSFileHandle *stdout = [NSFileHandle fileHandleWithStandardOutput];
NSData *strData = [helloWorld dataUsingEncoding: NSASCIIStringEncoding];
[stdout writeData: strData];
}
...