Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save maheshgiri/38163fad0f1f48b87792f3d048812b10 to your computer and use it in GitHub Desktop.

Select an option

Save maheshgiri/38163fad0f1f48b87792f3d048812b10 to your computer and use it in GitHub Desktop.

Revisions

  1. Matt Reagan renamed this gist Sep 22, 2015. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. Matt Reagan created this gist Sep 22, 2015.
    62 changes: 62 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,62 @@
    NSWindow *topmostAppWindowAtPoint(CGPoint screenPoint)
    {
    const CGWindowLevel kScreensaverWindowLevel = CGWindowLevelForKey(kCGScreenSaverWindowLevelKey);

    /* This function returns a pointer to the app's topmost NSWindow that
    the point `screenPoint` is over. The important distinction here is that
    this function takes _all_ system windows into consideration and will return
    `nil` if there is a system window (or NSMenu etc.) that the cursor
    is over which is atop the app window, which is information that
    can't otherwise be gleaned by checking against `[NSApp orderedWindows]` etc.

    This is useful in cases where you need to know e.g. what window the cursor is
    *really* over, whether it is a window in your app, or a menu in the menubar, etc.
    */

    pid_t appPID = [[NSRunningApplication currentApplication] processIdentifier];

    NSWindow *appWindow = nil;
    CFArrayRef windowArray = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
    CFIndex windowCount = 0;

    NSRect mainScreenRect = NSScreen.mainScreen.frame;
    float mainScreenHeight = mainScreenRect.size.height;

    /* Flip the screen coord point Y here to match what the CGWindow expects */
    screenPoint.y = mainScreenHeight - screenPoint.y;

    if ((windowCount = CFArrayGetCount(windowArray)))
    {
    for (CFIndex i = 0; i < windowCount; i++)
    {
    NSDictionary *windowInfoDictionary = (__bridge NSDictionary *)((CFDictionaryRef)CFArrayGetValueAtIndex(windowArray, i));
    NSNumber *ownerPID = (NSNumber *)(windowInfoDictionary[(id)kCGWindowOwnerPID]);
    NSNumber *level = (NSNumber *)(windowInfoDictionary[(id)kCGWindowLayer]);

    if (ownerPID.intValue == appPID)
    {
    /* We are concerned with menus or application windows etc., anything
    at or above screensaver level (1000) we just assume is something special
    that we should ignore, and skip it. */

    if (level.integerValue < kScreensaverWindowLevel)
    {
    CGRect rect = NSZeroRect;
    CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)(windowInfoDictionary[(id)kCGWindowBounds]), &rect);

    if (CGRectContainsPoint(rect, screenPoint))
    {
    NSNumber *windowID = windowInfoDictionary[(id)kCGWindowNumber];
    appWindow = [NSApp windowWithWindowNumber:windowID.integerValue];

    break;
    }
    }
    }
    }
    }

    CFRelease(windowArray);

    return appWindow;
    }