Repository: nvaccess/nvda

Issue:
New braille context presentation modes sometimes break panning backwards
### Steps to reproduce:

1. Open the NVDA Log Viewer (NVDA+n, T, V).
2. Pan braille backwards.

NB: The context presentation mode in use doesn't matter.

### Expected behavior:

The braille dispay shows "NVDA Log Viewer multi line ro edt".

### Actual behavior:

Nothing happens.

### System configuration:

NVDA version: master-14282,1ce6e944
I traced this to commit 1785d5f32 (merged #7236).

### Other questions:

So far reproduced in wx edit controls, Notepad, WordPad, Word, Notepad++.

CC @leonardder 


Discussion:
i can comfirm that using the latest snapshot and handytech braille wave display without bluetooth from source.
@leonardder 
Ugh, let me investigate this either today or tomorrow, but as soon as 
possible anyhow.


Resolving patch:
diff --git a/source/braille.py b/source/braille.py
--- a/source/braille.py
+++ b/source/braille.py
@@ -1132,7 +1132,7 @@ def _set_windowEndPos(self, endPos):
 		# Loop through the currently displayed regions in reverse order
 		# If focusToHardLeft is set for one of the regions, the display shouldn't scroll further back than the start of that region
 		for region, regionStart, regionEnd in reversed(list(self.regionsWithPositions)):
-			if regionStart<=endPos:
+			if regionStart<endPos:
 				if region.focusToHardLeft:
 					# Only scroll to the start of this region.
 					restrictPos = regionStart


Test patch:
diff --git a/tests/unit/test_braille.py b/tests/unit/test_braille.py
--- a/tests/unit/test_braille.py
+++ b/tests/unit/test_braille.py
@@ -55,6 +55,11 @@ def test_scrollOnly(self):
 		self.assertEqual(braille.handler.buffer.windowEndPos,self.regionsWithPositions[2].end)
 		# This also means that the window start position is equal to the start position of the 3rd region
 		self.assertEqual(braille.handler.buffer.windowStartPos,self.regionsWithPositions[2].start)
+		# Scroll the braille window back
+		braille.handler.scrollBack()
+		# Both the focus object and its parents should be visible
+		self.assertEqual(braille.handler.buffer.windowEndPos,self.regionsWithPositions[2].end)
+		self.assertEqual(braille.handler.buffer.windowStartPos,0)
 
 	def test_changedContext(self):
 		"""Test for the case where the focus object as well as ancestry differences should be visible on the display"""
@@ -71,6 +76,11 @@ def test_changedContext(self):
 		# Only the focus object should be visible now, equivalent to scroll only
 		self.assertEqual(braille.handler.buffer.windowEndPos,self.regionsWithPositions[2].end)
 		self.assertEqual(braille.handler.buffer.windowStartPos,self.regionsWithPositions[2].start)
+		# Scroll the braille window back
+		braille.handler.scrollBack()
+		# Both the focus object and its parents should be visible
+		self.assertEqual(braille.handler.buffer.windowEndPos,self.regionsWithPositions[2].end)
+		self.assertEqual(braille.handler.buffer.windowStartPos,0)
 		# Clean up the cached focus ancestors
 		# specifically, the desktop object (ancestor 0) has no associated region
 		# We will keep the region for the dialog (ancestor 1) and consider the list (ancestor 2) as new for this test