talonvoice / talon

Issue Tracker for the main Talon app
85 stars 0 forks source link

ui.windows() is not Z ordered on Windows #147

Closed jamesmugford closed 3 years ago

jamesmugford commented 4 years ago

windows = ui.windows() seems broken

Properties attached to window object are not correct.

e.g: window.heightand window.y for specific windows all return the same result

Hope this help

OS: Windows 10

timo commented 4 years ago

the window class doesn't seem to have height and y properties at all at least on my version; does it have a .rect property?

jamesmugford commented 4 years ago

Hmmm, maybe it's a deprecated API?

I assumed it was present from knausj85's code, here: https://github.com/knausj85/knausj_talon/blob/dcbb1ea89fd1bfbd09f57c25d9dc8a8907270c42/code/mouse.py#L239

It doesn't look like there is a rect property either.

This is currently a blocker for creating nice gaze scrolling

I'm presuming this is because the eyetracking API is not public yet and is undergoing frequent change.

I'll try to set up proper IntelliSense and see what is available

knausj85 commented 4 years ago

I think Talon's working fine

I think you're slightly misreading the code here due to questionable variable naming. "window" in the referenced script is actually the rect.

The function looks for the first window that contains mouse coordinate. This should perhaps just use ui.active_window() instead.

if you do something like this, you will see all dimensions and positions for windows. for w in ui.windows(): print(str(w) + "({},{}) ({}{})".format(w.rect.x, w.rect.y, w.rect.width, w.rect.height))

lunixbochs commented 4 years ago

is this not actually a bug?

knausj85 commented 4 years ago

As far as I can tell, the window sizing information is correct on Windows 10. I believe the actual issue is that the window list isn't Z-sorted, as on Mac and Linux.

I've poked around for an API that will allow us to do so, but they all feature ominous warnings.

e.g., https://stackoverflow.com/questions/6381198/get-window-z-order-with-python-windows-extensions suggests:

import win32gui
import win32con
def get_windows():
    '''Returns windows in z-order (top first)'''
    lst = []
    top = win32gui.GetTopWindow()
    if top is None: return lst
    lst.append(top)
    while True:
        next = win32gui.GetNextWindow(lst[-1], win32con.GW_HWNDNEXT)
        if next is None: break
        lst.append(next)
    return lst

but this just calls GetWindow, which has some (albeit obvious) caveats:

Remarks The EnumChildWindows function is more reliable than calling GetWindow in a loop. An application that calls GetWindow to perform this task risks being caught in an infinite loop or referencing a handle to a window that has been destroyed.

People claim EnumWindows / EnumChildWindows z-orders things, but its not actually documented and probably not guaranteed.

throws hands in air

lunixbochs commented 4 years ago

Is a valid janky solution just to sort the topmost window to the front and ignore ordering the rest for now?

knausj85 commented 4 years ago

Hmm, maybe. I'd be willing to test around it for you.

lunixbochs commented 4 years ago

What does your code need the window order for?

knausj85 commented 4 years ago

It's used for the rudimentary "gaze" scrolling with control mouse. Scrolls based on the cursor distance vs midpoint of the window that contains the cursor.

https://github.com/knausj85/knausj_talon/blob/d762a609d264b065c165dd97109262bf2915bae4/code/mouse.py#L282

lunixbochs commented 4 years ago

Why not only consider active_window as a workaround?

knausj85 commented 4 years ago

It's on my list to look at active_window first to improve it - or maybe exclusively on Windows for now, but that's a little less convenient. Since scrolling is allowed without a window having focus on Windows and Mac, it's not 'ideal' to consider just active_window, long-term, imo. I take advantage of this behavior often.

lunixbochs commented 3 years ago

https://stackoverflow.com/q/295996

Previous answers need considerable refinement. Enum-order = Z-order only if GetSystemMetrics(SM_IMMENABLED)=0, i.e. Input Method Manager/Input Method Editor features are disabled. Because all windows class "IME" (the title "Default IME") and "MSCTFIME UI" are enumerated after the window "Progman" ("Program Manager"), - i.e. not in Z-order.

lunixbochs commented 3 years ago

Fixed in 0.1.5-452