-
Notifications
You must be signed in to change notification settings - Fork 54
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
UIA provider isn't reliably detected on startup of example program #37
Comments
I can't reproduce the issue you describe (same Windows build, same Rust architecture, same NVDA version). Running the example from the commit linked above, I get the exact same result as with the next commit which introduce the workaround. For reference, here is what NVDA has to say about the window:
Hope it helps. |
@DataTriny Thanks for looking at this. If you get UIA stuff in the NVDA log, rather than IAccessible stuff, even in the situation I described where I had this problem, then the problem is indeed not happening for you. Let's see what the team at Microsoft says. |
Because of the potential race condition you mentioned, I tried compiling the example with the release flag, just to check if timing would play a role here. Apart from that, have you tried running the NVDA COM fixing tool? I don't see how it could solve this issue, but trying it costs nothing. |
I can still reproduce a variation on this with the current version of the hello_world example if I comment out the COM initialization code. Specifically, with NVDA 2021.2 on Windows 10 build 19043.1288, if NVDA is already running when the program starts, the button is announced, but sometimes the window title is not announced, and if you press NVDA+F1, you can see that the button is identified as an MSAA object, not native UIA. Moving the focus away from the window and then back fixes it. I don't know how I'm going to deal with this now that I'm trying to integrate AccessKit into druid-shell. Having druid-shell initialize COM with the MTA might be too opinionated, as it might interfere with integrating third-party components that require an STA. But having all applications have this platform-specific workaround is probably not acceptable either. |
@DataTriny I have a guess about why you can't reproduce this issue. Is the tabtip.exe process running on your PC? In the Windows 10 task manager, I believe it's called something like "Windows Touch and Handwriting Panel". As the name implies, it implements the touch keyboard on touch-enabled PCs. I have a touchscreen laptop, though I never use the touchscreen. If I kill that process, then the problem goes away. If I restart that process, then the problem comes back. I don't know what happens if you manually start that process on a non-touch-enabled PC. If you want to try it, it's in "C:\Program Files\Common Files\Microsoft Shared\Ink" (on English Windows). Anyway, I think I'm going to work around this by having |
@mwcampbell How on earth were you able to find out? If I manually start this service, I get the same kind of behavior you described here (no window title and IAccessible objects in the NVDA console). Looks like something odd is happening on Microsoft's side. BTW, if I comment out lines 231-232 of
The error code is apparently defined like so in
|
@DataTriny To answer your question about how I found out, I was exposed to tabtip.exe while I was on the Windows accessibility team at Microsoft. I never studied that particular program's code, but I had general awareness about what it does, and that it makes some use of accessibility APIs. Then yesterday, I noticed that the example program was getting WM_GETOBJECT messages even when I wasn't running a screen reader (I have enough sight to read the screen up close), and, remembering that my laptop has a touchscreen, I suspected tabtip.exe. |
I finally figured out what was causing this problem when I discovered that the window was receiving a |
Steps to reproduce:
hello_world
example program underplatforms/windows/examples
.Expected result: NVDA should say "Hello world window". This indicates that the UIA provider is properly exposed and NVDA is recognizing the window as a UIA window.
Observed: NVDA says "Hello world". This is what it says for a window for which it can't detect a UIA provider. However, if you reverse the order of the steps (start the program and then start NVDA), it says "Hello world window", indicating that it detected the UIA provider.
My analysis: I know that NVDA is behaving as it is because when it calls
UiaHasServerSideProvider
on the newly created window, that function is returning false. But I don't know whyUiaHasServerSideProvider
is returning false for that window. The window procedure handlesWM_GETOBJECT
by creating the UIA provider and passing that along with theWPARAM
andLPARAM
toUiaReturnRawElementProvider
. It doesn't do anything else with theWPARAM
andLPARAM
, since I want to let UIA Core handle both UIA and MSAA requests. So I guess there's some kind of race condition where, immediately after the window is created, UIA Core running in NVDA can't connect to UIA Core running in the example program. FWIW, NVDA is 32-bit x86 while the example program is x64.I have a workaround. If I call
CoInitializeEx
withCOINIT_MULTITHREADED
at the start of the program, then this unexpected behavior doesn't happen. But if I either omit a call toCoInitializeEx
or call it withCOINIT_APARTMENTTHREADED
, then I get this problem. So for now, I can just useCOINIT_MULTITHREADED
, but since AccessKit is a library aiming for wide adoption, I want it to work in any of these cases if possible. Also, it doesn't seem to matter whether I useProviderOptions_UseComThreading
or not, though I'd prefer not to.I've reported this to one of my former colleagues at Microsoft and his manager, since this looks like it might be a bug in UIA Core.
The text was updated successfully, but these errors were encountered: