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

Feature request: getWindowAt #20

Closed
Avasam opened this issue Jul 24, 2022 · 2 comments · Fixed by #22
Closed

Feature request: getWindowAt #20

Avasam opened this issue Jul 24, 2022 · 2 comments · Fixed by #22

Comments

@Avasam
Copy link
Collaborator

Avasam commented Jul 24, 2022

Similar to getWindowsAt, but only returns the top window at position. It can also rely on faster implementation since it may not need to get all windows.

For Windows, here's a snippet from https://github.com/Avasam/Auto-Split to quickly get the HWND at a coordinate

import win32gui
def __get_window_from_point(x: int, y: int) -> tuple[int, str]:
    # Grab the window handle from the coordinates selected by the widget
    hwnd = cast(int, win32gui.WindowFromPoint((x, y)))

    # Want to pull the parent window from the window handle
    # By using GetAncestor we are able to get the parent window instead
    # of the owner window.
    while win32gui.IsChild(win32gui.GetParent(hwnd), hwnd):
        hwnd = cast(int, user32.GetAncestor(hwnd, GA_ROOT))

    window_text = win32gui.GetWindowText(hwnd)

    return hwnd, window_text

Microsoft documentation: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-windowfrompoint

For other OSes... idk. I'm still trying to figure it out. I wouldn't mind starting with a naive implementation that reuses getWindowsAt

@Avasam
Copy link
Collaborator Author

Avasam commented Jul 24, 2022

For Linux, it seems getClientListStacking actually returns windows in stacking order from bottom to top.
I'm curious if there's any real performance difference between getClientListStacking and getClientList. If not, we could just opt for getClientListStacking all the time. And take the last element returned by getWindowsAt

https://ewmh.readthedocs.io/en/latest/ewmh.html#ewmh.ewmh.EWMH.getClientListStacking

I also saw someone say that XQueryTree gives list of windows in the stacking order. But I have not tested that claim.
https://stackoverflow.com/questions/31712876/with-x11-get-window-at-coordinates#31733725
https://tronche.com/gui/x/xlib/window-information/XQueryTree.html

@Kalmat
Copy link
Owner

Kalmat commented Jul 24, 2022

Hi!

I think I get your point. You want the upper window at a given point, right? Then, we could create a new method called: getUpperWindowAt() (sorry for my english, perhaps there is a better word than "upper").

In such a case, order matters, so your implementation on Windows and Linux seems totally right (I have not tested getClientList vs. getClientListStacking performance, though I don't think there should be much difference).

The problem will come, once again, on macOS. I didn't find any property or attribute which can be used to know the windows/apps stacking. Quartz returns the list of apps in "last to first focused" order, which in many cases may not match "upper". Given an app, it's possible to know its windows stack order, but unfortunately not for the app itself... Yes, I also love macOS... HAHAHAHA!

I'm still out for some reasons and couldn't work on the module yet. If you agree, I will add this new method (including the constrains of macOS) as soon as I can!!! You can also clone or fork the project and work on a PR if you want to. Any contribution is more than welcome!

Avasam added a commit to Avasam/PyWinCtl that referenced this issue Jul 24, 2022
This was referenced Jul 24, 2022
@Kalmat Kalmat closed this as completed in #22 Aug 4, 2022
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

Successfully merging a pull request may close this issue.

2 participants