From 5a0ff3f5ccd72d0e8d6ff1112a9e35e01ed7b1b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kr=C3=BCger?= Date: Sun, 9 Nov 2025 06:29:02 +0100 Subject: [PATCH] Add keyboard input handling to allow exiting animations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed issue where Ctrl+C did not work to exit looping animations. In raw terminal mode, signals are not automatically handled, so we need to manually poll for keyboard events. Changes: - Added crossterm event polling in render loop - Check for Ctrl+C, 'q', or ESC key to exit animation - Polls with 0ms timeout to avoid blocking animation frames Users can now exit with: - Ctrl+C - Press 'q' - Press ESC 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/animation/renderer.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/animation/renderer.rs b/src/animation/renderer.rs index 5434b20..798d838 100644 --- a/src/animation/renderer.rs +++ b/src/animation/renderer.rs @@ -2,6 +2,7 @@ use crate::animation::{easing::EasingFunction, effects::Effect, timeline::Timeli use crate::color::{apply, ColorEngine}; use crate::utils::{ansi, ascii::AsciiArt, terminal::TerminalManager}; use anyhow::Result; +use crossterm::event::{self, Event, KeyCode, KeyModifiers}; use tokio::time::sleep; pub struct Renderer<'a> { @@ -37,6 +38,18 @@ impl<'a> Renderer<'a> { loop { let frame_start = std::time::Instant::now(); + // Check for Ctrl+C or 'q' to exit + if event::poll(std::time::Duration::from_millis(0))? { + if let Event::Key(key) = event::read()? { + if key.code == KeyCode::Char('c') && key.modifiers.contains(KeyModifiers::CONTROL) { + break; + } + if key.code == KeyCode::Char('q') || key.code == KeyCode::Esc { + break; + } + } + } + // Calculate progress with easing let linear_progress = timeline.progress(); let eased_progress = self.easing.ease(linear_progress);