Keep degenerate UIA text ranges degenerate after movement (#7530)

Conhost expands UIA text ranges when moved. This means that degenerate
ranges become non-degenerate after movement, leading to odd behaviour
from UIA clients. This PR doesn't expand degenerate ranges, but rather
keeps them degenerate by moving `_end` to the newly-changed `_start`.

Tested in the NVDA Python console (cases with `setEndPoint` and
`compareEndPoints` described in #7342). Also ran the logic by
@michaeldcurran.

Closes #7342

Almost definitely addresses nvaccess/nvda#11288 (although I'll need to
test with my Braille display). Also fixes an issue privately reported to
me by @simon818 with copy/paste from review cursor which originally lead
me to believe the issue was with `moveEndPointByRange`.
This commit is contained in:
Bill Dengler 2020-09-04 16:59:38 -04:00 committed by GitHub
parent 7ab4d45a9d
commit 7a03f75ee9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 3 deletions

View file

@ -583,7 +583,7 @@ class UiaTextRangeTests
{
5,
{4 , 0 + 1},
{5 , 0 + 1}
{4 , 0 + 1}
}
},
@ -694,6 +694,30 @@ class UiaTextRangeTests
{0, bottomRow},
{0, bottomRow}
}
},
MoveTest{
L"can move to a new row when necessary when moving forward",
{ lastColumnIndex, 0 },
{ lastColumnIndex, 0 },
5,
{
5,
{0, 0 + 5},
{0, 0 + 5}
}
},
MoveTest{
L"can move to a new row when necessary when moving backward",
{ 0, 7 },
{ 0, 7 },
-5,
{
-5,
{0, 7 - 5},
{0, 7 - 5}
}
}
};
// clang-format on

View file

@ -579,6 +579,7 @@ IFACEMETHODIMP UiaTextRangeBase::Move(_In_ TextUnit unit,
// We can abstract this movement by moving _start, but disallowing moving to the end of the buffer
constexpr auto endpoint = TextPatternRangeEndpoint::TextPatternRangeEndpoint_Start;
constexpr auto preventBufferEnd = true;
const auto wasDegenerate = IsDegenerate();
try
{
if (unit == TextUnit::TextUnit_Character)
@ -603,8 +604,17 @@ IFACEMETHODIMP UiaTextRangeBase::Move(_In_ TextUnit unit,
// If we actually moved...
if (*pRetVal != 0)
{
// then just expand to get our _end
ExpandToEnclosingUnit(unit);
if (wasDegenerate)
{
// GH#7342: The range was degenerate before the move.
// To keep it that way, move _end to the new _start.
_end = _start;
}
else
{
// then just expand to get our _end
ExpandToEnclosingUnit(unit);
}
}
UiaTracing::TextRange::Move(unit, count, *pRetVal, *this);