vslavik / poedit

Translations editor for Mac, Windows and Unix
https://poedit.net
MIT License
1.71k stars 274 forks source link

Provide static control ids to aid in Screen Reader plugin creation #845

Open LeonarddeR opened 1 month ago

LeonarddeR commented 1 month ago

Many users of the NVDA screen reader use Poedit to translate NVDA. NVDA contains a so called app module for Poedit, which is a plugin that adds some convenience features to aid in translation. For example, you can press several shortcuts to report translator notes, comments, etc. with a single key stroke. Now, the way NVDA is finding out what to read is a bit tricky. It needs to find the proper IAccessibles/windows to read the contents from. It uses the user32 function GetWindowLongW with the GWL_ID parameter to find out the window control id. however, these control ids are not static, they seem to differ between Poedit releases or depending on how many plural forms a language has. I wonder whether something can be done that makes these control ids more static, so NVDA's module can be made more reliable?

cary-rowen commented 1 month ago

There are many projects that need to use Poedit for translation, the ones I am maintaining include, Be My Eyes, NVDA, Wordpress, etc.

It would be great if there was a way to make Poedit more compatible with NVDA's appModule.

vslavik commented 1 month ago

I wonder whether something can be done that makes these control ids more static

I don't think it is feasible - numeric IDs are allocated at runtime (so it's even less stable than you suspected) and manually allocating them statically would be a major PITA.

wxWidgets has a mechanism for assigning names to controls, though, that are IIRC exposed in the a11y interface and not always set by Poedit (resulting in useless names like "window" or "panel"). These can - and should be - set descriptively, would that address the problem or is there more to it that I'm missing?

LeonarddeR commented 1 month ago

I'm afraid changing the names of the controls won't do much good, as they will probably override the window text. Unfortunately, we have few other options with WX because these win32 controls still only exhibit MSA. Implementing UIAutomation parts just for this is probably a bit overkill. It looks like someone found a workaround that works for a majority of people. Therefore I think its safe to close this, since changing these ids its not feasible.

vslavik commented 1 month ago

I'm not a big fan of self-closing issues once opened... FWIW, I'm happy to work with you to improve thing. Step 1 of that is understanding the options, and the needs, though, and my knowledge of how NVDA works is limited.

I think you're right that names would only help with "invisible" container windows.

I don't suppose there's any API that Poedit could communicate this sort of information through to NVDA?

Implementing UIAutomation parts just for this is probably a bit overkill.

My knowledge of it is, while non-zero, pretty limited. I agree doing it for every sub-control is overkill-ish, but if the necessary information could be exposed from, say, just the editing area object as a whole, that would seem reasonable to do to me.

It looks like someone found a workaround that works for a majority of people.

Looking at that PR, the approach is extremely fragile and will be re-broken in the future, it's just a matter of time.

The PR also implies that stable IDs are only needed for a few controls, right? I interpreted you as wanting stable IDs everywhere, but ensuring hard-coded IDs for a few crucial elements should be manageable. Modern wxWidgets has capabilities to at least do it safely.


Note to self: NVDA's Poedit module source code

LeonarddeR commented 1 month ago

I'm not a big fan of self-closing issues once opened... FWIW, I'm happy to work with you to improve thing. Step 1 of that is understanding the options, and the needs, though, and my knowledge of how NVDA works is limited.

I'm sorry, happy to reopen it if you think it is feasible.

I don't suppose there's any API that Poedit could communicate this sort of information through to NVDA?

Implementing UIAutomation parts just for this is probably a bit overkill.

My knowledge of it is, while non-zero, pretty limited. I agree doing it for every sub-control is overkill-ish, but if the necessary information could be exposed from, say, just the editing area object as a whole, that would seem reasonable to do to me.

The easiest way to do this is probably implementing IAccessibleEx for these controls. It allows controls exposed as IAccessible to be enriched with additional UI Automation properties, like Automation ID.

The PR also implies that stable IDs are only needed for a few controls, right? I interpreted you as wanting stable IDs everywhere, but ensuring hard-coded IDs for a few crucial elements should be manageable. Modern wxWidgets has capabilities to at least do it safely.

Yes, we only need the controls as listed in the pr.