From 4a1e1f7ec226cab70ec0645c5cbd45281a4920d2 Mon Sep 17 00:00:00 2001 From: Michael Winter Date: Tue, 17 Mar 2026 17:41:09 +0100 Subject: [PATCH] Simplify quit: use Escape key instead of Ctrl+C - Rollback to original tty-based input - Add Escape key to quit - Remove arrow key detection (use < > keys only) - Simplify the play() method --- src/osc_sender.py | 71 +++++++++++++++++++---------------------------- 1 file changed, 29 insertions(+), 42 deletions(-) diff --git a/src/osc_sender.py b/src/osc_sender.py index 6d6d8fe..a6e74cc 100644 --- a/src/osc_sender.py +++ b/src/osc_sender.py @@ -76,7 +76,7 @@ class OSCSender: print(f"\nFundamental: {self.fundamental} Hz") print(f"Destination: {self.ip}:{self.port}") print(f"{'=' * 50}") - print("← Previous | Next → | Ctrl+C to quit") + print("← Previous | Next → | Escape to quit") def play(self): """Interactive playback with keyboard control.""" @@ -84,48 +84,35 @@ class OSCSender: print("No chords loaded!") return - import select - import signal - - # Send and display first chord - self.send_chord(self.current_index) - self.display_chord(self.current_index) - - def get_key(): - """Get a keypress with timeout. Returns None if no key pressed.""" - if select.select([sys.stdin], [], [], 0.1)[0]: - return sys.stdin.read(1) - return None - - print("\nUse arrow keys to navigate. Press Ctrl+C to quit.") - - # Handle SIGINT explicitly - def handle_sigint(signum, frame): - raise KeyboardInterrupt - - signal.signal(signal.SIGINT, handle_sigint) - try: + import threading + import tty + import termios + import os + + # Send and display first chord + self.send_chord(self.current_index) + self.display_chord(self.current_index) + + def get_key(): + """Get a single keypress.""" + fd = sys.stdin.fileno() + old_settings = termios.tcgetattr(fd) + try: + tty.setraw(sys.stdin.fileno()) + ch = sys.stdin.read(1) + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + return ch + + print("\nUse arrow keys to navigate. Press Escape to quit.") + while True: key = get_key() - if key is None: - continue - # Left arrow - if key == "\x1b": # Escape sequence start - next1 = get_key() - if next1 == "[": - next2 = get_key() - if next2 == "D": # Left arrow - if self.current_index > 0: - self.current_index -= 1 - self.send_chord(self.current_index) - self.display_chord(self.current_index) - elif next2 == "C": # Right arrow - if self.current_index < len(self.chords) - 1: - self.current_index += 1 - self.send_chord(self.current_index) - self.display_chord(self.current_index) + # Escape key - quit + if key == "\x1b": + break # Alternative: use < and > keys elif key == "," or key == "<": @@ -140,9 +127,9 @@ class OSCSender: self.display_chord(self.current_index) except KeyboardInterrupt: - print("\n\nPlayback stopped.") - except Exception: - pass # Clean exit for any other error + pass # Clean exit + + print("\n\nPlayback stopped.") def send_all(self): """Send all chords in sequence (for testing)."""