return valid text for list views in 64-bit mode#8190
Conversation
Item text in a list view can't be retrieved if the returned pointer is 64 bits long. Therefore, return the displayText within the column boundaries instead.
LeonarddeR
left a comment
There was a problem hiding this comment.
Thanks for your pr. I have some suggestions that might make your code a bit more compact and, though a bit trivial, might also improve performance.
| try: | ||
| return self._getColumnContentRaw(targetColumn) | ||
| except ArgumentError: | ||
| # In case that a 64-bit pointer to the text had been returned /rjh |
There was a problem hiding this comment.
Initials are usually not used in comments. If it is required to contact the comments author, we can use git blame for that.
However, it might be good to point at the issue you reported. e.g. # #8175: In case that a 64-bit pointer to the text had been returned, use the display text
| return self._getColumnContentRaw(targetColumn) | ||
| except ArgumentError: | ||
| # In case that a 64-bit pointer to the text had been returned /rjh | ||
| disp = DisplayModelTextInfo(self, 'all') |
There was a problem hiding this comment.
Instead of 'all', use textInfos.POSITION_ALL. However, personally I'd first try a different approach, see below.
| except ArgumentError: | ||
| # In case that a 64-bit pointer to the text had been returned /rjh | ||
| disp = DisplayModelTextInfo(self, 'all') | ||
| x,y,w,h = self._getColumnLocation(column) |
There was a problem hiding this comment.
DisplayModelTextInfo also takes a rectangle as its position argument. E.g.
right = left + width
bottom = top + height
info = displayModel.DisplayModelTextInfo(self, textInfos.Rect(left, top, right, bottom))
| x,y,w,h = self._getColumnLocation(column) | ||
| start = disp._getClosestOffsetFromPoint(x,y) | ||
| end = disp._getClosestOffsetFromPoint(x+w,y+h) | ||
| # Include the whole word, even if it is white space /rjh |
There was a problem hiding this comment.
See my comment above regarding initials vs mentioning the issue number
| start = disp._getClosestOffsetFromPoint(x,y) | ||
| end = disp._getClosestOffsetFromPoint(x+w,y+h) | ||
| # Include the whole word, even if it is white space /rjh | ||
| wordAtEnd = disp._getWordOffsets(end) |
There was a problem hiding this comment.
I don't think that this will be necessary when you create a DisplayModelTextInfo limited to the rectangle of the text.
|
@LeonarddeR |
|
Have you been able to verify whether this approach works as you expect it to?
|
|
It does its work within the boundaries of the general rendering of list views.
That is, NVDA delivers those list views in an explorer-like fashion.
For instance:
The name is composed of the first column, followed by pairs of
header/sub item
I'm not sure if this approach is appropriate for all kinds of list views.
As I've mentioned earlier, Tortoise SVN has an initial and a final
line which does not exactly fit into this scheme since the secondary
entries ("Path" column) would actually belong to the first one
("Action").
However, these are not issues addressed in this pull request since
they are application specific.
With that in mind, I believe the output to be the same as for a 32-bit
application.
We need someone running the 32-bit version of SVN Tortoise in order to
have this confirmed.
The only thing that I can compare to is an ordinary WxWidgets file
browser window (32-bit) that uses sysListView32, and yes, the
behaviour is the same.
We are certainly not worse off with this adaption than before.
Do you have some specific concerns remaining?
…On 18/04/2018, Leonard de Ruijter ***@***.***> wrote:
Have you been able to verify whether this approach works as you expect it
to?
--
You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub:
#8190 (comment)
|
LeonarddeR
left a comment
There was a problem hiding this comment.
This looks ok to me, but I won't do an approve until I first had time to dive more deeply into the SysListView32 code.
| targetColumn = self.parent._columnOrderArray[column - 1] | ||
| try: | ||
| return self._getColumnContentRaw(targetColumn) | ||
| except ArgumentError: |
There was a problem hiding this comment.
Could you please log a debugWarning here? Like:
except ArgumentError as e:
log.debugWarning("Could not retrieve content for column %d, %r" % (column, e))
This might be a bit obnoxious in the log though. May be log.debug would be enough here, I'm not sure. @michaelDCurran might have some thoughts about this.
|
I'm not quite sure about the warnings.
If you update translations, there could be hundreds of those log
entries be chained up.
A lot of overhead and the risk of freezes, don't you think.
…On 18/04/2018, Leonard de Ruijter ***@***.***> wrote:
leonardder commented on this pull request.
This looks ok to me, but I won't do an approve until I first had time to
dive more deeply into the SysListView32 code.
> @@ -333,7 +335,15 @@ def _getColumnContentRaw(self, index):
return buffer.value if buffer else None
def _getColumnContent(self, column):
- return self._getColumnContentRaw(self.parent._columnOrderArray[column -
1])
+ targetColumn = self.parent._columnOrderArray[column - 1]
+ try:
+ return self._getColumnContentRaw(targetColumn)
+ except ArgumentError:
Could you please log a debugWarning here? Like:
```
except ArgumentError as e:
log.debugWarning("Could not retrieve content for column %d, %r" %
(column, e))
```
This might be a bit obnoxious in the log though. May be log.debug would be
enough here, I'm not sure. @michaelDCurran might have some thoughts about
this.
--
You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub:
#8190 (review)
|
Try the native procedure only once for a new list. On failure, store the handle for further checks within this window scope.
|
@LeonarddeR |
|
@Robert-J-H commented on 20 Apr 2018, 07:06 CEST:
Have you considered setting a property on the parent (i.e. the list object itself)? |
|
Yes, I've contemplated that.
I can't see an advantage in that though.
The property would have to be set from this class anyway since it
needs at least one call to _getColumnContentRaw to validate the native
procedure.
I've also tested with Tortoise Git which doesn't suffer from the
64-bit pointer problem.
…On 20/04/2018, Leonard de Ruijter ***@***.***> wrote:
***@***.*****](https://github.com/Robert-J-H) commented on [20 Apr 2018,
07:06
CEST](#8190 (comment)
"2018-04-20T05:06:41Z - Replied by Github Reply Comments"):
> The downside is that I had to add a class variable for that.
Have you considered setting a property on the parent (i.e. the list object
itself)?
--
You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub:
#8190 (comment)
|
|
@Robert-J-H commented on 20 apr. 2018 16:27 CEST:
I guess an advantage would be that we avoid using class properties. I believe that we should avoid using class properties as long as there is an alternative. Just my opinion though. |
|
The parent of a list item may change, it can be a list view, combo
box, grid view, table, whatever.
App developers have no qualms when it comes to mix different control types.
Assigning instance properties to the parent would be confusing (for
us) because at one time it would be there and on other occasions not.
There isn't a prohibition against class properties, is there?
They are legitimate within Python, I should think.
It is worse IMHO to add a parent property dynamically.
But perhaps, you can give me an example how to accomplish this gracefully.
…On 24/04/2018, Leonard de Ruijter ***@***.***> wrote:
***@***.*****](https://github.com/Robert-J-H) commented on [20 apr. 2018
16:27
CEST](#8190 (comment)
"2018-04-20T14:27:53Z - Replied by Github Reply Comments"):
> I can't see an advantage in that though.
I guess an advantage would be that we avoid using class properties. I
believe that we should avoid using class properties as long as there is an
alternative. Just my opinion though.
--
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
#8190 (comment)
|
|
@Robert-J-H commented on 24 apr. 2018 11:30 CEST:
We are now working with SysListView32 items. The items have window class SysListView32 and role oleacc.ROLE_SYSTEM_LISTITEM or oleacc.ROLE_SYSTEM_MENUITEM. I assume their parent is always of NVDAObject class sysListView32.List. I could be wrong though, but I"m quite sure that this is the case. |
Change What's new
|
OK, you've convinced me.
It makes the code cleaner as we now have only True or False.
I've inserted a line in the changes.t2t in the English folder.
Is that the right place?
…On 24/04/2018, Leonard de Ruijter ***@***.***> wrote:
***@***.*****](https://github.com/Robert-J-H) commented on [24 apr. 2018
11:30
CEST](#8190 (comment)
"2018-04-24T09:30:58Z - Replied by Github Reply Comments"):
> The parent of a list item may change, it can be a list view, combo
> box, grid view, table, whatever.
We are now working with SysListView32 items. The items have window class
SysListView32 and role oleacc.ROLE_SYSTEM_LISTITEM or
oleacc.ROLE_SYSTEM_MENUITEM. I assume their parent is always of NVDAObject
class sysListView32.List. I could be wrong though, but I"m quite sure that
this is the case.
--
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
#8190 (comment)
|
|
@Robert-J-H commented on 25 apr. 2018 07:58 CEST:
I'm afraid not. Please feel free to update your initial message in the issue to reflect your change. and revert the changes.t2t change. Updating the changes.t2t as part of pr's causes merge conflicts in most, if not all cases. |
It can cause merge problems with PRs
|
I presume you mean the initial message of this pull request, not the
one in the issue.
Perhaps one should mention the fact about PRs and documentation changes on
https://github.com/nvaccess/nvda/wiki/Contributing
since it purports quite the contrary.
…On 25/04/2018, Leonard de Ruijter ***@***.***> wrote:
***@***.*****](https://github.com/Robert-J-H) commented on [25 apr. 2018
07:58
CEST](#8190 (comment)
"2018-04-25T05:58:08Z - Replied by Github Reply Comments"):
> I've inserted a line in the changes.t2t in the English folder.
> Is that the right place?
I'm afraid not. Please feel free to update your initial message in the issue
to reflect your change. and revert the changes.t2t change. Updating the
changes.t2t as part of pr's causes merge conflicts in most, if not all
cases.
--
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
#8190 (comment)
|
| == Bug Fixes == | ||
| - NVDA no longer fails to read focused controls in the Microsoft Account sign-in screen in Settings after entering an email address. (#7997) | ||
| - NVDA no longer fails to read the page when going back to a previous page in Microsoft Edge. (#7997) | ||
| - NVDA no longer fails to read items in list views within a 64-bit application such as Tortoise SVN. (#8175) |
There was a problem hiding this comment.
Thanks for thinking of editing the changes file. We will actually update the changes file when we merge it to master, to prevent a ton of changes in it causing merge conflicts. Can you back this out for now?
|
The change should actually be reverted with the last commit. |
|
@Robert-J-H commented on 26 apr. 2018 06:54 CEST:
Yes.
Yes, that's also the case. |
LeonarddeR
left a comment
There was a problem hiding this comment.
This looks good now, just one suggestion.
| def _getColumnContent(self, column): | ||
| return self._getColumnContentRaw(self.parent._columnOrderArray[column - 1]) | ||
| res = None | ||
| if self.parent._shouldEnableColumnContentRaw: |
There was a problem hiding this comment.
Just to make sure that this doesn't horribly crash if the parent is not a list and therefore lacks this property, could you change this to:
if getattr(self.parent, "_shouldEnableColumnContentRaw", True):
I agree that this is not very elegant, however a traceback ain't of very much elegance either.
|
On the contrary, it's actually quite elegant.
It guards nicely against some odd usage of list items.
Just tested again by downloading the newest NVDA translations.
The added items are nicely reported when you're in the list.
Note that each added item would produce an error sound without this
pull request.
That is, 951 for this test session.
Thanks for the getattr tip.
…On 30/04/2018, Leonard de Ruijter ***@***.***> wrote:
leonardder approved this pull request.
This looks good now, just one suggestion.
> finally:
winKernel.virtualFreeEx(processHandle,internalText,0,winKernel.MEM_RELEASE)
finally:
winKernel.virtualFreeEx(processHandle,internalItem,0,winKernel.MEM_RELEASE)
return buffer.value if buffer else None
def _getColumnContent(self, column):
- return self._getColumnContentRaw(self.parent._columnOrderArray[column -
1])
+ res = None
+ if self.parent._shouldEnableColumnContentRaw:
Just to make sure that this doesn't horribly crash if the parent is not a
list and therefore lacks this property, could you change this to:
`if getattr(self.parent, "_shouldEnableColumnContentRaw", True):`
I agree that this is not very elegant, however a traceback ain't of very
much elegance either.
--
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
#8190 (review)
|
|
Thanks for changing. @michaelDCurran, could you have an additional run over this code, just to make sure? |
|
Should be fine now, is it not. |
|
I've invested some time in the creation of a branch based on UIA, since this will also fix issues we're having with the retrieval of column locations. However, I"m afraid that that implementation would supersede your pr. |
|
Well, would your implementation solve the issue, that's the main question.
I can't see anything relevant to the problem at the given commit but I
didn't browse the whole history of course.
So, what do you suggest?
…On 29/06/2018, Leonard de Ruijter ***@***.***> wrote:
I've invested some time in the creation of a branch based on UIA, since this
will also fix issues we're having with the retrieval of column locations.
However, I"m afraid that that implementation would supersede your pr.
See https://github.com/babbagecom/nvda/tree/slvUIA
--
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
#8190 (comment)
|
|
@Robert-J-H commented on 29 Jun 2018, 16:24 CEST:
It probably will, as UIA deals with the part that fails on 64 bit systems wehn we do it manually. Still, there are drawbacks, as the UIA implementation seems somewhat slow. |
|
something is not right with this pr. It is showing many many commits on master. And more than 200 files changed. I think this pr needs to be rebased on latest master perhaps. |
|
@michaelDCurran
Hi Mike
Please have another look.
Now, there should be about eight commits and only one file changed.
Best
…On 31/07/2018, Michael Curran ***@***.***> wrote:
something is not right with this pr. It is showing many many commits on
master. And more than 200 files changed. I think this pr needs to be rebased
on latest master perhaps.
--
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
#8190 (comment)
|
|
Hi, As this is an important pull request that was dropped from next to alpha transition, coupled with more reports on 64-bit list view issues, I think it would be best to let someone review this ASAP. But first, please try merging latest master branch so folks can review it with up to date differences. Thanks. |
|
@Robert-J-H can you merge to last master? Or did you do it already? |
|
I have to retest the code.
I'm getting an assertion error now (assert index>0).
Not sure where it is coming from.
…On 05/01/2019, Adriani90 ***@***.***> wrote:
@Robert-J-H can you merge to last master? Or did you do it already?
--
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
#8190 (comment)
|
|
The error has nothing to do with my code.
Tortoise SVN update works after commenting out the assert statement.
Could the person that included it there please review the necessity of it?
Thanks
…On 05/01/2019, Robert Hänggi ***@***.***> wrote:
I have to retest the code.
I'm getting an assertion error now (assert index>0).
Not sure where it is coming from.
On 05/01/2019, Adriani90 ***@***.***> wrote:
> @Robert-J-H can you merge to last master? Or did you do it already?
>
> --
> You are receiving this because you were mentioned.
> Reply to this email directly or view it on GitHub:
> #8190 (comment)
|
|
Hi, Er, @LeonarddeR, assert came from location helper work, so can you shed some light on this? Thanks. |
|
Hi, Robert, are you willing to continue this work? Thanks. |
|
Well, isn't there the question about the assert command pending.
In any case, I've not updated yet to Python 3.
…On 14/08/2019, Joseph Lee ***@***.***> wrote:
Hi,
Robert, are you willing to continue this work?
Thanks.
--
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
#8190 (comment)
|
|
Hi, let’s address the assert question, but in the meantime, I advise porting this work to Python 3 if you can. Thanks.
|
|
hi @Robert-J-H |
|
We are going to close this pr due to inactivity. If I understand correctly, the reason that we could not fetch the column text in these 64-bit lists in the first place is a much deeper issue around pointers and virtual memory, which in some cases have caused application crashes. The higher priority solution I feel is to write some more nvdaInProcUtils functions in nvdaHelperRemote, similar to sysListView32_getGroupInfo which can get the needed info in one cross-proc call, avoiding any VirtualAllocEx / ReadProcessMemory calls etc. |
Link to issue number:
Closes #8175
Summary of the issue:
Item text in a list view can't be retrieved if the returned pointer is 64 bits long.
Example: Tortoise SVN on a 64-bit machine.
Currently, no exception handling is performed for this case.
Description of how this pull request fixes the issue:
The workaround will first attempt to get the item text by the native procedure.
If this fails, the item text will be retrieved from the display text instead.
Care is taken to limit the text to the column width without splitting words if possible.
Testing performed:
Only with Tortoise SVN.
Navigating with arrow keys works fine, so does table navigation.
Known issues with pull request:
Tortoise's list view has some peculiarities itself that aren't addressed with this commit.
For instance, the first and last entries for an update are not related to the headers, thus,
"Update completed at: Revision xxx" will be rendered as
"Update completed at: Path Revision xxx" if announcing of headers is enabled.
Change log entry:
Not changed yet, would probably go under
Bug fixes