Ensure states/roles are unique#13414
Conversation
michaelDCurran
left a comment
There was a problem hiding this comment.
The change looks okay, though as discussed, we can not be fully confident that there is no code in the wild that relied on the exact value of these constants.
I also feel that the PR description needs a slight correction:
NVDA roles and states were never originally written such that their values mirrored MSAA roles and states. Rather, NVDA states were defined as powers of 2 because the original states property on NVDAObjects returned 1 or more state values bit-wise ored together. But for a long time now the states property has returned a Python set, so this is no longer a necessary restriction.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as resolved.
This comment was marked as resolved.
Values in the State/Role enums are getting large, it is easy for a developer to accidentally duplicate a value. NVDA states were initially defined as powers of 2 so that the `states` property on `NVDAObject` could return multiple (bit flag) values within an integer. However, for a long time now, the states property returns a Python set. The values no longer have to set a unique bit. Also, now that Role/State constants are enums, we no longer depend on manually matching values printed in logging with the values in the file (because enums are named).
7323d1f to
9d1023c
Compare
For information, I have already seen add-ons or scratchpad scripts (globalPlugins/appModules) with hard-coded numeric values of role or state. Since NVDA 2022.1 is an API-breaking release, it should not be a problem however and it's up to add-on authors to update their code. |
@CyrilleB79 you are correct. Our only reservation is how late this is in the dev-cycle.
Do you have any examples I could look at? |
|
@feerrenrut I'm happy with the pr description now. |
Yes: at least in Thunderbird+ 3.3 downloadable on this page. This is a popular extension in French community. |
This comment was marked as resolved.
This comment was marked as resolved.
|
Just to clarify my previous comment: I have seen examples where numeric values were used for role or state. However, I do not remember any situation where bitwise operations were performed among them. Probably that's what you were looking for actually. Sorry for the confusion. |
|
Thanks @seanbudd, I'll update the description with that suggestion. Thanks for the examples @CyrilleB79, I was just curious about how the values are used, and how widely. I'll have a look at that add-on. If it will be difficult for add-ons to update, we may reconsider this PR. If there is any technical reason why hardcoded values would be used rather than importing, or difficulty with development using imported values, that would also be good to know. |
|
Cc @abdel792 if you may comment on the use of numeric values for roles in Thunderbird+ add-on. |
|
@CyrilleB79 I've had a look through that add-on ( |
|
@michaelDCurran and @seanbudd, if you both agree, I think we can merge this in to get wider testing / feedback, accepting the risk of having to revert. |
|
Merging this is fine with me.
|
You can have a look at the |
|
Thanks @CyrilleB79, I see. At least this should be a direct replacement with the enum. |
|
This pr causes issue #13457 |
|
While not an ideal solution, using IntFlag for states should cause these to match again. However, we run the risk of them breaking again unless we can figure out how to synchronise these. |
|
Has it been considered to no longer expose these states from the inprocess code as an long - rather add boolean's to the structure for each state? That seems much safer than relying on an auto-generated enum value. |
|
This should be fixed via #13465 @lukaszgo1, it's a potential option, but has it's own downs sides:
In #13465 I have separated the ABI for excel in-proc from general NVDA States, similar to IAccessible and IAccessible2 states, there is now an excelCellStates mapping to NVDA States. This moves the coupling from controlTypes and excel in-proc code, to excel in-proc and excel python code. |
|
@feerrenrut
That should not be an issue - nVDA stores the in process libraries in the version specific directory so each time new build of NVDA is started the new set of libraries is freshly injected into Excel.
Isn't it the same for the solution that you've proposed in #13465? A new state for an Excell cell still requires a new state being added into enum both in Python and in C++. Using booleans rather than Bitwise operations would result in much more readable code. Obviously they still should be decoupled from the actual values of an enum members in |
|
Hi @CyrilleB79 and all, In fact, the Thunderbird+ add-on has been around for a long time, and several people contributed to it. I'd proposed my help to Pierre-Louis only for some additional features he needed. The use of numeric values for roles had been introduced by other contributors, who preceded my work on this addon. I didn't modify their code, although I could see there was some mismatch with the coding rules for NVDA. There were far too many instructions to correct, and I didn't have too much free time. If you open Windows Notepad and then NVDA's Python console, a statement like the following should show True:
I think that's what you want to talk about? Thanks. |
Yes, that is theoretically true. In practice we find that the library doesn't always get unloaded. The only way to remedy this is to restart the application, or sometimes it even requires logging off. It's really important that python and c++ agree on the layout of the struct, adding booleans for each state makes that less likely. A mistake when adding a new state could result in crashes or some other adjacent field being very wrong, vs a mistake when adding a bit field value means that only the newly added state is not reported. Given this is the thing the developer is working on they should notice a missing state, but might not notice that all of a sudden the comment is no longer reported when the cell has a formula (as an example).
Yes, my point there was that it is the same. IE no advantage either way in terms of the number of things the developer has to remember.
This might be a matter of style / personal preference, consider the code that has to convert the booleans into a list of states: cellInfo=self.excelCellInfo
cellStates = []
if cellInfo.hasFormula:
cellStates.append(controlTypes.HASFORMULA)
elif cellInfo.hasComment:
cellStates.append(controlTypes.HASCOMMENT)
elif ... |
Summary: With UIA for Excel disabled, navigating to a cell with a formula and "has formula" was not reported. This is a regression caused by #13414 In `NVDAHelper/remote/excel.cpp` the properties of a cell were determined and bits were set on the `state` member of a `EXCEL_CELLINFO` struct. The constants used for this are in `NVDAHelper/remote/excel/Constants.h`, see the `NVSTATE_*` constants, previously these matched the `controlTypes.State` constants directly. Description of change: Rather than couple the excel implementation to the controlTypes implementation, these constants have been converted to enums (both in C++ and in Python), renumbered, and an explicit mapping to the corresponding `controlTypes.State` enum has been created. Fixes #13457
… (PR #13603) Related to #13588 Based on conversation in https://nvda-addons.groups.io/g/nvda-addons/topic/90329930 Summary of the issue: - Some add-ons depend on the legacy values of controlTypes.Roles (and possibly controlTypes.States) - These were removed in commit d4586a5 via PR #13414. - While HAS_ARIA_DETAILS isn't used internally, add-ons may indirectly depend on it. This enum value was initially added to controlTypes.py in commit d6787b8 and removed in aa351c5 which introduced a replacement approach: Use instead NVDAObject.hasDetails Description of change: Restore the values using more developer friendly definitions, use unit tests to ensure values match and can be constructed from and compared with integer values, or constructed from the enum value name.
Note this is an API breaking change.
Link to issue number:
None
Summary of the issue:
Values in the State/Role enums are getting large, it is easy for a developer to accidentally duplicate a value.
NVDA states were initially defined as powers of 2 so that the
statesproperty onNVDAObjectcould return multiple (bit flag) values within an integer. However, for a long time now, the states property returns a Python set. The values no longer have to set a unique bit.Also, now that Role/State constants are enums, we no longer depend on manually
matching values printed in logging with the values in the file (because
enums are named).
Description of how this pull request fixes the issue:
unique.auto.Testing strategy:
System tests
Usage on alpha
Known issues with pull request:
This not strictly a required API breaking change, however add-ons should not be relying on the explicit values.
Change log entries:
For Developers
Code Review Checklist: