Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do I find the topmost window at a given point? #76

Open
stijlist opened this issue Mar 23, 2021 · 1 comment
Open

How do I find the topmost window at a given point? #76

stijlist opened this issue Mar 23, 2021 · 1 comment

Comments

@stijlist
Copy link

How would I find the topmost window at a point?
Here's the code I have, but I'm not sure how to figure out which window is on top.

I don't see any references to z-index in the existing or planned API docs.

import Cocoa
import Swindler
import PromiseKit

let currentCursor = NSEvent.mouseLocation
print(currentCursor)
let _ = Swindler.initialize()
    .done { state -> Void in
        print(
            state.knownWindows.filter({
                window in
                guard window.isMinimized.value else { return false }
                return window.frame.value.contains(currentCursor)
            }))
        exit(0)
    }.catch { error in
        print(error)
    }
CFRunLoopRun()
@tmandry
Copy link
Owner

tmandry commented Mar 24, 2021

Hey! As I understand it it's actually kind of hard to do this with public APIs, but possible.

It is possible to get the window number of the topmost window at a given point (link). Then you have to tie that to the same window in the AX system. The best way using public APIs I know is to enumerate the windows in both systems and match their frames, pids, and titles: see this answer.

There is a private (unstable) API that ties them together directly: _AXUIElementGetWindow. We should expose a way to get the underlying AXUIElement for people who want to do this. It would have to be an Optional to work with the fake testing API.

Sorry it's such a pain. Converting from/to window IDs is something I'd like to see in Swindler itself, and it would enable APIs that do what you want directly. It would have to deal with the edge case of having two windows with the same frame, pid, and title somehow. We could also support the private API, but it would need to be with a compile time switch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants