From 76211757ecce73cba981bdf6704954b25a100a8c Mon Sep 17 00:00:00 2001 From: akbash Date: Tue, 18 Aug 2026 00:11:20 +0300 Subject: fix: reap ctrl-click url openers (#2906) * fix: reap ctrl-click url openers refs #2903 * fix: scope linux opener test import refs #2903 * test: isolate url opener regression refs #2903 --------- Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com> --- src/app/input/mod.rs | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) (limited to 'src/app/input/mod.rs') diff --git a/src/app/input/mod.rs b/src/app/input/mod.rs index 45124107..597d9296 100644 --- a/src/app/input/mod.rs +++ b/src/app/input/mod.rs @@ -566,6 +566,15 @@ impl App { &mut self, source_id: super::InputSourceId, mouse: MouseEvent, + ) -> bool { + self.handle_modified_url_click_with(source_id, mouse, crate::platform::open_url) + } + + fn handle_modified_url_click_with( + &mut self, + source_id: super::InputSourceId, + mouse: MouseEvent, + open_url: impl FnOnce(&str) -> std::io::Result>, ) -> bool { if self.state.mode != Mode::Terminal || !matches!(mouse.kind, MouseEventKind::Down(MouseButton::Left)) @@ -595,8 +604,12 @@ impl App { tracing::warn!(err = %err, url = %url, "failed to invoke plugin link handler"); } } - if let Err(err) = crate::platform::open_url(&url) { - tracing::warn!(err = %err, url = %url, "failed to open pane URL"); + match open_url(&url) { + Ok(Some(child)) => self.detached_process_children.push(child), + Ok(None) => {} + Err(err) => { + tracing::warn!(err = %err, url = %url, "failed to open pane URL"); + } } true } @@ -897,6 +910,18 @@ fn wait_for_file(path: &std::path::Path) -> String { panic!("timed out waiting for {}", path.display()); } +#[cfg(test)] +#[cfg(unix)] +async fn wait_for_detached_process_reap(app: &mut App, pid: u32) -> bool { + let deadline = tokio::time::Instant::now() + std::time::Duration::from_secs(2); + while crate::platform::process_exists(pid) && tokio::time::Instant::now() < deadline { + app.reap_finished_detached_processes(); + tokio::time::sleep(std::time::Duration::from_millis(20)).await; + } + app.reap_finished_detached_processes(); + !crate::platform::process_exists(pid) +} + #[cfg(test)] mod tests { use super::*; -- cgit v1.2.3