From 7a03f75ee9b905bd796d4d6a02f7cff3d5b1e472 Mon Sep 17 00:00:00 2001 From: Bill Dengler Date: Fri, 4 Sep 2020 16:59:38 -0400 Subject: [PATCH] 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`. --- .../UiaTextRangeTests.cpp | 26 ++++++++++++++++++- src/types/UiaTextRangeBase.cpp | 14 ++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/interactivity/win32/ut_interactivity_win32/UiaTextRangeTests.cpp b/src/interactivity/win32/ut_interactivity_win32/UiaTextRangeTests.cpp index 4101aebfe09..414d3f52e68 100644 --- a/src/interactivity/win32/ut_interactivity_win32/UiaTextRangeTests.cpp +++ b/src/interactivity/win32/ut_interactivity_win32/UiaTextRangeTests.cpp @@ -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 diff --git a/src/types/UiaTextRangeBase.cpp b/src/types/UiaTextRangeBase.cpp index 1de46851558..506b25cb104 100644 --- a/src/types/UiaTextRangeBase.cpp +++ b/src/types/UiaTextRangeBase.cpp @@ -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);