diff --git a/src/depcheck.rs b/src/depcheck.rs index e94646d..6a137a4 100644 --- a/src/depcheck.rs +++ b/src/depcheck.rs @@ -28,6 +28,54 @@ impl PartialOrd for Dependency { } } +impl Dependency { + pub fn check(&self) -> bool { + for dir in match self.dep_type { + DepType::SharedObject => shared_obj_paths(), + DepType::Executable => env::var("PATH") + .expect("PATH environment variable not defined") + .split(':') + .map(str::to_string) + .collect(), + DepType::Include => include_paths(), + } { + let path_s = &format!("{dir}/{fname}", dir = dir, fname = self.filename); + let path = Path::new(&path_s); + if path.is_file() { + return true; + } + } + false + } + + pub fn check_many(deps: Vec) -> Vec { + deps.iter() + .map(|dep| DependencyCheckResult { + dependency: dep.clone(), + found: dep.check(), + }) + .collect() + } + + pub fn package_name_for_distro(&self, distro: Option<&LinuxDistro>) -> String { + if let Some(distro) = distro { + if let Some(pname) = self + .packages + .iter() + .find(|(k, _)| *k == distro) + .map(|(_, v)| v) + { + return pname.clone(); + } + } + self.name.clone() + } + + pub fn package_name(&self) -> String { + self.package_name_for_distro(LinuxDistro::get().as_ref()) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct DependencyCheckResult { pub dependency: Dependency, @@ -73,40 +121,11 @@ fn include_paths() -> Vec { ] } -pub fn check_dependency(dep: Dependency) -> bool { - for dir in match dep.dep_type { - DepType::SharedObject => shared_obj_paths(), - DepType::Executable => env::var("PATH") - .expect("PATH environment variable not defined") - .split(':') - .map(str::to_string) - .collect(), - DepType::Include => include_paths(), - } { - let path_s = &format!("{dir}/{fname}", dir = dir, fname = dep.filename); - let path = Path::new(&path_s); - if path.is_file() { - return true; - } - } - false -} - -pub fn check_dependencies(deps: Vec) -> Vec { - deps.iter() - .map(|dep| DependencyCheckResult { - dependency: dep.clone(), - found: check_dependency(dep.clone()), - }) - .collect() -} - #[cfg(test)] mod tests { + use super::{DepType, Dependency}; use std::collections::HashMap; - use super::{check_dependency, DepType, Dependency}; - #[test] fn can_find_libc() { let libc_dep = Dependency { @@ -116,19 +135,19 @@ mod tests { packages: HashMap::new(), }; - assert!(check_dependency(libc_dep)); + assert!(libc_dep.check()); } #[test] fn can_find_ls() { - let libc_dep = Dependency { + let ls_dep = Dependency { name: "ls".into(), dep_type: DepType::Executable, filename: ("ls".into()), packages: HashMap::new(), }; - assert!(check_dependency(libc_dep)); + assert!(ls_dep.check()); } #[test] @@ -140,6 +159,6 @@ mod tests { packages: HashMap::new(), }; - assert!(!check_dependency(fake_dep)); + assert!(!fake_dep.check()); } } diff --git a/src/dependencies/basalt_deps.rs b/src/dependencies/basalt_deps.rs index a4499f9..4374cc9 100644 --- a/src/dependencies/basalt_deps.rs +++ b/src/dependencies/basalt_deps.rs @@ -1,5 +1,5 @@ use crate::{ - depcheck::{check_dependencies, DepType, Dependency, DependencyCheckResult}, + depcheck::{DepType, Dependency, DependencyCheckResult}, dependencies::common::{dep_eigen, dep_gpp}, linux_distro::LinuxDistro, }; @@ -134,7 +134,7 @@ fn basalt_deps() -> Vec { } pub fn check_basalt_deps() -> Vec { - check_dependencies(basalt_deps()) + Dependency::check_many(basalt_deps()) } pub fn get_missing_basalt_deps() -> Vec { diff --git a/src/dependencies/common.rs b/src/dependencies/common.rs index 675eb0d..785184e 100644 --- a/src/dependencies/common.rs +++ b/src/dependencies/common.rs @@ -143,3 +143,17 @@ pub fn dep_vulkan_headers() -> Dependency { ]), } } + +pub fn dep_pkexec() -> Dependency { + Dependency { + name: "pkexec".into(), + dep_type: DepType::Executable, + filename: "pkexec".into(), + packages: HashMap::from([ + (LinuxDistro::Arch, "polkit".into()), + (LinuxDistro::Debian, "pkexec".into()), + (LinuxDistro::Fedora, "polkit".into()), + (LinuxDistro::Alpine, "polkit".into()), + ]), + } +} diff --git a/src/dependencies/libsurvive_deps.rs b/src/dependencies/libsurvive_deps.rs index 7852899..58460a5 100644 --- a/src/dependencies/libsurvive_deps.rs +++ b/src/dependencies/libsurvive_deps.rs @@ -1,5 +1,5 @@ use crate::{ - depcheck::{check_dependencies, Dependency, DependencyCheckResult}, + depcheck::{Dependency, DependencyCheckResult}, dependencies::common::{dep_cmake, dep_eigen, dep_gcc, dep_git, dep_gpp, dep_ninja}, }; @@ -15,7 +15,7 @@ fn libsurvive_deps() -> Vec { } pub fn check_libsurvive_deps() -> Vec { - check_dependencies(libsurvive_deps()) + Dependency::check_many(libsurvive_deps()) } pub fn get_missing_libsurvive_deps() -> Vec { diff --git a/src/dependencies/mercury_deps.rs b/src/dependencies/mercury_deps.rs index 674f87d..4245ea2 100644 --- a/src/dependencies/mercury_deps.rs +++ b/src/dependencies/mercury_deps.rs @@ -1,5 +1,5 @@ use crate::{ - depcheck::{check_dependencies, DepType, Dependency, DependencyCheckResult}, + depcheck::{DepType, Dependency, DependencyCheckResult}, linux_distro::LinuxDistro, }; use std::collections::HashMap; @@ -37,7 +37,7 @@ fn mercury_deps() -> Vec { } pub fn check_mercury_deps() -> Vec { - check_dependencies(mercury_deps()) + Dependency::check_many(mercury_deps()) } pub fn get_missing_mercury_deps() -> Vec { diff --git a/src/dependencies/mod.rs b/src/dependencies/mod.rs index 37f4ba4..6cc2364 100644 --- a/src/dependencies/mod.rs +++ b/src/dependencies/mod.rs @@ -5,5 +5,4 @@ pub mod libsurvive_deps; pub mod mercury_deps; pub mod monado_deps; pub mod openhmd_deps; -pub mod pkexec_dep; pub mod wivrn_deps; diff --git a/src/dependencies/monado_deps.rs b/src/dependencies/monado_deps.rs index b0e0ffd..b21fc38 100644 --- a/src/dependencies/monado_deps.rs +++ b/src/dependencies/monado_deps.rs @@ -1,5 +1,5 @@ use crate::{ - depcheck::{check_dependencies, DepType, Dependency, DependencyCheckResult}, + depcheck::{DepType, Dependency, DependencyCheckResult}, dependencies::common::{ dep_cmake, dep_eigen, dep_gcc, dep_git, dep_glslang_validator, dep_gpp, dep_libdrm, dep_ninja, dep_openxr, dep_vulkan_headers, dep_vulkan_icd_loader, @@ -54,7 +54,7 @@ fn monado_deps() -> Vec { } pub fn check_monado_deps() -> Vec { - check_dependencies(monado_deps()) + Dependency::check_many(monado_deps()) } pub fn get_missing_monado_deps() -> Vec { diff --git a/src/dependencies/openhmd_deps.rs b/src/dependencies/openhmd_deps.rs index 6b8bf95..462ce78 100644 --- a/src/dependencies/openhmd_deps.rs +++ b/src/dependencies/openhmd_deps.rs @@ -1,5 +1,5 @@ use crate::{ - depcheck::{check_dependencies, Dependency, DependencyCheckResult}, + depcheck::{Dependency, DependencyCheckResult}, dependencies::common::{dep_cmake, dep_gcc, dep_git, dep_gpp, dep_ninja}, }; @@ -8,7 +8,7 @@ fn openhmd_deps() -> Vec { } pub fn check_openhmd_deps() -> Vec { - check_dependencies(openhmd_deps()) + Dependency::check_many(openhmd_deps()) } pub fn get_missing_openhmd_deps() -> Vec { diff --git a/src/dependencies/pkexec_dep.rs b/src/dependencies/pkexec_dep.rs deleted file mode 100644 index f3110d9..0000000 --- a/src/dependencies/pkexec_dep.rs +++ /dev/null @@ -1,18 +0,0 @@ -use crate::{ - depcheck::{DepType, Dependency}, - linux_distro::LinuxDistro, -}; -use std::collections::HashMap; - -pub fn pkexec_dep() -> Dependency { - Dependency { - name: "pkexec".into(), - dep_type: DepType::Executable, - filename: "pkexec".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "polkit".into()), - (LinuxDistro::Debian, "pkexec".into()), - (LinuxDistro::Fedora, "polkit".into()), - ]), - } -} diff --git a/src/dependencies/wivrn_deps.rs b/src/dependencies/wivrn_deps.rs index e4c3b3d..7491b88 100644 --- a/src/dependencies/wivrn_deps.rs +++ b/src/dependencies/wivrn_deps.rs @@ -1,5 +1,5 @@ use crate::{ - depcheck::{check_dependencies, DepType, Dependency, DependencyCheckResult}, + depcheck::{DepType, Dependency, DependencyCheckResult}, dependencies::common::{ dep_cmake, dep_eigen, dep_gcc, dep_git, dep_glslang_validator, dep_gpp, dep_libdrm, dep_ninja, dep_openxr, dep_vulkan_headers, dep_vulkan_icd_loader, @@ -146,7 +146,7 @@ fn wivrn_deps() -> Vec { } pub fn check_wivrn_deps() -> Vec { - check_dependencies(wivrn_deps()) + Dependency::check_many(wivrn_deps()) } pub fn get_missing_wivrn_deps() -> Vec { diff --git a/src/ui/app.rs b/src/ui/app.rs index ff06ee8..d6033d2 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -19,13 +19,12 @@ use crate::builders::build_openhmd::get_build_openhmd_jobs; use crate::builders::build_wivrn::get_build_wivrn_jobs; use crate::config::Config; use crate::constants::APP_NAME; -use crate::depcheck::check_dependency; use crate::dependencies::basalt_deps::get_missing_basalt_deps; +use crate::dependencies::common::dep_pkexec; use crate::dependencies::libsurvive_deps::get_missing_libsurvive_deps; use crate::dependencies::mercury_deps::get_missing_mercury_deps; use crate::dependencies::monado_deps::get_missing_monado_deps; use crate::dependencies::openhmd_deps::get_missing_openhmd_deps; -use crate::dependencies::pkexec_dep::pkexec_dep; use crate::dependencies::wivrn_deps::get_missing_wivrn_deps; use crate::file_builders::active_runtime_json::{ set_current_active_runtime_to_profile, set_current_active_runtime_to_steam, @@ -478,9 +477,7 @@ impl SimpleComponent for App { ( missing_deps .iter() - .map(|dep| { - dep.packages.get(&d).unwrap_or_else(|| &dep.name).clone() - }) + .map(|dep| dep.package_name_for_distro(Some(&d))) .collect::>() .join(", "), { @@ -656,7 +653,7 @@ impl SimpleComponent for App { )); } Msg::RunSetCap => { - if !check_dependency(pkexec_dep()) { + if !dep_pkexec().check() { println!("pkexec not found, skipping setcap"); } else { let profile = self.get_selected_profile(); diff --git a/src/ui/install_wivrn_box.rs b/src/ui/install_wivrn_box.rs index 0cb1789..5fde31a 100644 --- a/src/ui/install_wivrn_box.rs +++ b/src/ui/install_wivrn_box.rs @@ -2,7 +2,6 @@ use super::alert::alert; use crate::{ adb::get_adb_install_runner, cmd_runner::CmdRunner, - depcheck::check_dependency, dependencies::adb_dep::adb_dep, downloader::download_file, paths::wivrn_apk_download_path, @@ -177,7 +176,7 @@ impl SimpleComponent for InstallWivrnBox { } } Self::Input::DownloadWivrn(link) => { - if !check_dependency(adb_dep()) { + if !adb_dep().check() { alert("ADB is not installed", Some("Please install ADB on your computer to install WiVRn on your Android headset"), Some(&self.root_win)); } else { self.set_install_wivrn_status(InstallWivrnStatus::InProgress); diff --git a/src/ui/main_view.rs b/src/ui/main_view.rs index 2e7b49c..b136082 100644 --- a/src/ui/main_view.rs +++ b/src/ui/main_view.rs @@ -5,6 +5,7 @@ use super::profile_editor::{ProfileEditor, ProfileEditorMsg, ProfileEditorOutMsg use super::steam_launch_options_box::{SteamLaunchOptionsBox, SteamLaunchOptionsBoxMsg}; use super::steamvr_calibration_box::SteamVrCalibrationBox; use crate::config::Config; +use crate::dependencies::common::dep_pkexec; use crate::file_utils::mount_has_nosuid; use crate::gpu_profile::{ get_amd_gpu_power_profile, get_first_amd_gpu, get_set_amd_vr_pow_prof_cmd, GpuPowerProfile, @@ -222,7 +223,7 @@ impl SimpleComponent for MainView { gtk::Label { set_label: concat!( "Your current prefix is inside a partition ", - "mounted with the nosuid option. This will prevent ", + "mounted with the nosuid option.\nThis will prevent ", "the XR runtime from acquiring certain privileges ", "and will cause noticeable stutter when running XR ", "applications." @@ -233,6 +234,27 @@ impl SimpleComponent for MainView { set_wrap_mode: gtk::pango::WrapMode::Word, } }, + gtk::Box { + set_orientation: gtk::Orientation::Vertical, + set_hexpand: true, + set_vexpand: false, + set_spacing: 12, + add_css_class: "card", + add_css_class: "padded", + #[track = "model.changed(Self::selected_profile())"] + set_visible: true || !dep_pkexec().check(), + warning_heading(), + gtk::Label { + set_label: &format!( + "Pkexec wasn't found on your system.\nThis will prevent the XR runtime from acquiring certain priviledges and will cause noticeable stutter when running XR applications.\nYou can fix this by installing the following package on your system: {}", dep_pkexec().package_name() + ), + set_use_markup: true, + add_css_class: "warning", + set_xalign: 0.0, + set_wrap: true, + set_wrap_mode: gtk::pango::WrapMode::Word, + } + }, gtk::Box { set_orientation: gtk::Orientation::Vertical, set_hexpand: true,