Skip to content

Fixing incorrect line reporting in Scintilla controls when line wrapping is on.#9427

Merged
michaelDCurran merged 14 commits into
nvaccess:masterfrom
DataTriny:npp_linewrap_fix
Apr 25, 2019
Merged

Fixing incorrect line reporting in Scintilla controls when line wrapping is on.#9427
michaelDCurran merged 14 commits into
nvaccess:masterfrom
DataTriny:npp_linewrap_fix

Conversation

@DataTriny

Copy link
Copy Markdown
Contributor

Link to issue number:

Fixes #9424.

Summary of the issue:

When navigating inside a Scintilla control with line wrapping enabled, NVDA fails to report the correct line (either when navigating with the keyboard or the mouse).

Description of how this pull request fixes the issue:

In _getLineOffsets:

  • Firstly self.obj.location were not properly deconstructed (top and left were swapped),

  • _getOffsetFromPoint were called with x=0 to retrieve the start point of the line, ignoring the real x coordinate of the Scintilla control,

  • finally, _getOffsetFromPoint were called with x=width to retrieve the endpoint of the line, again ignoring the margin on the left of the control.

Testing performed:

Navigated through a document in Notepad++ with line wrapping enabled. Made sure that it worked with multiple DPI factors, on short lines as well as wrapped ones.

Known issues with pull request:

None

Change log entry:

None

@LeonarddeR LeonarddeR left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for testing this thoroughly, also with several DPI levels. I will push a try build for people to test.

Comment thread source/NVDAObjects/window/scintilla.py Outdated
Comment thread source/NVDAObjects/window/scintilla.py Outdated
Comment thread source/NVDAObjects/window/scintilla.py Outdated

@LeonarddeR LeonarddeR left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, after reading the code again, there is something that seems odd to me.

  1. We're fetching the location of the control, which is in screen coordinates.

  2. Then, when calling self._getOffsetFromPoint, you are adding the result of SCI_POINTYFROMPOSITION to the top of the window. However, according to the Scintilla docs:

    These messages return the x and y display pixel location of text at position pos in the document.

  3. I also noticed that _getOffsetFromPoint throws client coordinates at scintilla, wwhereas _getPointFromOffset doesn't do anything with client to screen conversion. Could you look into this while at it?

@DataTriny

Copy link
Copy Markdown
Contributor Author

@LeonarddeR Regarding your second point: it also sounded strange to me at first, but I tried several combinations and only this one was giving the right results. I claim that it's pixel perfect!

Finally, _getPointFromOffset already returns screen coordinates according to my testing (even if I didn't thought). But I can't figure out where this function gets called so I tested it manually.

@LeonarddeR

LeonarddeR commented Apr 2, 2019 via email

Copy link
Copy Markdown
Collaborator

@DataTriny

Copy link
Copy Markdown
Contributor Author

Hi again @LeonarddeR,

So... SCI_POINTXFROMPOSITION and SCI_POINTYFROMPOSITION unfortunately don't give screen coordinates. I had to add the left and top margin of the control.

Anything else?

…nge objects between NvDA and nvdaHelper inproc code, rather than letting Windows do it, as the previous implementation was failing on Office 2007 because CoInitialize was never called on the RPC worker thread.
Comment thread source/NVDAObjects/window/scintilla.py Outdated
return watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POSITIONFROMPOINT,x,y)

def _getPointFromOffset(self,offset):
location = self.obj.location

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're basically converting client to screen coordinates here, doing it manually. Is there a specific reason why you aren't using clientToScreen here? Does it fail?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Leonard,

You are right! I just forgot about it. This way makes it more explicit.

@LeonarddeR LeonarddeR left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost there

Comment thread source/NVDAObjects/window/scintilla.py Outdated
@@ -193,9 +194,9 @@ def _getLineOffsets(self,offset):
# Lines in Scintilla refer to document lines, not wrapped lines.
# There's no way to retrieve wrapped lines, so use screen coordinates.
y=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POINTYFROMPOSITION,None,offset)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You now can retrieve y with _getPointFromOffset. That gives you an x you won't use, but it at least ensures that you're following an uniform codepath to get screen coordinates from scintilla offsets.

Comment thread source/NVDAObjects/window/scintilla.py Outdated
start = self._getOffsetFromPoint(0,y)
end=self._getOffsetFromPoint(width,y)
location=self.obj.location
start = self._getOffsetFromPoint(location.left, location.top+y)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you use _getPointFromOffset above, this will be:

Suggested change
start = self._getOffsetFromPoint(location.left, location.top+y)
start = self._getOffsetFromPoint(location.left, y)

Comment thread source/NVDAObjects/window/scintilla.py Outdated
end=self._getOffsetFromPoint(width,y)
location=self.obj.location
start = self._getOffsetFromPoint(location.left, location.top+y)
end=self._getOffsetFromPoint(location.right, location.top+y)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When using _getPointFromOffset above, this becomes:

Suggested change
end=self._getOffsetFromPoint(location.right, location.top+y)
end=self._getOffsetFromPoint(location.right, y)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Leonard,

Yes it makes sense. I initially didn't write it like this because I thought a useless call to watchdog.cancellableSendMessage to get the X coordinate wouldn't be accepted. But I don't really know how expensive is that type of call.

@LeonarddeR

LeonarddeR commented Apr 4, 2019 via email

Copy link
Copy Markdown
Collaborator

@LeonarddeR LeonarddeR added the app/scintilla Scintilla edit controls label Apr 5, 2019
@dpy013

dpy013 commented Apr 12, 2019

Copy link
Copy Markdown
Contributor

hi
What is the current status of this PR? I saw that he had been approved.

@LeonarddeR

Copy link
Copy Markdown
Collaborator

I have approved it, but approval from a NV Access member is required before this can be merged.

@ABuffEr

ABuffEr commented Apr 24, 2019

Copy link
Copy Markdown
Contributor

Hi,
I have no role here, but I kindly pray @michaelDCurran to review and merge this pr, or revert the changes that had broken line wrapping support. Using Notepad++ each day for multiple purposes, I must use a stable, without being able to test new features in alpha, very annoying situation.

@michaelDCurran michaelDCurran merged commit 7f41aed into nvaccess:master Apr 25, 2019
@nvaccessAuto nvaccessAuto added this to the 2019.2 milestone Apr 25, 2019
@DataTriny DataTriny deleted the npp_linewrap_fix branch April 26, 2019 09:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app/scintilla Scintilla edit controls bug/regression

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NVDA's support for Scintilla controls. is broken in alpha snapshots, if "line wrap" is enabled in the text editor

6 participants