diff --git a/src/paths.rs b/src/paths.rs index f714964..7761758 100644 --- a/src/paths.rs +++ b/src/paths.rs @@ -1,4 +1,6 @@ -use crate::{constants::CMD_NAME, xdg::XDG}; +use anyhow::bail; + +use crate::{constants::CMD_NAME, util::steam_library_folder::SteamLibraryFolder, xdg::XDG}; use std::{ env, fs::create_dir_all, @@ -83,9 +85,24 @@ pub fn get_exec_prefix() -> PathBuf { .into() } -pub fn get_steamvr_bin_dir_path() -> PathBuf { - XDG.get_data_home() - .join("Steam/steamapps/common/SteamVR/bin/linux64") +const STEAMVR_STEAM_APPID: u32 = 250820; + +fn get_steamvr_base_dir() -> anyhow::Result { + SteamLibraryFolder::get_folders()? + .into_iter() + .find(|(_, lf)| lf.apps.contains_key(&STEAMVR_STEAM_APPID)) + .map(|(_, lf)| PathBuf::from(lf.path)) + .ok_or(anyhow::Error::msg( + "Could not find SteamVR in Steam libraryfolders.vdf", + )) +} + +pub fn get_steamvr_bin_dir_path() -> anyhow::Result { + let res = get_steamvr_base_dir()?.join("bin/linux64"); + if !res.is_dir() { + bail!("SteamVR bin dir `{}` does not exist", res.to_string_lossy()); + } + Ok(res) } pub fn get_plugins_dir() -> PathBuf { diff --git a/src/ui/steamvr_calibration_box.rs b/src/ui/steamvr_calibration_box.rs index f2f9c7d..beae630 100644 --- a/src/ui/steamvr_calibration_box.rs +++ b/src/ui/steamvr_calibration_box.rs @@ -10,7 +10,6 @@ use relm4::{ }; use std::{ collections::{HashMap, VecDeque}, - path::Path, thread::sleep, time::Duration, }; @@ -145,51 +144,55 @@ impl SimpleComponent for SteamVrCalibrationBox { } Self::Input::RunCalibration => { self.set_calibration_result(None); - let steamvr_bin_dir = get_steamvr_bin_dir_path().to_string_lossy().to_string(); - if !Path::new(&steamvr_bin_dir).is_dir() { - self.set_calibration_success(false); - self.set_calibration_result(Some("SteamVR not found".into())); - return; - } - let mut env: HashMap = HashMap::new(); - env.insert("LD_LIBRARY_PATH".into(), steamvr_bin_dir.clone()); - let vrcmd = format!("{steamvr_bin_dir}/vrcmd"); - let server_worker = { - let mut jobs: VecDeque = VecDeque::new(); - jobs.push_back(WorkerJob::new_cmd( - Some(env.clone()), - vrcmd.clone(), - Some(vec!["--pollposes".into()]), - )); - JobWorker::new(jobs, sender.input_sender(), |msg| match msg { - JobWorkerOut::Log(_) => Self::Input::NoOp, - JobWorkerOut::Exit(code) => Self::Input::OnServerWorkerExit(code), - }) - }; - let cal_worker = { - let mut jobs: VecDeque = VecDeque::new(); - jobs.push_back(WorkerJob::new_func(Box::new(move || { - sleep(Duration::from_secs(2)); - FuncWorkerOut { - success: true, - out: vec![], - } - }))); - jobs.push_back(WorkerJob::new_cmd( - Some(env), - vrcmd, - Some(vec!["--resetroomsetup".into()]), - )); - JobWorker::new(jobs, sender.input_sender(), |msg| match msg { - JobWorkerOut::Log(_) => Self::Input::NoOp, - JobWorkerOut::Exit(code) => Self::Input::OnCalWorkerExit(code), - }) - }; + match get_steamvr_bin_dir_path() { + Err(e) => { + error!("could not get SteamVR bin dir: {e}"); + self.set_calibration_success(false); + self.set_calibration_result(Some("SteamVR not found".into())); + } + Ok(bin_dir_p) => { + let steamvr_bin_dir = bin_dir_p.to_string_lossy().to_string(); + let mut env: HashMap = HashMap::new(); + env.insert("LD_LIBRARY_PATH".into(), steamvr_bin_dir.clone()); + let vrcmd = format!("{steamvr_bin_dir}/vrcmd"); + let server_worker = { + let mut jobs: VecDeque = VecDeque::new(); + jobs.push_back(WorkerJob::new_cmd( + Some(env.clone()), + vrcmd.clone(), + Some(vec!["--pollposes".into()]), + )); + JobWorker::new(jobs, sender.input_sender(), |msg| match msg { + JobWorkerOut::Log(_) => Self::Input::NoOp, + JobWorkerOut::Exit(code) => Self::Input::OnServerWorkerExit(code), + }) + }; + let cal_worker = { + let mut jobs: VecDeque = VecDeque::new(); + jobs.push_back(WorkerJob::new_func(Box::new(move || { + sleep(Duration::from_secs(2)); + FuncWorkerOut { + success: true, + out: vec![], + } + }))); + jobs.push_back(WorkerJob::new_cmd( + Some(env), + vrcmd, + Some(vec!["--resetroomsetup".into()]), + )); + JobWorker::new(jobs, sender.input_sender(), |msg| match msg { + JobWorkerOut::Log(_) => Self::Input::NoOp, + JobWorkerOut::Exit(code) => Self::Input::OnCalWorkerExit(code), + }) + }; - server_worker.start(); - cal_worker.start(); - self.server_worker = Some(server_worker); - self.calibration_worker = Some(cal_worker); + server_worker.start(); + cal_worker.start(); + self.server_worker = Some(server_worker); + self.calibration_worker = Some(cal_worker); + } + }; } Self::Input::OnServerWorkerExit(code) => { if code != 0 {