Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion src-tauri/src/overlay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,10 @@ fn show_overlay_state_on_main(app_handle: &AppHandle, state: &str) {
// Size the overlay for this state (compact vs. streaming), then position it.
let (width, height) = overlay_dimensions(state);
if let Some(overlay_window) = app_handle.get_webview_window("recording_overlay") {
// Invalidate any delayed hide still in flight from a previous session
// (see `hide_recording_overlay`).
OVERLAY_SHOW_GENERATION.fetch_add(1, Ordering::SeqCst);

#[cfg(target_os = "linux")]
let shown_with_layer_shell = if LAYER_SHELL_ACTIVE.load(Ordering::SeqCst) {
let position = settings::get_settings(app_handle).overlay_position;
Expand Down Expand Up @@ -666,17 +670,33 @@ fn update_overlay_position_on_main(app_handle: &AppHandle) {
}
}

/// Generation counter bumped every time the overlay is shown. The delayed
/// `hide()` below only unmaps the window if no show happened after it was
/// scheduled, so a hide left over from a finished transcription can never
/// take down the overlay of a session that started in the meantime — e.g. a
/// press the coordinator remembered while the pipeline was busy and started
/// the instant it drained, well inside the 300 ms hide delay.
static OVERLAY_SHOW_GENERATION: AtomicU64 = AtomicU64::new(0);

/// Hides the recording overlay window with fade-out animation
pub fn hide_recording_overlay(app_handle: &AppHandle) {
// Always hide the overlay regardless of settings - if setting was changed while recording,
// we still want to hide it properly
if let Some(overlay_window) = app_handle.get_webview_window("recording_overlay") {
// Snapshot before doing anything observable, so any show that lands
// after this point invalidates the delayed hide below.
let scheduled_at = OVERLAY_SHOW_GENERATION.load(Ordering::SeqCst);
// Emit event to trigger fade-out animation
let _ = overlay_window.emit("hide-overlay", ());
// Hide the window after a short delay to allow animation to complete
// Hide the window after a short delay to allow animation to complete,
// unless a newer session has shown the overlay again by then.
let window_clone = overlay_window.clone();
std::thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_millis(300));
if OVERLAY_SHOW_GENERATION.load(Ordering::SeqCst) != scheduled_at {
log::debug!("Skipping stale overlay hide: a newer session is showing the overlay");
return;
}
let _ = window_clone.hide();
});
}
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/src/signal_handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use std::thread;
/// Used by signal handlers, CLI flags, and any other external trigger.
pub fn send_transcription_input(app: &AppHandle, binding_id: &str, source: &str) {
if let Some(c) = app.try_state::<TranscriptionCoordinator>() {
c.send_input(binding_id, source, true, false);
c.send_external_input(binding_id, source);
} else {
warn!("TranscriptionCoordinator not initialized");
}
Expand Down
Loading