I\'m trying to use the Accessibility API to change the position of other applications windows.What I wish to do is to get all the windows on the screen from all the applicat
Based on your sample code (slightly modified, as what you posted does not compile and will crash unmodified), I did some experiments.
Here are a few caveats:
CGWindowListCopyWindowInfo
will return "all on screen" windows when asked the way you're calling it, but it doesn't guarantee that these are either "user windows" or windows with accessibility. Most menu bar items have a root window which is "on screen" and most of them aren't accessible (which shows up when you try to walk the accessibility tree for the PIDs you retrieve).I've included here modifications to your code (this will run without crashing), which will grab the pertinent window information from the applications you retrieve via PID and then move the windows. I have a sleep statement so that I could stop execution, since I was just testing for the effect of movement:
#import <Foundation/Foundation.h>
#import <CoreFoundation/CoreFoundation.h>
#import <ApplicationServices/ApplicationServices.h>
int main(int argc, char *argv[]) {
@autoreleasepool {
// Get all the windows
CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
NSArray* arr = CFBridgingRelease(windowList);
// Loop through the windows
for (NSMutableDictionary* entry in arr)
{
// Get window PID
pid_t pid = [[entry objectForKey:(id)kCGWindowOwnerPID] intValue];
// Get AXUIElement using PID
AXUIElementRef appRef = AXUIElementCreateApplication(pid);
NSLog(@"Ref = %@",appRef);
// Get the windows
CFArrayRef windowList;
AXUIElementCopyAttributeValue(appRef, kAXWindowsAttribute, (CFTypeRef *)&windowList);
NSLog(@"WindowList = %@", windowList);
if ((!windowList) || CFArrayGetCount(windowList)<1)
continue;
// get just the first window for now
AXUIElementRef windowRef = (AXUIElementRef) CFArrayGetValueAtIndex( windowList, 0);
CFTypeRef role;
AXUIElementCopyAttributeValue(windowRef, kAXRoleAttribute, (CFTypeRef *)&role);
CFTypeRef position;
CGPoint point;
// Get the position attribute of the window (maybe something is wrong?)
AXUIElementCopyAttributeValue(windowRef, kAXPositionAttribute, (CFTypeRef *)&position);
AXValueGetValue(position, kAXValueCGPointType, &point);
// Debugging (always zeros?)
NSLog(@"point=%f,%f", point.x,point.y);
// Create a point
CGPoint newPoint;
newPoint.x = 0;
newPoint.y = 0;
NSLog(@"Create");
position = (CFTypeRef)(AXValueCreate(kAXValueCGPointType, (const void *)&newPoint));
// Set the position attribute of the window (runtime error over here)
NSLog(@"SetAttribute");
AXUIElementSetAttributeValue(windowRef, kAXPositionAttribute, position);
sleep(5);
}
}
}