diff --git a/src-tauri/src/ambient_light/publisher.rs b/src-tauri/src/ambient_light/publisher.rs index 7c4d200..ef27d47 100644 --- a/src-tauri/src/ambient_light/publisher.rs +++ b/src-tauri/src/ambient_light/publisher.rs @@ -296,8 +296,19 @@ impl LedColorsPublisher { let mut buffer = Vec::::with_capacity(group_size * 3); if group.end > group.start { - for i in group.pos - display_led_offset..group_size + group.pos - display_led_offset - { + // Prevent integer underflow by using saturating subtraction + let start_index = if group.pos >= display_led_offset { + group.pos - display_led_offset + } else { + 0 + }; + let end_index = if group.pos + group_size >= display_led_offset { + group_size + group.pos - display_led_offset + } else { + 0 + }; + + for i in start_index..end_index { if i < colors.len() { let bytes = colors[i].as_bytes(); buffer.append(&mut bytes.to_vec()); @@ -308,10 +319,19 @@ impl LedColorsPublisher { } } } else { - for i in (group.pos - display_led_offset - ..group_size + group.pos - display_led_offset) - .rev() - { + // Prevent integer underflow by using saturating subtraction + let start_index = if group.pos >= display_led_offset { + group.pos - display_led_offset + } else { + 0 + }; + let end_index = if group.pos + group_size >= display_led_offset { + group_size + group.pos - display_led_offset + } else { + 0 + }; + + for i in (start_index..end_index).rev() { if i < colors.len() { let bytes = colors[i].as_bytes(); buffer.append(&mut bytes.to_vec()); diff --git a/src-tauri/src/screen_stream.rs b/src-tauri/src/screen_stream.rs index f98f33c..2bc86a8 100644 --- a/src-tauri/src/screen_stream.rs +++ b/src-tauri/src/screen_stream.rs @@ -143,12 +143,12 @@ impl ScreenStreamManager { let mut last_process_time = Instant::now(); loop { - // Check if stream still has subscribers + // Check if stream still has subscribers and is still running let should_continue = { let streams_lock = streams.read().await; if let Some(stream_state) = streams_lock.get(&display_id) { let state = stream_state.read().await; - !state.subscribers.is_empty() + !state.subscribers.is_empty() && state.is_running } else { false } @@ -191,7 +191,7 @@ impl ScreenStreamManager { let mut state = stream_state.write().await; let changed = state.last_screenshot_hash.map_or(true, |hash| hash != frame_hash); let elapsed_ms = state.last_force_send.elapsed().as_millis(); - let force_send = elapsed_ms > 200; // Force send every 200ms for higher FPS + let force_send = elapsed_ms > 500; // Force send every 500ms for better CPU performance if changed || force_send { state.last_screenshot_hash = Some(frame_hash); @@ -338,8 +338,19 @@ impl ScreenStreamManager { } pub async fn stop_stream(&self, display_id: u32) { + log::info!("Stopping stream for display_id: {}", display_id); let mut streams = self.streams.write().await; + + if let Some(stream_state) = streams.get(&display_id) { + // Mark stream as not running to stop the processing task + let mut state = stream_state.write().await; + state.is_running = false; + log::info!("Marked stream as not running for display_id: {}", display_id); + } + + // Remove the stream from the map streams.remove(&display_id); + log::info!("Removed stream from manager for display_id: {}", display_id); } } @@ -440,6 +451,7 @@ pub async fn handle_websocket_connection( log::info!("Starting stream with config: display_id={}, width={}, height={}", config.display_id, config.target_width, config.target_height); let stream_manager = ScreenStreamManager::global().await; + let display_id_for_cleanup = config.display_id; let mut frame_rx = match stream_manager.start_stream(config).await { Ok(rx) => { log::info!("Screen stream started successfully"); @@ -498,6 +510,11 @@ pub async fn handle_websocket_connection( _ = control_task => {}, } + // Clean up resources when connection ends + log::info!("WebSocket connection ending, cleaning up resources for display_id: {}", display_id_for_cleanup); + let stream_manager = ScreenStreamManager::global().await; + stream_manager.stop_stream(display_id_for_cleanup).await; + log::info!("WebSocket connection handler completed"); Ok(()) } diff --git a/src-tauri/src/screenshot_manager.rs b/src-tauri/src/screenshot_manager.rs index f7033c8..27a59c9 100644 --- a/src-tauri/src/screenshot_manager.rs +++ b/src-tauri/src/screenshot_manager.rs @@ -189,8 +189,8 @@ impl ScreenshotManager { } } - // Sleep for a frame duration (15 FPS for better performance) - sleep(Duration::from_millis(67)).await; + // Sleep for a frame duration (5 FPS for much better CPU performance) + sleep(Duration::from_millis(200)).await; yield_now().await; } }