diff --git a/qemu-display/src/display.rs b/qemu-display/src/display.rs index 0a2a3b4..fe9e83c 100644 --- a/qemu-display/src/display.rs +++ b/qemu-display/src/display.rs @@ -19,6 +19,32 @@ pub struct Display { } impl Display { + pub async fn lookup( + conn: &Connection, + wait: bool, + name: Option<&str>, + ) -> Result> { + let mut changed = fdo::DBusProxy::new(conn) + .await? + .receive_name_owner_changed() + .await?; + loop { + let list = Display::by_name(&conn).await?; + if let Some(name) = name { + let res = list.get(name); + if res.is_some() { + return Ok(res.cloned()); + } + } else if !list.is_empty() { + return Ok(None); + } + if !wait { + return Err(Error::Failed("Can't find VM".into())); + }; + let _ = changed.next().await; + } + } + pub async fn by_name(conn: &Connection) -> Result> { let mut hm = HashMap::new(); let list = match fdo::DBusProxy::new(conn) diff --git a/qemu-rdw/src/main.rs b/qemu-rdw/src/main.rs index 5c89190..f4c5b18 100644 --- a/qemu-rdw/src/main.rs +++ b/qemu-rdw/src/main.rs @@ -27,6 +27,7 @@ struct AppOptions { vm_name: Option, address: Option, list: bool, + wait: bool, } impl App { @@ -56,6 +57,14 @@ impl App { "List available VM names", None, ); + app.add_main_option( + "wait", + glib::Char(0), + glib::OptionFlags::NONE, + glib::OptionArg::None, + "Wait for display to be available", + None, + ); app.add_main_option( "version", glib::Char(0), @@ -79,6 +88,9 @@ impl App { if opt.lookup_value("list", None).is_some() { app_opt.list = true; } + if opt.lookup_value("wait", None).is_some() { + app_opt.wait = true; + } app_opt.vm_name = opt .lookup_value(&glib::OPTION_REMAINING, None) .and_then(|args| args.child_value(0).get::()); @@ -135,15 +147,11 @@ impl App { app_clone.inner.app.quit(); return; } - let dest = if let Some(name) = opt_clone.borrow().vm_name.as_ref() { - let list = Display::by_name(&conn).await.unwrap(); - Some( - list.get(name) - .unwrap_or_else(|| panic!("Can't find VM name: {}", name)) - .clone(), - ) - } else { - None + let dest = { + let name = opt_clone.borrow().vm_name.clone(); + let wait = opt_clone.borrow().wait; + + Display::lookup(&conn, wait, name.as_deref()).await.unwrap() }; let display = Display::new(&conn, dest.as_ref()).await.unwrap();