Reputation: 21
I am trying to get the on screen position of every visible window on os x. In my function get_position(), AXUIElementCopyAttributeValue() returns kAXErrorAttributeUnsupported for every window on screen except for the finder window. Why is this the case? and What am I doing wrong?
int get_position()
{
CFArrayRef a = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
NSArray * arr = CFBridgingRelease(a);
pid_t window_pid = 0;
unsigned long count = [ arr count];
NSMutableDictionary* entry;
for ( unsigned long i = 0; i < count; i++)
{
//CFTypeRef position;
AXValueRef temp;
CGPoint current_point;
entry = arr[i];
window_pid = [[entry objectForKey:(id)kCGWindowOwnerPID] intValue];
NSString * temp_ns_string = [entry objectForKey:(id)kCGWindowName ];
const char *window_name =[temp_ns_string UTF8String];
printf("%s - ", window_name);
printf("Pid: %i\n", window_pid);
AXUIElementRef window_ref = AXUIElementCreateApplication(window_pid);
AXError error = AXUIElementCopyAttributeValue(window_ref, kAXPositionAttribute, (CFTypeRef *)&temp);
if ((AXValueGetValue(temp, kAXValueCGPointType, ¤t_point) ))
{
printf("%s - ", window_name);
printf("Pid: %i - ", window_pid);
printf(" %f,%f\n", current_point.x, current_point.y);
}
else
{
printf("%s - ", window_name);
printf("Pid: %i\n", window_pid);
}
}
return 0;
}
Upvotes: 2
Views: 1523
Reputation: 501
On MacOS, each app may have more than one window, different windows use the same pid.
AXUIElementRef app = AXUIElementCreateApplication(pid)
So you can get the 1 focus window by give kAXFocusedWindowAttribute
AXUIElementRef window;
AXUIElementCopyAttributeValue(app, kAXFocusedWindowAttribute, &window)
Or you can get multi windows by give kAXWindowsAttribute
NSArray *windows;
AXUIElementCopyAttributeValues(app, kAXWindowsAttribute,
0,
99999,
(CFArrayRef *) &result
);
then get position or size from window
AXValueRef pos;
AXValueRef size;
AXUIElementCopyAttributeValue(window, kAXPositionAttribute, (CFTypeRef *)&pos)
AXUIElementCopyAttributeValue(window, kAXSizeAttribute, (CFTypeRef *)&size)
now, convert the position into actual CGPoint or CGSize
CGPoint cpoint = CGPointMake(0, 0);
CGSize csize = CGSizeMake(0, 0);
AXValueGetValue(pos, kAXValueCGPointType, &cpoint);
AXValueGetValue(size, kAXValueCGSizeType, &csize);
I think above should help.
Upvotes: 5
Reputation: 15598
AXUIElementRef window_ref = AXUIElementCreateApplication(window_pid);
AXUIElementCreateApplication
returns an application object. Most applications don't have a position. Some applications return a position but this isn't the position of the window. The position of the window is in the dictionary with key kCGWindowBounds
.
Upvotes: 0