improved documentation for the diff generation.
This commit is contained in:
@ -120,47 +120,94 @@ class screenManager():
|
||||
self.env['screen']['newDelta'] = ''
|
||||
self.env['runtime']['attributeManager'].resetAttributeDelta()
|
||||
|
||||
# changes on the screen
|
||||
# Diff generation - critical for screen reader functionality
|
||||
# This code detects and categorizes screen content changes to provide appropriate
|
||||
# speech feedback (typing echo vs incoming text vs screen updates)
|
||||
|
||||
# Pre-process screen text for comparison - collapse multiple spaces to single space
|
||||
# This normalization prevents spurious diffs from spacing inconsistencies
|
||||
oldScreenText = re.sub(' +',' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screen']['oldContentText']))
|
||||
newScreenText = re.sub(' +',' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screen']['newContentText']))
|
||||
|
||||
# Track whether this appears to be typing (user input) vs other screen changes
|
||||
typing = False
|
||||
diffList = []
|
||||
|
||||
if (self.env['screen']['oldContentText'] != self.env['screen']['newContentText']):
|
||||
# Special case: Initial screen content (going from empty to populated)
|
||||
# This handles first screen load or TTY switch scenarios
|
||||
if self.env['screen']['newContentText'] != '' and self.env['screen']['oldContentText'] == '':
|
||||
if oldScreenText == '' and\
|
||||
newScreenText != '':
|
||||
self.env['screen']['newDelta'] = newScreenText
|
||||
else:
|
||||
# Calculate byte positions for the current cursor's line in the flat text buffer
|
||||
# Formula: (line_number * columns) + line_number accounts for newlines
|
||||
# Each line contributes 'columns' chars + 1 newline char
|
||||
cursorLineStart = self.env['screen']['newCursor']['y'] * self.env['screen']['columns'] + self.env['screen']['newCursor']['y']
|
||||
cursorLineEnd = cursorLineStart + self.env['screen']['columns']
|
||||
|
||||
# TYPING DETECTION ALGORITHM
|
||||
# Determines if this screen change is likely user typing vs other content changes
|
||||
# All conditions must be met for typing detection:
|
||||
if abs(self.env['screen']['oldCursor']['x'] - self.env['screen']['newCursor']['x']) >= 1 and \
|
||||
self.env['screen']['oldCursor']['y'] == self.env['screen']['newCursor']['y'] and \
|
||||
self.env['screen']['newContentText'][:cursorLineStart] == self.env['screen']['oldContentText'][:cursorLineStart] and \
|
||||
self.env['screen']['newContentText'][cursorLineEnd:] == self.env['screen']['oldContentText'][cursorLineEnd:]:
|
||||
# Condition 1: Cursor moved horizontally by at least 1 position (typical of typing)
|
||||
# Condition 2: Cursor stayed on same line (typing doesn't usually change lines)
|
||||
# Condition 3: Content BEFORE cursor line is unchanged (text above typing area)
|
||||
# Condition 4: Content AFTER cursor line is unchanged (text below typing area)
|
||||
# Together: only the current line changed, cursor moved horizontally = likely typing
|
||||
|
||||
# Optimize diff calculation for typing by focusing on a small window around cursor
|
||||
cursorLineStartOffset = cursorLineStart
|
||||
cursorLineEndOffset = cursorLineEnd
|
||||
|
||||
# Limit analysis window to avoid processing entire long lines
|
||||
# +3 provides safety buffer beyond cursor position to catch edge cases
|
||||
if cursorLineEnd > cursorLineStart + self.env['screen']['newCursor']['x'] + 3:
|
||||
cursorLineEndOffset = cursorLineStart + self.env['screen']['newCursor']['x'] + 3
|
||||
|
||||
# Extract just the relevant text sections for character-level diff
|
||||
oldScreenText = self.env['screen']['oldContentText'][cursorLineStartOffset:cursorLineEndOffset]
|
||||
newScreenText = self.env['screen']['newContentText'][cursorLineStartOffset:cursorLineEndOffset]
|
||||
|
||||
# Character-level diff for typing detection (not line-level)
|
||||
diff = self.differ.compare(oldScreenText, newScreenText)
|
||||
diffList = list(diff)
|
||||
typing = True
|
||||
|
||||
# Validate typing assumption by checking if detected changes match cursor movement
|
||||
tempNewDelta = ''.join(x[2:] for x in diffList if x[0] == '+')
|
||||
if tempNewDelta.strip() != '':
|
||||
if tempNewDelta != ''.join(newScreenText[self.env['screen']['oldCursor']['x']:self.env['screen']['newCursor']['x']].rstrip()):
|
||||
# Compare diff result against expected typing pattern
|
||||
# Expected: characters between old and new cursor positions
|
||||
expectedTyping = ''.join(newScreenText[self.env['screen']['oldCursor']['x']:self.env['screen']['newCursor']['x']].rstrip())
|
||||
|
||||
# If diff doesn't match expected typing pattern, treat as general screen change
|
||||
if tempNewDelta != expectedTyping:
|
||||
# Fallback: treat entire current line as new content
|
||||
diffList = ['+ ' + self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] +'\n']
|
||||
typing = False
|
||||
else:
|
||||
# GENERAL SCREEN CHANGE DETECTION
|
||||
# Not typing - handle as line-by-line content change
|
||||
# This catches: incoming messages, screen updates, application output, etc.
|
||||
diff = self.differ.compare(oldScreenText.split('\n'),\
|
||||
newScreenText.split('\n'))
|
||||
diffList = list(diff)
|
||||
|
||||
# Extract added and removed content from diff results
|
||||
# Output format depends on whether this was detected as typing or general change
|
||||
if not typing:
|
||||
# Line-based changes: join with newlines for proper speech cadence
|
||||
self.env['screen']['newDelta'] = '\n'.join(x[2:] for x in diffList if x[0] == '+')
|
||||
else:
|
||||
# Character-based changes: no newlines for smooth typing echo
|
||||
self.env['screen']['newDelta'] = ''.join(x[2:] for x in diffList if x[0] == '+')
|
||||
|
||||
# Negative delta (removed content) - used for backspace/delete detection
|
||||
self.env['screen']['newNegativeDelta'] = ''.join(x[2:] for x in diffList if x[0] == '-')
|
||||
|
||||
# track highlighted
|
||||
|
Reference in New Issue
Block a user