use std::thread;
use std::time::Duration;
use super::window::{find_primary_window, window_exists};
const WINDOW_POLL_INTERVAL: Duration = Duration::from_secs(3);
pub(crate) struct WindowWatcher {
stop_tx: std::sync::mpsc::SyncSender<()>,
}
impl WindowWatcher {
pub(crate) fn start(
owner: String,
on_closed: impl Fn() + Send + 'static,
on_identified: impl Fn(String) + Send + 'static,
) -> Self {
let (stop_tx, stop_rx) = std::sync::mpsc::sync_channel::<()>(1);
thread::spawn(move || {
let mut watch_id: Option<u32> = None;
loop {
match stop_rx.recv_timeout(WINDOW_POLL_INTERVAL) {
Ok(_) | Err(std::sync::mpsc::RecvTimeoutError::Disconnected) => return,
Err(std::sync::mpsc::RecvTimeoutError::Timeout) => {}
}
match watch_id {
None => {
if let Some((id, title)) = find_primary_window(&owner) {
on_identified(title);
watch_id = Some(id);
}
}
Some(id) => {
if !window_exists(id) {
on_closed();
return;
}
}
}
}
});
WindowWatcher { stop_tx }
}
}
impl Drop for WindowWatcher {
fn drop(&mut self) {
let _ = self.stop_tx.try_send(());
}
}