CGWindowID CGWindowWithInfo(AXUIElementRef window, CGPoint location) {

    AXError error;

    pid_t pid;
    error = AXUIElementGetPid(window, &pid);
    if (error != kAXErrorSuccess)
        return kCGNullWindowID;

    CFStringRef title = NULL;
    error = AXUIElementGetTitle(window, &title);

    CGRect frame;
    error = AXUIElementGetFrame(window, &frame);
    if (error != kAXErrorSuccess)
        return kCGNullWindowID;

    CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements,
                                                       kCGNullWindowID);
    if (windowList == NULL)
        return kCGNullWindowID;

    CGWindowID windowID = kCGNullWindowID;

    for (CFIndex i = 0; i < CFArrayGetCount(windowList); i++) {

        CFDictionaryRef window = CFArrayGetValueAtIndex(windowList, i);

        int windowPID;
        CFNumberGetValue(CFDictionaryGetValue(window, kCGWindowOwnerPID),
                         kCFNumberIntType,
                         &windowPID);

        if (windowPID != pid)
            continue;

        CGRect windowBounds;
        CGRectMakeWithDictionaryRepresentation(CFDictionaryGetValue(window, kCGWindowBounds),
                                               &windowBounds);

        if (!CGSizeEqualToSize(frame.size, windowBounds.size))
            continue;

        if (!CGRectContainsPoint(windowBounds, location))
            continue;

        CFStringRef windowName = CFDictionaryGetValue(window, kCGWindowName);
        if (windowName == NULL || title == NULL || CFStringCompare(windowName, title, 0) == kCFCompareEqualTo) {
            CFNumberGetValue(CFDictionaryGetValue(window, kCGWindowNumber),
                             kCGWindowIDCFNumberType,
                             &windowID);
            break;
        }
    }

    CFRelease(windowList);

    return windowID;
}
bool OSXWindowCapture::WindowRect( int windowId, CGRect *rect ) {
  CFArrayRef windowList = CGWindowListCopyWindowInfo( kCGWindowListOptionIncludingWindow, windowId );
  CFIndex numWindows = CFArrayGetCount( windowList );

  if( numWindows > 0 ) {
    CFDictionaryRef info = ( CFDictionaryRef )CFArrayGetValueAtIndex( windowList, 0 );
    CGRectMakeWithDictionaryRepresentation( ( CFDictionaryRef )CFDictionaryGetValue( info, kCGWindowBounds ), rect);
  }

  CFRelease( windowList );
  return numWindows > 0;
}
CGRect CGWindowGetBounds(CGWindowID windowID) {

    CGRect bounds;

    CFArrayRef array = CGWindowListCopyWindowInfo(kCGWindowListOptionIncludingWindow,
                                                  windowID);

    if (CFArrayGetCount(array) != 1)
        return CGRectMake(NAN, NAN, NAN, NAN);

    CFDictionaryRef dict = CFArrayGetValueAtIndex(array, 0);
    CFDictionaryRef _bounds = CFDictionaryGetValue(dict, kCGWindowBounds);
    CGRectMakeWithDictionaryRepresentation(_bounds, &bounds);

    CFRelease(array);

    return bounds;
}
CGWindowID CGWindowAtPosition(CGPoint position) {

    CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements,
                                                       kCGNullWindowID);
    if (windowList == NULL)
        return kCGNullWindowID;

    CGWindowID windowID = kCGNullWindowID;

    for (CFIndex i = 0; i < CFArrayGetCount(windowList); i++) {

        CFDictionaryRef window = CFArrayGetValueAtIndex(windowList, i);

        int layer;
        CFNumberGetValue(CFDictionaryGetValue(window, kCGWindowLayer),
                         kCFNumberIntType,
                         &layer);
        if (layer != 0)
            continue;

        CGRect windowBounds;
        CGRectMakeWithDictionaryRepresentation(CFDictionaryGetValue(window, kCGWindowBounds),
                                               &windowBounds);

        if (CGRectContainsPoint(windowBounds, position)) {
            CFNumberGetValue(CFDictionaryGetValue(window, kCGWindowNumber),
                             kCGWindowIDCFNumberType,
                             &windowID);
            break;
        }
    }

    CFRelease(windowList);

    return windowID;
}