dkager / tolk

Screen reader abstraction library.
GNU Lesser General Public License v3.0
92 stars 42 forks source link

autodetection of screen readers when the current one becomes unavailable? #4

Closed Neurrone closed 8 years ago

Neurrone commented 8 years ago

Currently, if the current screen reader gets shut down e.g jaws or NVDA, it falls back to SAPI5. When you start another screen reader e.g close jaws, and start NVDA, it doesn't detect that NVDA is running.

  1. Is it possible to do this automatically?
  2. As a workaround, i did a tolk_unload and a tolk_load when the window regains focus after the user switches back. This does detect screen reader changes but there is a noticeable pause when doing so. Is there a faster way of triggering an autodetection?
dkager commented 8 years ago

Good catch! The reason for this is that SAPI is considered a normal screen reader driver and thus once it is detected it sticks. I can think of two solutions:

  1. If it is expected that users are running their own screen reader, disable SAPI support with Tolk_TrySAPI(false).
  2. Whenever SAPI is used but not preferred, try to detect other screen readers first on every call to Tolk_Output. This would of course cause some overhead, but maybe it can be justified. After all, if SAPI is not to be preferred then the detection algorithm should try hard to come up with something better. Also, these detection calls basically boil down to calls to FindWindow, which seems reasonably efficient. What do you think?
Neurrone commented 8 years ago

I like to have SAPI available just in case to support the widest install scenarios possible. For item 2, it depends if there is a noticeable delay. An alternative was to only do a redetection only if the application explicitly asks for it. For example, doing so only when you receive an event that your window has just regained focus would be the most efficient. I tried doing so with tolk_unload and tolk_load but that was really slow; could that be made faster, or be done without reloading?

dkager commented 8 years ago

Hmm, except for (de)initializing COM loading/unloading shouldn't be very slow. I would like to implement solution (2) because SAPI can't really be shut down by the user, so currently once you fall back to SAPI you'll never revert to using a screen reader even if one is launched. I'm hesitant to implement a manual detection function for various reasons, but if the alternative soluton proves problematic it can still be considered.

dkager commented 8 years ago

Would you mind giving today's release a try?

Neurrone commented 8 years ago

Just tried it, and the issue's fixed. There is a bit of lag when i use SAPI5, though that is in all likelihood the lag of using SAPI5 itself and not anything Tolk does. Did you implement every output to sapi5 doing a detection for other screen readers if prefer sapi is false?

Thanks for the quick fix :)

dkager commented 8 years ago

Did you implement every output to sapi5 doing a detection for other screen readers if prefer sapi is false? Yes. If the lag you are experiencing is due to the detection code, it should go away if you set prefer SAPI to true. In that case I'd be curious to know if you are using any DLLs from the lib folder. The other (COM-based) screen readers are detected with a call to FindWindow, which really shouldn't be laggy. But even so, I would like to get an algorithm that doesn't query the activeness on every output. But that's something for another day. :)