From af4740d5adbff62aa99366185aac371e3d506636 Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Fri, 17 Oct 2025 21:26:13 -0400 Subject: [PATCH] Various minor fixes in preparation for new release. --- .../onScreenUpdate/65000-progress_detector.py | 33 +++++++++++-------- .../commands/onScreenUpdate/70000-incoming.py | 15 +++++---- src/fenrirscreenreader/core/outputManager.py | 5 +-- src/fenrirscreenreader/fenrirVersion.py | 4 +-- 4 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/fenrirscreenreader/commands/onScreenUpdate/65000-progress_detector.py b/src/fenrirscreenreader/commands/onScreenUpdate/65000-progress_detector.py index d6f12f01..4f5d3010 100644 --- a/src/fenrirscreenreader/commands/onScreenUpdate/65000-progress_detector.py +++ b/src/fenrirscreenreader/commands/onScreenUpdate/65000-progress_detector.py @@ -66,12 +66,18 @@ class command: # Check if delta is too large (screen change) vs small incremental # updates - delta_length = len(self.env["screen"]["new_delta"]) + delta_text = self.env["screen"]["new_delta"] + delta_length = len(delta_text) if ( delta_length > 200 ): # Allow longer progress lines like Claude Code's status return False + # If delta contains newlines and is substantial, let incoming handler + # deal with it to avoid interfering with multi-line text output + if '\n' in delta_text and delta_length > 50: + return False + # Check if current line looks like a prompt - progress unlikely during # prompts if self.is_current_line_prompt(): @@ -270,7 +276,7 @@ class command: self.env["commandBuffer"]["lastProgressTime"] = current_time return - # Pattern 5: Braille progress indicators + # Pattern 5: Braille spinner indicators braille_match = re.search(r'[⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏⡿⣟⣯⣷⣾⣽⣻⢿]', text) if braille_match: if current_time - self.env["commandBuffer"]["lastProgressTime"] >= 1.0: @@ -286,19 +292,12 @@ class command: self.env["commandBuffer"]["lastProgressTime"] = current_time return - # Pattern 7: Moon phase progress indicators + # Pattern 7: Moon phase spinner indicators moon_match = re.search(r'[🌑🌒🌓🌔🌕🌖🌗🌘]', text) if moon_match: - moon_phases = { - '🌑': 0, '🌒': 12.5, '🌓': 25, '🌔': 37.5, - '🌕': 50, '🌖': 62.5, '🌗': 75, '🌘': 87.5 - } - moon_char = moon_match.group(0) - if moon_char in moon_phases: - percentage = moon_phases[moon_char] - if percentage != self.env["commandBuffer"]["lastProgressValue"]: - self.play_progress_tone(percentage) - self.env["commandBuffer"]["lastProgressValue"] = percentage + if current_time - self.env["commandBuffer"]["lastProgressTime"] >= 1.0: + self.play_activity_beep() + self.env["commandBuffer"]["lastProgressTime"] = current_time return # Pattern 8: Thinking/processing with timing (🔄 Thinking... 23s) @@ -320,6 +319,14 @@ class command: self.env["commandBuffer"]["lastProgressTime"] = current_time return + # Pattern 9: Half-circle/circle progress indicators (◐ ◓ ◒ ◑) + circle_match = re.search(r'[◐◓◒◑]', text) + if circle_match: + if current_time - self.env["commandBuffer"]["lastProgressTime"] >= 1.0: + self.play_activity_beep() + self.env["commandBuffer"]["lastProgressTime"] = current_time + return + def play_progress_tone(self, percentage): # Map 0-100% to 400-1200Hz frequency range frequency = 400 + (percentage * 8) diff --git a/src/fenrirscreenreader/commands/onScreenUpdate/70000-incoming.py b/src/fenrirscreenreader/commands/onScreenUpdate/70000-incoming.py index 40397ce7..2d32a17d 100644 --- a/src/fenrirscreenreader/commands/onScreenUpdate/70000-incoming.py +++ b/src/fenrirscreenreader/commands/onScreenUpdate/70000-incoming.py @@ -25,18 +25,19 @@ class command: """Check if this delta was already handled by tab completion to avoid duplicates""" if "tabCompletion" not in self.env["commandBuffer"]: return False - + tab_state = self.env["commandBuffer"]["tabCompletion"] - + # Check if this exact delta was processed recently by tab completion - if (tab_state.get("lastProcessedDelta") == delta_text and + if (tab_state.get("lastProcessedDelta") == delta_text and tab_state.get("lastProcessedTime")): - - # Only suppress if processed within the last 100ms to avoid stale suppression + + # Only suppress if processed within the last 50ms to avoid stale suppression + # Reduced from 100ms to minimize false positives with rapid multi-line updates time_since_processed = time.time() - tab_state["lastProcessedTime"] - if time_since_processed <= 0.1: + if time_since_processed <= 0.05: return True - + return False def run(self): diff --git a/src/fenrirscreenreader/core/outputManager.py b/src/fenrirscreenreader/core/outputManager.py index 68e5690a..be1a43f6 100644 --- a/src/fenrirscreenreader/core/outputManager.py +++ b/src/fenrirscreenreader/core/outputManager.py @@ -71,7 +71,7 @@ class OutputManager: to_announce_capital = False self.last_echo = text self.speak_text( - text, interrupt, ignore_punctuation, to_announce_capital + text, interrupt, ignore_punctuation, to_announce_capital, flush ) def get_last_echo(self): @@ -104,6 +104,7 @@ class OutputManager: interrupt=True, ignore_punctuation=False, announce_capital=False, + flush=True, ): if not self.env["runtime"]["SettingsManager"].get_setting_as_bool( "speech", "enabled" @@ -119,7 +120,7 @@ class OutputManager: debug.DebugLevel.ERROR, ) return - if interrupt: + if interrupt or flush: self.interrupt_output() try: self.env["runtime"]["SpeechDriver"].set_language( diff --git a/src/fenrirscreenreader/fenrirVersion.py b/src/fenrirscreenreader/fenrirVersion.py index 247e1810..b0cf2bc9 100644 --- a/src/fenrirscreenreader/fenrirVersion.py +++ b/src/fenrirscreenreader/fenrirVersion.py @@ -4,5 +4,5 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributors. -version = "2025.09.26" -code_name = "master" +version = "2025.10.17" +code_name = "testing"