diff --git a/Cargo.lock b/Cargo.lock index cb2d639..bc56ea6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -445,16 +445,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "delicious-adwaita" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e53548c789a95211e0ce6d26c213067002b9b4360f8de69046d84de78ad9da3f" -dependencies = [ - "gtk4", - "libadwaita", -] - [[package]] name = "deranged" version = "0.3.11" @@ -573,11 +563,10 @@ dependencies = [ [[package]] name = "envision" -version = "3.1.1" +version = "3.0.1" dependencies = [ "anyhow", "ash", - "delicious-adwaita", "gettext-rs", "git2", "gtk4", @@ -1084,9 +1073,9 @@ dependencies = [ [[package]] name = "gtk4" -version = "0.9.6" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1c491051f030994fd0cde6f3c44f3f5640210308cff1298c7673c47408091d" +checksum = "9376d14d7e33486c54823a42bef296e882b9f25cb4c52b52f4d1d57bbadb5b6d" dependencies = [ "cairo-rs", "field-offset", @@ -1117,9 +1106,9 @@ dependencies = [ [[package]] name = "gtk4-sys" -version = "0.9.6" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41e03b01e54d77c310e1d98647d73f996d04b2f29b9121fe493ea525a7ec03d6" +checksum = "e653b0a9001ba9be1ffddb9373bfe9a111f688222f5aeee2841481300d91b55a" dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", @@ -1534,9 +1523,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libadwaita" -version = "0.7.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500135d29c16aabf67baafd3e7741d48e8b8978ca98bac39e589165c8dc78191" +checksum = "8611ee9fb85e7606c362b513afcaf5b59853f79e4d98caaaf581d99465014247" dependencies = [ "gdk4", "gio", diff --git a/Cargo.toml b/Cargo.toml index 4ecd109..575b302 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "envision" -version = "3.1.1" +version = "3.0.1" edition = "2021" authors = [ "Gabriele Musco ", @@ -44,4 +44,3 @@ tracing-subscriber = { version = "0.3.19", features = ["env-filter", "json"] } tracing = "0.1.41" tracing-appender = "0.2.3" serde_yaml = "0.9.34" -delicious-adwaita = { version = "0.3.0", features = ["all_themes"] } diff --git a/data/org.gabmus.envision.metainfo.xml.in.in b/data/org.gabmus.envision.metainfo.xml.in.in index 76b4dd4..8925605 100644 --- a/data/org.gabmus.envision.metainfo.xml.in.in +++ b/data/org.gabmus.envision.metainfo.xml.in.in @@ -30,35 +30,6 @@ @REPO_URL@/issues - - -

Fixes

-
    -
  • add libusb and libusb-dev deps
  • -
  • Revert "disable and blacklist wayvr dashboard plugin"
  • -
-
-
- - -

What's new

-
    -
  • don't set openvrpaths as read only during profile startup
  • -
  • small design changes to build window ui
  • -
  • add support for vapor openvr compatibility module
  • -
  • remove monado vulkan layers check for nvidia
  • -
-

Fixes

-
    -
  • disable and blacklist wayvr dashboard plugin
  • -
  • monado dependencies: use wayland-protocols-devel on Fedora
  • -
-

Other changes

-
    -
  • clippy
  • -
-
-

Fixes

diff --git a/dist/arch/PKGBUILD b/dist/arch/PKGBUILD index ee1a4b2..3ff8a64 100644 --- a/dist/arch/PKGBUILD +++ b/dist/arch/PKGBUILD @@ -33,6 +33,7 @@ makedepends=( ) optdepends=( 'libudev0-shim: steamvr_lh lighthouse driver support' + 'monado-vulkan-layers-git: Vulkan layers for NVIDIA users' ) provides=(envision) conflicts=(envision) diff --git a/meson.build b/meson.build index d58f4ed..7e406b2 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ project( 'envision', 'rust', - version: '3.1.1', # version number row + version: '3.0.1', # version number row meson_version: '>= 0.59', license: 'AGPL-3.0-or-later', ) diff --git a/scripts/build_mercury.sh b/scripts/build_mercury.sh index 932d343..b3db66a 100755 --- a/scripts/build_mercury.sh +++ b/scripts/build_mercury.sh @@ -2,6 +2,57 @@ set -ev +PREFIX=$1 + +CACHE_DIR=$2 + +if [[ -z $PREFIX ]] || [[ -z $CACHE_DIR ]]; then + echo "Usage: $0 PREFIX CACHE_DIR" + exit 1 +fi + +ONNX_RELEASES=$(curl -sSL "https://api.github.com/repos/microsoft/onnxruntime/releases") +NUM_RELEASES=$(echo "$ONNX_RELEASES" | jq -r '[ select (.[]!=null) ] | length') + +for (( IDX=0; IDX VecDeque { let mut jobs = VecDeque::::new(); @@ -43,24 +40,11 @@ pub fn get_build_basalt_jobs(profile: &Profile, clean_build: bool) -> VecDeque = HashMap::new(); for (k, v) in [ - // The basalt build uses a lot of RAM, so we have to limit the number of - // build processes to not starve the system of memory - // Limit to 6 build processes at most - ( - "CMAKE_BUILD_PARALLEL_LEVEL", - std::cmp::min( - 6, - std::thread::available_parallelism() - .map(NonZero::get) - .unwrap_or(2), - ) - .to_string(), - ), - ("CMAKE_BUILD_TYPE", "RelWithDebInfo".into()), - ("CMAKE_POLICY_VERSION_MINIMUM", "3.5".into()), - ("BUILD_TESTS", "off".into()), + ("CMAKE_BUILD_PARALLEL_LEVEL", "2"), + ("CMAKE_BUILD_TYPE", "RelWithDebInfo"), + ("BUILD_TESTS", "off"), ] { - cmake_env.insert(k.to_string(), v); + cmake_env.insert(k.to_string(), v.to_string()); } cmake_env }), diff --git a/src/builders/build_mercury.rs b/src/builders/build_mercury.rs index 28185d1..36b5c23 100644 --- a/src/builders/build_mercury.rs +++ b/src/builders/build_mercury.rs @@ -1,8 +1,11 @@ use std::collections::VecDeque; -use crate::{constants::pkg_data_dir, termcolor::TermColor, ui::job_worker::job::WorkerJob}; +use crate::{ + constants::pkg_data_dir, paths::get_cache_dir, profile::Profile, termcolor::TermColor, + ui::job_worker::job::WorkerJob, +}; -pub fn get_build_mercury_jobs() -> VecDeque { +pub fn get_build_mercury_jobs(profile: &Profile) -> VecDeque { let mut jobs = VecDeque::new(); jobs.push_back(WorkerJob::new_printer( "Building Mercury...", @@ -14,7 +17,10 @@ pub fn get_build_mercury_jobs() -> VecDeque { .join("scripts/build_mercury.sh") .to_string_lossy() .to_string(), - None, + Some(vec![ + profile.prefix.to_string_lossy().to_string(), + get_cache_dir().to_string_lossy().to_string(), + ]), )); jobs diff --git a/src/builders/build_vapor.rs b/src/builders/build_vapor.rs deleted file mode 100644 index 5a05932..0000000 --- a/src/builders/build_vapor.rs +++ /dev/null @@ -1,68 +0,0 @@ -use crate::{ - build_tools::{cmake::Cmake, git::Git}, - profile::Profile, - termcolor::TermColor, - ui::job_worker::job::WorkerJob, - util::file_utils::rm_rf, -}; -use std::{ - collections::{HashMap, VecDeque}, - path::Path, -}; - -pub fn get_build_vapor_jobs(profile: &Profile, clean_build: bool) -> VecDeque { - let mut jobs = VecDeque::::new(); - jobs.push_back(WorkerJob::new_printer( - "Building VapoR...", - Some(TermColor::Blue), - )); - - let git = Git { - repo: profile - .ovr_comp - .repo - .as_ref() - .unwrap_or(&"https://github.com/micheal65536/VapoR.git".into()) - .clone(), - dir: profile.ovr_comp.path.clone(), - branch: profile - .ovr_comp - .branch - .as_ref() - .unwrap_or(&"master".into()) - .clone(), - }; - - jobs.extend(git.get_pre_build_jobs(profile.pull_on_build)); - - let build_dir = profile.ovr_comp.path.join("build"); - let install_dir = build_dir.join("install_pfx"); - let cmake = Cmake { - env: None, - vars: Some({ - let mut cmake_vars: HashMap = HashMap::new(); - for (k, v) in [ - ("VAPOR_LOG_SILENT", "ON"), - ("USE_SYSTEM_OPENXR", "OFF"), - ("CMAKE_BUILD_TYPE", "RelWithDebInfo"), - ] { - cmake_vars.insert(k.to_string(), v.to_string()); - } - cmake_vars.insert( - "CMAKE_INSTALL_PREFIX".into(), - install_dir.to_string_lossy().to_string(), - ); - cmake_vars - }), - source_dir: profile.ovr_comp.path.clone(), - build_dir: build_dir.clone(), - }; - if !Path::new(&build_dir).is_dir() || clean_build { - rm_rf(&build_dir); - jobs.push_back(cmake.get_prepare_job()); - } - jobs.push_back(cmake.get_build_job()); - jobs.push_back(cmake.get_install_job()); - - jobs -} diff --git a/src/builders/mod.rs b/src/builders/mod.rs index 9d57245..1f66748 100644 --- a/src/builders/mod.rs +++ b/src/builders/mod.rs @@ -4,6 +4,5 @@ pub mod build_mercury; pub mod build_monado; pub mod build_opencomposite; pub mod build_openhmd; -pub mod build_vapor; pub mod build_wivrn; pub mod build_xrizer; diff --git a/src/config.rs b/src/config.rs index 80cf0f5..18cd864 100644 --- a/src/config.rs +++ b/src/config.rs @@ -45,10 +45,6 @@ const fn default_win_size() -> [i32; 2] { DEFAULT_WIN_SIZE } -fn default_theme_name() -> String { - "Follow system".into() -} - #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct Config { pub selected_profile_uuid: String, @@ -58,8 +54,6 @@ pub struct Config { pub win_size: [i32; 2], #[serde(default)] pub plugins: HashMap, - #[serde(default = "default_theme_name")] - pub theme_name: String, } impl Default for Config { @@ -71,7 +65,6 @@ impl Default for Config { user_profiles: Vec::default(), win_size: DEFAULT_WIN_SIZE, plugins: HashMap::default(), - theme_name: default_theme_name(), } } } diff --git a/src/depcheck/basalt_deps.rs b/src/depcheck/basalt_deps.rs index 00a29b6..2a05826 100644 --- a/src/depcheck/basalt_deps.rs +++ b/src/depcheck/basalt_deps.rs @@ -1,7 +1,7 @@ use super::{ boost_deps::boost_deps, common::{dep_cmake, dep_eigen, dep_gpp, dep_libgl, dep_ninja, dep_opencv}, - DepType, DepcheckResultGetMissing, Dependency, DependencyCheckResult, + DepType, Dependency, DependencyCheckResult, }; use crate::linux_distro::LinuxDistro; use std::collections::HashMap; @@ -181,5 +181,9 @@ pub fn check_basalt_deps() -> Vec { } pub fn get_missing_basalt_deps() -> Vec { - check_basalt_deps().filter_missing_deps() + check_basalt_deps() + .iter() + .filter(|res| !res.found) + .map(|res| res.dependency.clone()) + .collect() } diff --git a/src/depcheck/common.rs b/src/depcheck/common.rs index 901d0ff..56ac4ef 100644 --- a/src/depcheck/common.rs +++ b/src/depcheck/common.rs @@ -303,35 +303,3 @@ pub fn dep_adb() -> Dependency { ]), } } - -pub fn dep_getcap_setcap() -> Dependency { - Dependency { - name: "libcap".into(), - dep_type: DepType::Executable, - filename: "setcap".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "libcap".into()), - (LinuxDistro::Debian, "libcap2-bin".into()), - (LinuxDistro::Fedora, "libcap".into()), - (LinuxDistro::Alpine, "libcap".into()), - (LinuxDistro::Gentoo, "sys-libs/libcap".into()), - (LinuxDistro::Suse, "libcap-progs".into()), - ]), - } -} - -pub fn dep_glslc() -> Dependency { - Dependency { - name: "glslc".into(), - dep_type: DepType::Executable, - filename: "glslc".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "shaderc".into()), - (LinuxDistro::Debian, "glslc".into()), - (LinuxDistro::Fedora, "glslc".into()), - (LinuxDistro::Alpine, "shaderc".into()), - (LinuxDistro::Gentoo, "media-libs/shaderc".into()), - (LinuxDistro::Suse, "shaderc".into()), - ]), - } -} diff --git a/src/depcheck/libsurvive_deps.rs b/src/depcheck/libsurvive_deps.rs index 46eec55..c9e8d9c 100644 --- a/src/depcheck/libsurvive_deps.rs +++ b/src/depcheck/libsurvive_deps.rs @@ -1,6 +1,6 @@ use super::{ common::{dep_cmake, dep_eigen, dep_gcc, dep_git, dep_gpp, dep_ninja}, - DepcheckResultGetMissing, Dependency, DependencyCheckResult, + Dependency, DependencyCheckResult, }; fn libsurvive_deps() -> Vec { @@ -19,5 +19,9 @@ pub fn check_libsurvive_deps() -> Vec { } pub fn get_missing_libsurvive_deps() -> Vec { - check_libsurvive_deps().filter_missing_deps() + check_libsurvive_deps() + .iter() + .filter(|res| !res.found) + .map(|res| res.dependency.clone()) + .collect() } diff --git a/src/depcheck/mercury_deps.rs b/src/depcheck/mercury_deps.rs index d8c61b5..cad3c80 100644 --- a/src/depcheck/mercury_deps.rs +++ b/src/depcheck/mercury_deps.rs @@ -1,27 +1,10 @@ -use super::{ - common::dep_opencv, DepType, DepcheckResultGetMissing, Dependency, DependencyCheckResult, -}; +use super::{common::dep_opencv, DepType, Dependency, DependencyCheckResult}; use crate::linux_distro::LinuxDistro; use std::collections::HashMap; fn mercury_deps() -> Vec { vec![ dep_opencv(), - Dependency { - name: "onnxruntime-dev".into(), - dep_type: DepType::Include, - filename: "onnxruntime/onnxruntime_c_api.h".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "onnxruntime".into()), - (LinuxDistro::Debian, "libonnxruntime-dev".into()), - (LinuxDistro::Fedora, "onnxruntime-devel".into()), - // alpine doesn't seem to have the package - // (LinuxDistro::Alpine, "".into()), - (LinuxDistro::Gentoo, "sci-ml/onnx".into()), - // opensuse doesn't seem to have the package - // (LinuxDistro::Suse, "".into()), - ]), - }, Dependency { name: "jq".into(), dep_type: DepType::Executable, @@ -56,5 +39,9 @@ pub fn check_mercury_deps() -> Vec { } pub fn get_missing_mercury_deps() -> Vec { - check_mercury_deps().filter_missing_deps() + check_mercury_deps() + .iter() + .filter(|res| !res.found) + .map(|res| res.dependency.clone()) + .collect() } diff --git a/src/depcheck/mod.rs b/src/depcheck/mod.rs index f2565eb..002a8c8 100644 --- a/src/depcheck/mod.rs +++ b/src/depcheck/mod.rs @@ -6,7 +6,6 @@ pub mod mercury_deps; pub mod monado_deps; pub mod openhmd_deps; pub mod wivrn_deps; -pub mod xrizer_deps; use crate::linux_distro::LinuxDistro; use std::{collections::HashMap, env, fmt::Display, path::Path}; @@ -109,24 +108,6 @@ impl Display for DependencyCheckResult { } } -pub trait DepcheckResultGetMissing { - fn filter_missing_deps(self) -> Vec; -} - -impl DepcheckResultGetMissing for Vec { - fn filter_missing_deps(self) -> Vec { - self.into_iter() - .filter_map(|res| { - if !res.found { - Some(res.dependency) - } else { - None - } - }) - .collect() - } -} - fn shared_obj_paths() -> Vec { vec![ "/lib".into(), @@ -136,24 +117,6 @@ fn shared_obj_paths() -> Vec { "/usr/local/lib64".into(), "/usr/lib/x86_64-linux-gnu".into(), "/usr/lib/aarch64-linux-gnu".into(), - // Debian puts libclang in /usr/lib/llvm-[llvm major version]/lib. - "/usr/lib/llvm-15/lib".into(), - "/usr/lib/llvm-16/lib".into(), - "/usr/lib/llvm-19/lib".into(), - // Fedora puts libclang in /usr/lib64/llvm[llvm major version]/lib as well as /usr/lib64. - "/usr/lib64/llvm15/lib".into(), - "/usr/lib64/llvm16/lib".into(), - "/usr/lib64/llvm17/lib".into(), - "/usr/lib64/llvm18/lib".into(), - "/usr/lib64/llvm19/lib".into(), - "/usr/lib64/llvm20/lib".into(), - // Gentoo puts libclang in /usr/lib/llvm/[llvm major version]/lib64. - "/usr/lib/llvm/15/lib64".into(), - "/usr/lib/llvm/16/lib64".into(), - "/usr/lib/llvm/17/lib64".into(), - "/usr/lib/llvm/18/lib64".into(), - "/usr/lib/llvm/19/lib64".into(), - "/usr/lib/llvm/20/lib64".into(), "/lib/x86_64-linux-gnu".into(), "/lib/aarch64-linux-gnu".into(), "/app/lib".into(), @@ -177,8 +140,6 @@ fn include_paths() -> Vec { "/usr/include/ffmpeg/libpostproc".into(), "/usr/include/ffmpeg/libswresample".into(), "/usr/include/ffmpeg/libswscale".into(), - // opensuse puts wayland-client.h here - "/usr/include/wayland".into(), ] } diff --git a/src/depcheck/monado_deps.rs b/src/depcheck/monado_deps.rs index f9e1b9b..93055d3 100644 --- a/src/depcheck/monado_deps.rs +++ b/src/depcheck/monado_deps.rs @@ -4,12 +4,9 @@ use super::{ dep_libgl, dep_libudev, dep_libx11, dep_libxcb, dep_ninja, dep_openxr, dep_vulkan_headers, dep_vulkan_icd_loader, }, - DepType, DepcheckResultGetMissing, Dependency, DependencyCheckResult, -}; -use crate::{ - depcheck::common::{dep_glslc, dep_libxrandr}, - linux_distro::LinuxDistro, + DepType, Dependency, DependencyCheckResult, }; +use crate::{depcheck::common::dep_libxrandr, linux_distro::LinuxDistro}; use std::collections::HashMap; fn monado_deps() -> Vec { @@ -40,7 +37,7 @@ fn monado_deps() -> Vec { packages: HashMap::from([ (LinuxDistro::Arch, "wayland-protocols".into()), (LinuxDistro::Debian, "wayland-protocols".into()), - (LinuxDistro::Fedora, "wayland-protocols-devel".into()), + (LinuxDistro::Fedora, "wayland-protocols".into()), (LinuxDistro::Gentoo, "dev-libs/wayland-protocols".into()), (LinuxDistro::Suse, "wayland-protocols-devel".into()), ]), @@ -63,7 +60,19 @@ fn monado_deps() -> Vec { dep_ninja(), dep_gcc(), dep_gpp(), - dep_glslc(), + Dependency { + name: "glslc".into(), + dep_type: DepType::Executable, + filename: "glslc".into(), + packages: HashMap::from([ + (LinuxDistro::Arch, "shaderc".into()), + (LinuxDistro::Debian, "glslc".into()), + (LinuxDistro::Fedora, "glslc".into()), + (LinuxDistro::Alpine, "shaderc".into()), + (LinuxDistro::Gentoo, "media-libs/shaderc".into()), + (LinuxDistro::Suse, "shaderc".into()), + ]), + }, dep_glslang_validator(), Dependency { name: "sdl2".into(), @@ -74,34 +83,10 @@ fn monado_deps() -> Vec { (LinuxDistro::Debian, "libsdl2-dev".into()), (LinuxDistro::Fedora, "SDL2-devel".into()), (LinuxDistro::Gentoo, "media-libs/libsdl2".into()), - (LinuxDistro::Suse, "sdl2-compat-devel".into()), + (LinuxDistro::Suse, "SDL2-devel".into()), ]), }, dep_libudev(), - Dependency { - name: "libusb".into(), - dep_type: DepType::SharedObject, - filename: "libusb-1.0.so".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "libusb".into()), - (LinuxDistro::Debian, "libusb-1.0-0".into()), - (LinuxDistro::Fedora, "libusb1".into()), - (LinuxDistro::Gentoo, "dev-libs/libusb".into()), - (LinuxDistro::Suse, "libusb-1_0-0".into()), - ]), - }, - Dependency { - name: "libusb-dev".into(), - dep_type: DepType::Include, - filename: "libusb-1.0/libusb.h".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "libusb".into()), - (LinuxDistro::Debian, "libusb-1.0-0-dev".into()), - (LinuxDistro::Fedora, "libusb1-devel".into()), - (LinuxDistro::Gentoo, "dev-libs/libusb".into()), - (LinuxDistro::Suse, "libusb-1_0-devel".into()), - ]), - }, Dependency { name: "mesa-common-dev".into(), dep_type: DepType::Include, @@ -122,5 +107,9 @@ pub fn check_monado_deps() -> Vec { } pub fn get_missing_monado_deps() -> Vec { - check_monado_deps().filter_missing_deps() + check_monado_deps() + .iter() + .filter(|res| !res.found) + .map(|res| res.dependency.clone()) + .collect() } diff --git a/src/depcheck/openhmd_deps.rs b/src/depcheck/openhmd_deps.rs index d31d013..819324f 100644 --- a/src/depcheck/openhmd_deps.rs +++ b/src/depcheck/openhmd_deps.rs @@ -1,6 +1,6 @@ use super::{ common::{dep_gcc, dep_git, dep_gpp, dep_ninja}, - DepcheckResultGetMissing, Dependency, DependencyCheckResult, + Dependency, DependencyCheckResult, }; use crate::linux_distro::LinuxDistro; use std::collections::HashMap; @@ -31,5 +31,9 @@ pub fn check_openhmd_deps() -> Vec { } pub fn get_missing_openhmd_deps() -> Vec { - check_openhmd_deps().filter_missing_deps() + check_openhmd_deps() + .iter() + .filter(|res| !res.found) + .map(|res| res.dependency.clone()) + .collect() } diff --git a/src/depcheck/wivrn_deps.rs b/src/depcheck/wivrn_deps.rs index 9126272..acf9a35 100644 --- a/src/depcheck/wivrn_deps.rs +++ b/src/depcheck/wivrn_deps.rs @@ -4,7 +4,7 @@ use super::{ dep_libudev, dep_libx11, dep_libxcb, dep_ninja, dep_openxr, dep_vulkan_headers, dep_vulkan_icd_loader, }, - DepType, DepcheckResultGetMissing, Dependency, DependencyCheckResult, + DepType, Dependency, DependencyCheckResult, }; use crate::{ depcheck::common::{dep_libgl, dep_libxrandr}, @@ -270,5 +270,9 @@ pub fn check_wivrn_deps() -> Vec { } pub fn get_missing_wivrn_deps() -> Vec { - check_wivrn_deps().filter_missing_deps() + check_wivrn_deps() + .iter() + .filter(|res| !res.found) + .map(|res| res.dependency.clone()) + .collect() } diff --git a/src/depcheck/xrizer_deps.rs b/src/depcheck/xrizer_deps.rs deleted file mode 100644 index 49d9354..0000000 --- a/src/depcheck/xrizer_deps.rs +++ /dev/null @@ -1,65 +0,0 @@ -use super::{DepType, DepcheckResultGetMissing, Dependency, DependencyCheckResult}; -use crate::{depcheck::common::dep_glslc, linux_distro::LinuxDistro}; -use std::collections::HashMap; - -fn xrizer_deps() -> Vec { - vec![ - dep_glslc(), - Dependency { - name: "cargo".into(), - dep_type: DepType::Executable, - filename: "cargo".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "rust".into()), - (LinuxDistro::Debian, "cargo".into()), - (LinuxDistro::Fedora, "cargo".into()), - (LinuxDistro::Alpine, "cargo".into()), - (LinuxDistro::Suse, "cargo".into()), - ]), - }, - Dependency { - name: "libxcb-glx".into(), - dep_type: DepType::Include, - filename: "xcb/glx.h".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "libxcb".into()), - (LinuxDistro::Debian, "libxcb-glx0-dev".into()), - (LinuxDistro::Fedora, "libxcb-devel".into()), - (LinuxDistro::Gentoo, "x11-libs/libxcb".into()), - (LinuxDistro::Suse, "libxcb-devel".into()), - ]), - }, - Dependency { - name: "libclang".into(), - dep_type: DepType::SharedObject, - filename: "libclang.so".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "clang".into()), - (LinuxDistro::Debian, "libclang-19-dev".into()), - (LinuxDistro::Fedora, "clang19-devel".into()), - (LinuxDistro::Gentoo, "llvm-core/clang-runtime".into()), - (LinuxDistro::Suse, "clang19-devel".into()), - ]), - }, - Dependency { - name: "wayland-dev".into(), - dep_type: DepType::Include, - filename: "wayland-client.h".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "wayland".into()), - (LinuxDistro::Debian, "libwayland-dev".into()), - (LinuxDistro::Fedora, "wayland-devel".into()), - (LinuxDistro::Gentoo, "dev-libs/wayland".into()), - (LinuxDistro::Suse, "wayland-devel".into()), - ]), - }, - ] -} - -pub fn check_xrizer_deps() -> Vec { - Dependency::check_many(xrizer_deps()) -} - -pub fn get_missing_xrizer_deps() -> Vec { - check_xrizer_deps().filter_missing_deps() -} diff --git a/src/downloader.rs b/src/downloader.rs index 3b1b16b..bb9a4b7 100644 --- a/src/downloader.rs +++ b/src/downloader.rs @@ -13,7 +13,7 @@ const CHUNK_SIZE: usize = 1024; fn headers() -> HeaderMap { let mut headers = HeaderMap::new(); - headers.insert(USER_AGENT, format!("{APP_ID}/1.0").parse().unwrap()); + headers.insert(USER_AGENT, format!("{}/1.0", APP_ID).parse().unwrap()); headers } diff --git a/src/env_var_descriptions.rs b/src/env_var_descriptions.rs index 84a404b..ef92101 100644 --- a/src/env_var_descriptions.rs +++ b/src/env_var_descriptions.rs @@ -65,7 +65,7 @@ fn env_var_descriptions() -> Vec<(&'static str, &'static str)> { fn env_var_descriptions_as_paragraph() -> String { ENV_VAR_DESCRIPTIONS .iter() - .map(|(k, v)| format!("{k}\n{v}")) + .map(|(k, v)| format!("{}\n{}", k, v)) .collect::>() .join("\n\n") } diff --git a/src/file_builders/openvrpaths_vrpath.rs b/src/file_builders/openvrpaths_vrpath.rs index 1b888c2..7bd431b 100644 --- a/src/file_builders/openvrpaths_vrpath.rs +++ b/src/file_builders/openvrpaths_vrpath.rs @@ -85,7 +85,6 @@ fn build_steam_openvrpaths() -> OpenVrPaths { } pub fn set_current_openvrpaths_to_steam() -> anyhow::Result<()> { - // removing readonly flag just in case, remove this line in the future set_file_readonly(&get_openvrpaths_vrpath_path(), false)?; dump_current_openvrpaths(&build_steam_openvrpaths())?; Ok(()) @@ -105,18 +104,19 @@ pub fn build_profile_openvrpaths(profile: &Profile) -> OpenVrPaths { pub fn set_current_openvrpaths_to_profile(profile: &Profile) -> anyhow::Result<()> { let dest = get_openvrpaths_vrpath_path(); - // removing readonly flag just in case, remove this line in the future set_file_readonly(&dest, false)?; backup_steam_openvrpaths(); dump_current_openvrpaths(&build_profile_openvrpaths(profile))?; + set_file_readonly(&dest, true)?; Ok(()) } #[cfg(test)] mod tests { - use super::{dump_openvrpaths_to_path, get_openvrpaths_from_path, OpenVrPaths}; use std::path::Path; + use super::{dump_openvrpaths_to_path, get_openvrpaths_from_path, OpenVrPaths}; + #[test] fn can_read_openvrpaths_vrpath_steamvr() { let ovrp = get_openvrpaths_from_path(Path::new("./test/files/openvrpaths.vrpath")).unwrap(); diff --git a/src/file_builders/wivrn_config.rs b/src/file_builders/wivrn_config.rs index 16a8b46..53c966e 100644 --- a/src/file_builders/wivrn_config.rs +++ b/src/file_builders/wivrn_config.rs @@ -143,7 +143,7 @@ pub struct WivrnConfig { pub encoders: Vec, #[serde(skip_serializing_if = "Option::is_none")] pub application: Option, - #[serde(default, rename = "tcp-only")] + #[serde(default)] pub tcp_only: bool, /// contains unknown fields #[serde(flatten)] diff --git a/src/gpu_profile.rs b/src/gpu_profile.rs index 98eea11..5a57c22 100644 --- a/src/gpu_profile.rs +++ b/src/gpu_profile.rs @@ -116,7 +116,7 @@ fn list_gpus() -> Vec { for i in 0..5 { // arbitrary range, find a better way - let card_dir = PathBuf::from(format!("/sys/class/drm/card{i}")); + let card_dir = PathBuf::from(format!("/sys/class/drm/card{}", i)); let vendor_file = card_dir.join("device/vendor"); if let Some(mut reader) = get_reader(&vendor_file) { let mut buf = String::new(); diff --git a/src/linux_distro.rs b/src/linux_distro.rs index 2fcd76a..7bdfe0b 100644 --- a/src/linux_distro.rs +++ b/src/linux_distro.rs @@ -49,13 +49,13 @@ impl LinuxDistro { Ok(_) if buf.starts_with("PRETTY_NAME=\"") => { return buf .split('=') - .next_back() + .last() .map(|b| b.trim().trim_matches('"').trim().to_string()); } Ok(_) if buf.starts_with("NAME=\"") => { name = buf .split('=') - .next_back() + .last() .map(|b| b.trim().trim_matches('"').trim().to_string()); } _ => {} @@ -79,7 +79,7 @@ impl LinuxDistro { { let name = buf .split('=') - .next_back() + .last() .unwrap_or_default() .trim() .trim_matches('"') @@ -115,7 +115,6 @@ impl LinuxDistro { || s.contains("steamos") || s.contains("steam os") || s.contains("endeavour") - || s.contains("cachyos") || s.contains("garuda") { return Some(Self::Arch); @@ -151,33 +150,7 @@ impl LinuxDistro { Self::Alpine => format!("sudo apk add {}", packages.join(" ")), Self::Debian => format!("sudo apt install {}", packages.join(" ")), Self::Gentoo => format!("sudo emerge -av {}", packages.join(" ")), - Self::Suse => { - let mut opi_pkgs = Vec::new(); - let mut zypper_pkgs = Vec::new(); - for pkg in packages { - if ["OpenXR-SDK-devel"].contains(&pkg.as_str()) { - opi_pkgs.push(pkg.clone()); - } else { - zypper_pkgs.push(pkg.clone()); - } - } - [ - if opi_pkgs.is_empty() { - None - } else { - Some(format!("opi {}", opi_pkgs.join(" "))) - }, - if zypper_pkgs.is_empty() { - None - } else { - Some(format!("sudo zypper install {}", zypper_pkgs.join(" "))) - }, - ] - .iter() - .filter_map(|c| c.clone()) - .collect::>() - .join(" && ") - } + Self::Suse => format!("sudo zypper install {}", packages.join(" ")), Self::Fedora => { let mut install_rpmfusion_cmd: Option = None; let mut swap_ffmpeg_cmd: Option = None; @@ -217,10 +190,10 @@ impl LinuxDistro { #[cfg(test)] mod tests { - use super::LinuxDistro; - use crate::depcheck::common::{dep_openxr, dep_pkexec, dep_vulkan_icd_loader}; use std::path::Path; + use super::LinuxDistro; + #[test] fn can_detect_arch_linux_from_etc_os_release() { assert_eq!( @@ -230,34 +203,4 @@ mod tests { Some(LinuxDistro::Arch) ) } - - #[test] - fn can_account_for_opensuse_opi_packages() { - assert_eq!( - LinuxDistro::Suse - .install_command( - &[dep_openxr(), dep_vulkan_icd_loader()] - .iter() - .map(|dep| dep.package_name_for_distro(Some(&LinuxDistro::Suse))) - .collect::>() - ) - .as_str(), - "opi OpenXR-SDK-devel && sudo zypper install vulkan-devel" - ) - } - - #[test] - fn opensuse_opi_does_not_interfere_if_not_needed() { - assert_eq!( - LinuxDistro::Suse - .install_command( - &[dep_pkexec(), dep_vulkan_icd_loader()] - .iter() - .map(|dep| dep.package_name_for_distro(Some(&LinuxDistro::Suse))) - .collect::>() - ) - .as_str(), - "sudo zypper install polkit vulkan-devel" - ) - } } diff --git a/src/main.rs b/src/main.rs index 64a6e59..bb72425 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,16 +11,9 @@ use relm4::{ gtk::{self, gdk, gio, glib, prelude::*}, MessageBroker, RelmApp, }; -use std::{ - env, - fs::{read_dir, remove_file}, - os::unix::fs::MetadataExt, - path::{Path, PathBuf}, -}; -use steam_linux_runtime_injector::{ - restore_sniper_runtime_entrypoint, restore_soldier_runtime_entrypoint, -}; -use tracing::{error, warn}; +use std::env; +use steam_linux_runtime_injector::restore_runtime_entrypoint; +use tracing::warn; use tracing_subscriber::{ filter::LevelFilter, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter, Layer, }; @@ -70,50 +63,7 @@ fn restore_steam_xr_files() { } } } - restore_sniper_runtime_entrypoint(); - restore_soldier_runtime_entrypoint(); -} - -const LOGS_MAX_SIZE_BYTES: u64 = 1000000000; // 1GB - -fn remove_old_logs(dir: &Path, log_files: Option>) -> anyhow::Result<()> { - let log_files: Vec = log_files - .map::>, _>(Ok) - .unwrap_or_else(|| { - let mut files: Vec = read_dir(dir)? - .filter_map(|de| { - let p = de.ok()?.path(); - if p.is_file() && !p.is_symlink() { - Some(p) - } else { - None - } - }) - .collect(); - files.sort_unstable(); - Ok(files) - })?; - let total_size = log_files - .iter() - .filter_map(|p| Some(p.metadata().ok()?.size())) - .reduce(u64::saturating_add) - .unwrap_or(0); - // if size is under threshold, finish - if total_size < LOGS_MAX_SIZE_BYTES { - return Ok(()); - } - // keep a minimum of 3 logs - if log_files.len() <= 3 { - return Ok(()); - } - - remove_file(log_files.first().ok_or_else(|| - anyhow::Error::msg( - "Could not get first item in log files list, but they should be more than 3! This is a bug!" - ) - )?)?; - - remove_old_logs(dir, Some(log_files)) + restore_runtime_entrypoint(); } fn main() -> Result<()> { @@ -121,8 +71,6 @@ fn main() -> Result<()> { panic!("{APP_NAME} cannot run as root"); } restore_steam_xr_files(); - // deferring error logging for this since tracing isn't initialized yet - let old_logs_removal_res = remove_old_logs(&get_logs_dir(), None); let rolling_log_writer = tracing_appender::rolling::daily(get_logs_dir(), "log"); let (non_blocking_appender, _appender_guard) = @@ -142,10 +90,6 @@ fn main() -> Result<()> { ) .init(); - if let Err(e) = old_logs_removal_res { - error!("Failed to remove old log files: {e}"); - } - // Prepare i18n gettextrs::setlocale(LocaleCategory::LcAll, ""); gettextrs::bindtextdomain(GETTEXT_PACKAGE, LOCALE_DIR).expect("Unable to bind the text domain"); @@ -160,7 +104,7 @@ fn main() -> Result<()> { } let provider = gtk::CssProvider::new(); - provider.load_from_resource(&format!("{RESOURCES_BASE_PATH}/style.css")); + provider.load_from_resource(&format!("{}/style.css", RESOURCES_BASE_PATH)); if let Some(display) = gdk::Display::default() { gtk::style_context_add_provider_for_display( &display, diff --git a/src/openxr_prober.rs b/src/openxr_prober.rs index de756e3..c013959 100644 --- a/src/openxr_prober.rs +++ b/src/openxr_prober.rs @@ -17,7 +17,7 @@ pub fn is_openxr_ready() -> bool { let Ok(xr_instance) = entry.create_instance( &xr::ApplicationInfo { - application_name: &format!("{CMD_NAME}-openxr-prober"), + application_name: &format!("{}-openxr-prober", CMD_NAME), application_version: 0, engine_name: CMD_NAME, engine_version: 0, diff --git a/src/profile.rs b/src/profile.rs index 2666291..ad6b170 100644 --- a/src/profile.rs +++ b/src/profile.rs @@ -2,8 +2,7 @@ use crate::{ depcheck::{ basalt_deps::get_missing_basalt_deps, libsurvive_deps::get_missing_libsurvive_deps, mercury_deps::get_missing_mercury_deps, monado_deps::get_missing_monado_deps, - openhmd_deps::get_missing_openhmd_deps, wivrn_deps::get_missing_wivrn_deps, - xrizer_deps::get_missing_xrizer_deps, Dependency, + openhmd_deps::get_missing_openhmd_deps, wivrn_deps::get_missing_wivrn_deps, Dependency, }, file_builders::active_runtime_json::ActiveRuntime, paths::{get_data_dir, BWRAP_SYSTEM_PREFIX, SYSTEM_PREFIX}, @@ -15,7 +14,7 @@ use serde::{Deserialize, Serialize}; use std::{ collections::HashMap, fmt::Display, - fs::{remove_dir_all, File}, + fs::File, io::BufReader, path::{Path, PathBuf}, slice::Iter, @@ -266,7 +265,6 @@ pub enum OvrCompatibilityModuleType { #[default] Opencomposite, Xrizer, - Vapor, } impl Display for OvrCompatibilityModuleType { @@ -274,23 +272,13 @@ impl Display for OvrCompatibilityModuleType { f.write_str(match self { Self::Opencomposite => "OpenComposite", Self::Xrizer => "xrizer", - Self::Vapor => "VapoR", }) } } impl OvrCompatibilityModuleType { pub fn iter() -> Iter<'static, Self> { - [Self::Opencomposite, Self::Xrizer, Self::Vapor].iter() - } - - pub fn get_missing_deps(&self) -> Vec { - match self { - OvrCompatibilityModuleType::Xrizer => get_missing_xrizer_deps(), - OvrCompatibilityModuleType::Opencomposite | OvrCompatibilityModuleType::Vapor => { - Vec::default() - } - } + [Self::Opencomposite, Self::Xrizer].iter() } } @@ -301,7 +289,6 @@ impl FromStr for OvrCompatibilityModuleType { match s.to_lowercase().trim() { "opencomposite" => Ok(Self::Opencomposite), "xrizer" => Ok(Self::Xrizer), - "vapor" => Ok(Self::Vapor), _ => Err(format!("no match for ovr compatibility module `{s}`")), } } @@ -312,8 +299,7 @@ impl From for OvrCompatibilityModuleType { match value { 0 => Self::Opencomposite, 1 => Self::Xrizer, - 2 => Self::Vapor, - _ => panic!("OvrCompatibilityModuleType index out of bounds"), + _ => panic!("OvrCompatibilityModuleType index out of bounds"), } } } @@ -342,7 +328,6 @@ impl ProfileOvrCompatibilityModule { pub fn runtime_dir(&self) -> PathBuf { match self.mod_type { OvrCompatibilityModuleType::Opencomposite => self.path.join("build"), - OvrCompatibilityModuleType::Vapor => self.path.join("build/install_pfx/lib/VapoR"), OvrCompatibilityModuleType::Xrizer => self.path.join("target/release"), } } @@ -459,29 +444,6 @@ impl Profile { get_data_dir().join("prefixes").join(uuid) } - /// deletes files and folders associated to this profile (mostly repo clones) - pub fn delete_files(&self) -> Vec> { - [ - Some(&self.xrservice_path), - Some(&self.ovr_comp.path), - self.features.libsurvive.path.as_ref(), - self.features.basalt.path.as_ref(), - self.features.openhmd.path.as_ref(), - ] - .iter() - .map(|dir| match dir { - Some(dir) => { - if dir.try_exists().unwrap_or_default() { - remove_dir_all(dir) - } else { - Ok(()) - } - } - None => Ok(()), - }) - .collect() - } - pub fn xr_runtime_json_env_var(&self) -> String { format!( "XR_RUNTIME_JSON=\"{prefix}/share/openxr/1/openxr_{runtime}.json\"", @@ -746,7 +708,7 @@ impl Profile { if self.features.mercury_enabled { missing_deps.extend(get_missing_mercury_deps()); } - missing_deps.extend(self.ovr_comp.mod_type.get_missing_deps()); + // no listed deps for opencomp } missing_deps.sort_unstable(); missing_deps.dedup(); // dedup only works if sorted, hence the above diff --git a/src/profiles/lighthouse.rs b/src/profiles/lighthouse.rs index 9ba0af8..97f3a1f 100644 --- a/src/profiles/lighthouse.rs +++ b/src/profiles/lighthouse.rs @@ -21,7 +21,7 @@ pub fn lighthouse_profile() -> Profile { environment.insert("LD_LIBRARY_PATH".into(), prepare_ld_library_path(&prefix)); Profile { uuid: "lighthouse-default".into(), - name: format!("Lighthouse Driver - {APP_NAME} Default"), + name: format!("Lighthouse Driver - {name} Default", name = APP_NAME), xrservice_path: data_monado_path(), xrservice_type: XRServiceType::Monado, ovr_comp: ProfileOvrCompatibilityModule { diff --git a/src/profiles/openhmd.rs b/src/profiles/openhmd.rs index 71ec6f7..8709725 100644 --- a/src/profiles/openhmd.rs +++ b/src/profiles/openhmd.rs @@ -21,7 +21,7 @@ pub fn openhmd_profile() -> Profile { environment.insert("LD_LIBRARY_PATH".into(), prepare_ld_library_path(&prefix)); Profile { uuid: "openhmd-default".into(), - name: format!("OpenHMD - {APP_NAME} Default"), + name: format!("OpenHMD - {name} Default", name = APP_NAME), xrservice_path: data_monado_path(), xrservice_type: XRServiceType::Monado, ovr_comp: ProfileOvrCompatibilityModule { diff --git a/src/profiles/simulated.rs b/src/profiles/simulated.rs index c5af2ec..a39a66b 100644 --- a/src/profiles/simulated.rs +++ b/src/profiles/simulated.rs @@ -22,7 +22,7 @@ pub fn simulated_profile() -> Profile { ); Profile { uuid: "simulated-default".into(), - name: format!("Simulated Driver - {APP_NAME} Default"), + name: format!("Simulated Driver - {name} Default", name = APP_NAME), xrservice_path: data_monado_path(), xrservice_type: XRServiceType::Monado, ovr_comp: ProfileOvrCompatibilityModule { diff --git a/src/profiles/survive.rs b/src/profiles/survive.rs index 6349b77..d3e8ff6 100644 --- a/src/profiles/survive.rs +++ b/src/profiles/survive.rs @@ -23,7 +23,7 @@ pub fn survive_profile() -> Profile { environment.insert("LD_LIBRARY_PATH".into(), prepare_ld_library_path(&prefix)); Profile { uuid: "survive-default".into(), - name: format!("Survive - {APP_NAME} Default"), + name: format!("Survive - {name} Default", name = APP_NAME), xrservice_path: data_monado_path(), xrservice_type: XRServiceType::Monado, ovr_comp: ProfileOvrCompatibilityModule { diff --git a/src/profiles/wivrn.rs b/src/profiles/wivrn.rs index b68e15d..980e1ed 100644 --- a/src/profiles/wivrn.rs +++ b/src/profiles/wivrn.rs @@ -19,7 +19,7 @@ pub fn wivrn_profile() -> Profile { environment.insert("U_PACING_APP_USE_MIN_FRAME_PERIOD".into(), "1".into()); Profile { uuid: "wivrn-default".into(), - name: format!("WiVRn - {APP_NAME} Default"), + name: format!("WiVRn - {name} Default", name = APP_NAME), xrservice_path: data_wivrn_path(), xrservice_type: XRServiceType::Wivrn, ovr_comp: ProfileOvrCompatibilityModule { diff --git a/src/profiles/wmr.rs b/src/profiles/wmr.rs index ae99d62..c332f6a 100644 --- a/src/profiles/wmr.rs +++ b/src/profiles/wmr.rs @@ -21,7 +21,7 @@ pub fn wmr_profile() -> Profile { environment.insert("LD_LIBRARY_PATH".into(), prepare_ld_library_path(&prefix)); Profile { uuid: "wmr-default".into(), - name: format!("WMR - {APP_NAME} Default"), + name: format!("WMR - {name} Default", name = APP_NAME), xrservice_path: data_monado_path(), xrservice_type: XRServiceType::Monado, ovr_comp: ProfileOvrCompatibilityModule { diff --git a/src/steam_linux_runtime_injector.rs b/src/steam_linux_runtime_injector.rs index 6e08b5f..97f50c5 100644 --- a/src/steam_linux_runtime_injector.rs +++ b/src/steam_linux_runtime_injector.rs @@ -2,7 +2,7 @@ use crate::{ paths::get_backup_dir, profile::Profile, util::{ - file_utils::{copy_file, get_writer, mark_as_executable}, + file_utils::{copy_file, get_writer}, steam_library_folder::SteamLibraryFolder, }, }; @@ -15,85 +15,45 @@ use std::{ }; use tracing::error; -pub const SNIPER_RUNTIME_STEAM_APPID: u32 = 1628350; -pub const SOLDIER_RUNTIME_STEAM_APPID: u32 = 1391110; +pub const PRESSURE_VESSEL_STEAM_APPID: u32 = 1628350; -fn get_sniper_runtime_entrypoint_path() -> Option { +fn get_runtime_entrypoint_path() -> Option { match SteamLibraryFolder::get_folders() { Ok(libraryfolders) => libraryfolders .iter() - .find(|(_, folder)| folder.apps.contains_key(&SNIPER_RUNTIME_STEAM_APPID)) + .find(|(_, folder)| folder.apps.contains_key(&PRESSURE_VESSEL_STEAM_APPID)) .map(|(_, folder)| { PathBuf::from(&folder.path) .join("steamapps/common/SteamLinuxRuntime_sniper/_v2-entry-point") }), Err(e) => { - error!("unable to get sniper runtime entrypoint path: {e}"); - None - } - } -} - -fn get_soldier_runtime_entrypoint_path() -> Option { - match SteamLibraryFolder::get_folders() { - Ok(libraryfolders) => libraryfolders - .iter() - .find(|(_, folder)| folder.apps.contains_key(&SOLDIER_RUNTIME_STEAM_APPID)) - .map(|(_, folder)| { - PathBuf::from(&folder.path) - .join("steamapps/common/SteamLinuxRuntime_soldier/_v2-entry-point") - }), - Err(e) => { - error!("unable to get soldier runtime entrypoint path: {e}"); + error!("unable to get runtime entrypoint path: {e}"); None } } } lazy_static! { - static ref STEAM_SNIPER_RUNTIME_ENTRYPOINT_PATH: Option = - get_sniper_runtime_entrypoint_path(); - static ref STEAM_SOLDIER_RUNTIME_ENTRYPOINT_PATH: Option = - get_soldier_runtime_entrypoint_path(); + static ref STEAM_RUNTIME_ENTRYPOINT_PATH: Option = get_runtime_entrypoint_path(); } -fn get_backup_sniper_runtime_entrypoint_location() -> PathBuf { +fn get_backup_runtime_entrypoint_location() -> PathBuf { get_backup_dir().join("_v2-entry-point.bak") } -fn get_backup_soldier_runtime_entrypoint_location() -> PathBuf { - get_backup_dir().join("_v2-entry-point.soldier.bak") +fn backup_runtime_entrypoint(path: &Path) { + copy_file(path, &get_backup_runtime_entrypoint_location()); } -fn backup_sniper_runtime_entrypoint(path: &Path) { - copy_file(path, &get_backup_sniper_runtime_entrypoint_location()); -} - -fn backup_soldier_runtime_entrypoint(path: &Path) { - copy_file(path, &get_backup_soldier_runtime_entrypoint_location()); -} - -pub fn restore_sniper_runtime_entrypoint() { - if let Some(path) = STEAM_SNIPER_RUNTIME_ENTRYPOINT_PATH.as_ref() { - let backup = get_backup_sniper_runtime_entrypoint_location(); +pub fn restore_runtime_entrypoint() { + if let Some(path) = STEAM_RUNTIME_ENTRYPOINT_PATH.as_ref() { + let backup = get_backup_runtime_entrypoint_location(); if Path::new(&backup).is_file() { copy_file(&backup, path); - let _ = mark_as_executable(path); } } } -pub fn restore_soldier_runtime_entrypoint() { - if let Some(path) = STEAM_SOLDIER_RUNTIME_ENTRYPOINT_PATH.as_ref() { - let backup = get_backup_soldier_runtime_entrypoint_location(); - if Path::new(&backup).is_file() { - copy_file(&backup, path); - let _ = mark_as_executable(path); - } - } -} - -/// this implementation is identical for both sniper and soldier runtimes fn append_to_runtime_entrypoint(data: &str, path: &Path) -> anyhow::Result<()> { let existing = read_to_string(path)?; let new = existing.replace( @@ -105,12 +65,10 @@ fn append_to_runtime_entrypoint(data: &str, path: &Path) -> anyhow::Result<()> { Ok(()) } -pub fn set_sniper_runtime_entrypoint_launch_opts_from_profile( - profile: &Profile, -) -> anyhow::Result<()> { - restore_sniper_runtime_entrypoint(); - if let Some(dest) = STEAM_SNIPER_RUNTIME_ENTRYPOINT_PATH.as_ref() { - backup_sniper_runtime_entrypoint(dest); +pub fn set_runtime_entrypoint_launch_opts_from_profile(profile: &Profile) -> anyhow::Result<()> { + restore_runtime_entrypoint(); + if let Some(dest) = STEAM_RUNTIME_ENTRYPOINT_PATH.as_ref() { + backup_runtime_entrypoint(dest); append_to_runtime_entrypoint( &profile .get_env_vars() @@ -120,31 +78,8 @@ pub fn set_sniper_runtime_entrypoint_launch_opts_from_profile( .join("\n"), dest, )?; - mark_as_executable(dest)?; return Ok(()); } - bail!("Could not find valid sniper runtime entrypoint"); -} - -pub fn set_soldier_runtime_entrypoint_launch_opts_from_profile( - profile: &Profile, -) -> anyhow::Result<()> { - restore_soldier_runtime_entrypoint(); - if let Some(dest) = STEAM_SOLDIER_RUNTIME_ENTRYPOINT_PATH.as_ref() { - backup_soldier_runtime_entrypoint(dest); - append_to_runtime_entrypoint( - &profile - .get_env_vars() - .iter() - .map(|ev| "export ".to_string() + ev) - .collect::>() - .join("\n"), - dest, - )?; - mark_as_executable(dest)?; - - return Ok(()); - } - bail!("Could not find valid soldier runtime entrypoint"); + bail!("Could not find valid runtime entrypoint"); } diff --git a/src/ui/about_dialog.rs b/src/ui/about_dialog.rs index 0e28534..8f4235e 100644 --- a/src/ui/about_dialog.rs +++ b/src/ui/about_dialog.rs @@ -33,7 +33,7 @@ pub fn create_about_dialog() -> adw::AboutDialog { const UNKNOWN: &str = "UNKNOWN"; pub fn populate_debug_info(dialog: &adw::AboutDialog, vkinfo: Option<&VulkanInfo>) { - if !dialog.debug_info().is_empty() { + if dialog.debug_info().len() > 0 { return; } let distro_family = LinuxDistro::get(); @@ -70,7 +70,7 @@ pub fn populate_debug_info(dialog: &adw::AboutDialog, vkinfo: Option<&VulkanInfo .and_then(|s| { s.split("\n") .find(|line| line.starts_with("model name")) - .map(|line| line.split(':').next_back().map(|s| s.trim().to_string())) + .map(|line| line.split(':').last().map(|s| s.trim().to_string())) }) .flatten() .unwrap_or(UNKNOWN.into()) @@ -81,6 +81,12 @@ pub fn populate_debug_info(dialog: &adw::AboutDialog, vkinfo: Option<&VulkanInfo .map(|i| i.gpu_names.join(", ")) .unwrap_or(UNKNOWN.into()) ), + format!( + "Monado Vulkan Layers: {}", + vkinfo + .map(|i| i.has_monado_vulkan_layers.to_string()) + .unwrap_or(UNKNOWN.into()) + ), format!("Detected XR Devices: {}", { let devs = PhysicalXRDevice::from_usb(); if devs.is_empty() { diff --git a/src/ui/app.rs b/src/ui/app.rs index a9b9265..98510a3 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -20,8 +20,7 @@ use crate::{ build_basalt::get_build_basalt_jobs, build_libsurvive::get_build_libsurvive_jobs, build_mercury::get_build_mercury_jobs, build_monado::get_build_monado_jobs, build_opencomposite::get_build_opencomposite_jobs, build_openhmd::get_build_openhmd_jobs, - build_vapor::get_build_vapor_jobs, build_wivrn::get_build_wivrn_jobs, - build_xrizer::get_build_xrizer_jobs, + build_wivrn::get_build_wivrn_jobs, build_xrizer::get_build_xrizer_jobs, }, config::{Config, PluginConfig}, constants::APP_NAME, @@ -41,11 +40,8 @@ use crate::{ profile::{OvrCompatibilityModuleType, Profile, XRServiceType}, stateless_action, steam_linux_runtime_injector::{ - restore_sniper_runtime_entrypoint, restore_soldier_runtime_entrypoint, - set_sniper_runtime_entrypoint_launch_opts_from_profile, - set_soldier_runtime_entrypoint_launch_opts_from_profile, + restore_runtime_entrypoint, set_runtime_entrypoint_launch_opts_from_profile, }, - termcolor::TermColor, util::file_utils::{ setcap_cap_sys_nice_eip, setcap_cap_sys_nice_eip_cmd, verify_cap_sys_nice_eip, }, @@ -54,7 +50,6 @@ use crate::{ xr_devices::XRDevice, }; use adw::{prelude::*, ResponseAppearance}; -use delicious_adwaita::{theme::Theme, ThemeEngine}; use gtk::glib::{self, clone}; use notify_rust::NotificationHandle; use relm4::{ @@ -100,8 +95,6 @@ pub struct App { inhibit_fail_notif: Option, pluginstore: Option>, - - theme_engine: ThemeEngine, } #[derive(Debug)] @@ -119,8 +112,7 @@ pub enum Msg { StartWithDebug, RestartXRService, ProfileSelected(Profile), - /// bool param: delete files - DeleteProfile(bool), + DeleteProfile, SaveProfile(Profile), RunSetCap, OpenLibsurviveSetup, @@ -136,8 +128,6 @@ pub enum Msg { WivrnCheckPairMode, OpenPluginStore, UpdateConfigPlugins(HashMap), - ShowThemeManager, - SaveThemeConfig, NoOp, } @@ -236,17 +226,13 @@ impl App { ); worker.start(); self.xrservice_worker = Some(worker); - let set_sniper_launch_opts_res = - set_sniper_runtime_entrypoint_launch_opts_from_profile(&prof); - let set_soldier_launch_opts_res = - set_soldier_runtime_entrypoint_launch_opts_from_profile(&prof); self.main_view .sender() .emit(MainViewMsg::XRServiceActiveChanged( true, Some(self.get_selected_profile()), // show launch opts only if setting the runtime entrypoint fails - set_sniper_launch_opts_res.is_err() || set_soldier_launch_opts_res.is_err(), + set_runtime_entrypoint_launch_opts_from_profile(&prof).is_err(), )); self.debug_view .sender() @@ -310,8 +296,7 @@ impl App { } pub fn restore_openxr_openvr_files(&self) { - restore_sniper_runtime_entrypoint(); - restore_soldier_runtime_entrypoint(); + restore_runtime_entrypoint(); if let Err(e) = remove_current_active_runtime() { alert( "Could not remove profile active runtime", @@ -380,7 +365,7 @@ impl AsyncComponent for App { set_content: Some(&adw::NavigationPage::new(model.debug_view.widget(), "Debug View")), set_show_content: false, set_collapsed: !model.config.debug_view_enabled, - }, + } }, connect_close_request[sender] => move |win| { sender.input(Msg::SaveWinSize(win.width(), win.height())); @@ -404,27 +389,6 @@ impl AsyncComponent for App { ) { match message { Msg::NoOp => {} - Msg::ShowThemeManager => { - let dialog = self - .theme_engine - .theme_chooser_dialog(Theme::default_themes().as_ref()); - dialog.set_content_height(2000); - dialog.present(Some(&self.app_win)); - dialog.connect_closed(clone!( - #[strong] - sender, - move |_| { - sender.input(Msg::SaveThemeConfig); - } - )); - } - Msg::SaveThemeConfig => { - let name = self.theme_engine.current_theme_name(); - if self.config.theme_name != name { - self.config.theme_name = name; - self.config.save(); - } - } Msg::OnServiceLog(rows) => { if !rows.is_empty() { self.debug_view @@ -555,7 +519,7 @@ impl AsyncComponent for App { jobs.extend(get_build_basalt_jobs(&profile, clean_build)); } if profile.features.mercury_enabled { - jobs.extend(get_build_mercury_jobs()); + jobs.extend(get_build_mercury_jobs(&profile)); } jobs.extend(match profile.xrservice_type { XRServiceType::Monado => get_build_monado_jobs(&profile, clean_build), @@ -569,9 +533,6 @@ impl AsyncComponent for App { OvrCompatibilityModuleType::Xrizer => { get_build_xrizer_jobs(&profile, clean_build) } - OvrCompatibilityModuleType::Vapor => { - get_build_vapor_jobs(&profile, clean_build) - } }); let missing_deps = profile.missing_dependencies(); if !(self.skip_depcheck || profile.skip_dependency_check || missing_deps.is_empty()) @@ -661,10 +622,6 @@ impl AsyncComponent for App { if dep_pkexec().check() { self.setcap_confirm_dialog.present(Some(&self.app_win)); } else { - self.build_window - .sender() - .emit(BuildWindowMsg::UpdateContent(vec![TermColor::Red - .colorize("pkexec not found, cannot set capabilities\n")])); alert_w_widget( "pkexec not found", Some(&format!( @@ -687,7 +644,7 @@ impl AsyncComponent for App { self.build_window .sender() .emit(BuildWindowMsg::UpdateBuildStatus(BuildStatus::Error( - format!("Exit status {errcode}"), + format!("Exit status {}", errcode), ))); } }; @@ -697,16 +654,9 @@ impl AsyncComponent for App { w.stop(); } } - Msg::DeleteProfile(delete_files) => { + Msg::DeleteProfile => { let todel = self.get_selected_profile(); if todel.editable { - if delete_files { - for res in todel.delete_files() { - if let Err(e) = res { - error!("Error deleting profile directory: {e}"); - } - } - } self.config.user_profiles.retain(|p| p.uuid != todel.uuid); self.config.save(); self.profiles = self.config.profiles(); @@ -746,7 +696,6 @@ impl AsyncComponent for App { } Msg::RunSetCap => { if !dep_pkexec().check() { - // there's a precheck ahead of this, this should likely never happen error!("pkexec not found, skipping setcap"); } else { let profile = self.get_selected_profile(); @@ -764,26 +713,8 @@ impl AsyncComponent for App { if let Err(e) = setcap_cap_sys_nice_eip(&profile).await { setcap_failed_dialog(); error!("failed running setcap: {e}"); - self.build_window - .sender() - .emit(BuildWindowMsg::UpdateContent(vec![ - TermColor::Red.colorize("Setting capabilities failed\n") - ])); } else if !verify_cap_sys_nice_eip(&profile).await { setcap_failed_dialog(); - error!("setcap succeeded but capabilities were reset"); - self.build_window - .sender() - .emit(BuildWindowMsg::UpdateContent(vec![TermColor::Red - .colorize( - "Setting capabilities succeeded, but capabilities have been reset\n", - )])); - } else { - self.build_window - .sender() - .emit(BuildWindowMsg::UpdateContent(vec![ - TermColor::Green.colorize("Capabilities set correctly\n") - ])); } } } @@ -1031,17 +962,6 @@ impl AsyncComponent for App { } ) ); - stateless_action!( - actions, - ThemeManagerAction, - clone!( - #[strong] - sender, - move |_| { - sender.input(Msg::ShowThemeManager); - } - ) - ); // this bypasses the macro because I need the underlying gio action // to enable/disable it in update() let configure_wivrn_action = { @@ -1078,12 +998,13 @@ impl AsyncComponent for App { config: config.clone(), selected_profile: selected_profile.clone(), root_win: root.clone().into(), + vkinfo: vkinfo.clone(), }) .forward(sender.input_sender(), |message| match message { MainViewOutMsg::DoStartStopXRService => Msg::DoStartStopXRService, MainViewOutMsg::RestartXRService => Msg::RestartXRService, MainViewOutMsg::ProfileSelected(uuid) => Msg::ProfileSelected(uuid), - MainViewOutMsg::DeleteProfile(delete_files) => Msg::DeleteProfile(delete_files), + MainViewOutMsg::DeleteProfile => Msg::DeleteProfile, MainViewOutMsg::SaveProfile(p) => Msg::SaveProfile(p), MainViewOutMsg::OpenLibsurviveSetup => Msg::OpenLibsurviveSetup, MainViewOutMsg::BuildProfile(clean) => Msg::BuildProfile(clean), @@ -1110,17 +1031,6 @@ impl AsyncComponent for App { .detach(), split_view: None, setcap_confirm_dialog, - theme_engine: ThemeEngine::new_with_theme(&{ - if config.theme_name == "Follow system" { - Theme::default() - } else { - Theme::default_themes() - .into_iter() - .find(|t| t.name == config.theme_name) - .unwrap_or_default() - } - }) - .unwrap(), config, profiles, xrservice_worker: None, @@ -1209,7 +1119,6 @@ new_stateless_action!(pub QuitAction, AppActionGroup, "quit"); new_stateful_action!(pub DebugViewToggleAction, AppActionGroup, "debugviewtoggle", (), bool); new_stateless_action!(pub ConfigureWivrnAction, AppActionGroup, "configurewivrn"); new_stateless_action!(pub PluginStoreAction, AppActionGroup, "store"); -new_stateless_action!(pub ThemeManagerAction, AppActionGroup, "thememanager"); new_stateless_action!(pub DebugOpenDataAction, AppActionGroup, "debugopendata"); new_stateless_action!(pub DebugOpenPrefixAction, AppActionGroup, "debugopenprefix"); diff --git a/src/ui/build_window.rs b/src/ui/build_window.rs index 1bc966b..759af9b 100644 --- a/src/ui/build_window.rs +++ b/src/ui/build_window.rs @@ -1,5 +1,3 @@ -use crate::termcolor::TermColor; - use super::{term_widget::TermWidget, SENDER_IO_ERR_MSG}; use adw::prelude::*; use relm4::prelude::*; @@ -90,54 +88,43 @@ impl SimpleComponent for BuildWindow { gtk::Label { #[track = "model.changed(BuildWindow::build_status())"] set_markup: match &model.build_status { - BuildStatus::Building => String::default(), - BuildStatus::Done => "Build done, you can close this window".into(), + BuildStatus::Building => "Build in progress...".to_string(), + BuildStatus::Done => "Build done, you can close this window".to_string(), BuildStatus::Error(code) => { - format!("Build failed: \"{code}\"") + format!("Build failed: \"{c}\"", c = code) } }.as_str(), - #[track = "model.changed(BuildWindow::build_status())"] - set_visible: match &model.build_status { - BuildStatus::Building => false, - BuildStatus::Done | BuildStatus::Error(_) => true, - }, add_css_class: "title-2", set_wrap: true, set_wrap_mode: gtk::pango::WrapMode::Word, set_justify: gtk::Justification::Center, }, + gtk::Button { + #[track = "model.changed(BuildWindow::build_status())"] + set_visible: matches!(&model.build_status, BuildStatus::Building), + add_css_class: "destructive-action", + add_css_class: "circular", + set_icon_name: "window-close-symbolic", + set_tooltip_text: Some("Cancel build"), + connect_clicked[sender] => move |_| { + sender.output(Self::Output::CancelBuild).expect(SENDER_IO_ERR_MSG); + } + }, }, model.term.container.clone(), }, - add_bottom_bar: bottom_bar = >k::Box { - set_orientation: gtk::Orientation::Horizontal, + add_bottom_bar: bottom_bar = >k::Button { + add_css_class: "pill", set_halign: gtk::Align::Center, - set_hexpand: true, - set_margin_bottom: 24, - set_spacing: 12, - gtk::Button { - add_css_class: "pill", - set_halign: gtk::Align::Center, - set_label: "Close", - #[track = "model.changed(BuildWindow::can_close())"] - set_visible: model.can_close, - connect_clicked[win] => move |_| { - win.close(); - }, + set_label: "Close", + set_margin_all: 12, + #[track = "model.changed(BuildWindow::can_close())"] + set_sensitive: model.can_close, + connect_clicked[win] => move |_| { + + win.close(); }, - // this - gtk::Button { - #[track = "model.changed(BuildWindow::build_status())"] - set_visible: matches!(&model.build_status, BuildStatus::Building), - add_css_class: "destructive-action", - add_css_class: "pill", - set_label: "Cancel build", - connect_clicked[sender] => move |_| { - sender.output(Self::Output::CancelBuild).expect(SENDER_IO_ERR_MSG); - } - }, - // ^^^ - }, + } } } } @@ -166,18 +153,8 @@ impl SimpleComponent for BuildWindow { label.remove_css_class("success"); label.remove_css_class("error"); match status { - BuildStatus::Done => { - label.add_css_class("success"); - sender.input(BuildWindowMsg::UpdateContent(vec![ - TermColor::Blue.colorize("Build completed!\n") - ])); - } - BuildStatus::Error(_) => { - label.add_css_class("error"); - sender.input(BuildWindowMsg::UpdateContent(vec![ - TermColor::Blue.colorize("Build failed!\n") - ])); - } + BuildStatus::Done => label.add_css_class("success"), + BuildStatus::Error(_) => label.add_css_class("error"), _ => {} } if status != BuildStatus::Building { diff --git a/src/ui/main_view.rs b/src/ui/main_view.rs index 8a2c145..c81a5a9 100644 --- a/src/ui/main_view.rs +++ b/src/ui/main_view.rs @@ -21,11 +21,11 @@ use crate::{ paths::{get_data_dir, get_home_dir}, profile::{LighthouseDriver, Profile, XRServiceType}, stateless_action, - ui::app::ThemeManagerAction, util::{ file_utils::{get_writer, mount_has_nosuid}, steamvr_utils::chaperone_info_exists, }, + vulkaninfo::VulkanInfo, wivrn_dbus, xr_devices::XRDevice, }; @@ -75,6 +75,8 @@ pub struct MainView { #[tracker::do_not_track] profile_export_action: gtk::gio::SimpleAction, xrservice_ready: bool, + #[tracker::do_not_track] + vkinfo: Option, wivrn_pairing_mode: bool, wivrn_pin: Option, wivrn_supports_pairing: bool, @@ -113,8 +115,7 @@ pub enum MainViewOutMsg { DoStartStopXRService, RestartXRService, ProfileSelected(Profile), - /// bool param: delete files - DeleteProfile(bool), + DeleteProfile, SaveProfile(Profile), OpenLibsurviveSetup, /// params: clean @@ -125,6 +126,7 @@ pub struct MainViewInit { pub config: Config, pub selected_profile: Profile, pub root_win: gtk::Window, + pub vkinfo: Option, } impl MainView { @@ -160,7 +162,6 @@ impl AsyncComponent for MainView { "Configure _WiVRn" => ConfigureWivrnAction, }, section! { - "Change _Theme" => ThemeManagerAction, "_About" => AboutAction, }, }, @@ -460,6 +461,34 @@ impl AsyncComponent 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", + set_visible: model + .vkinfo + .as_ref() + .is_some_and( + |i| i.has_nvidia_gpu && !i.has_monado_vulkan_layers + ), + warning_heading(), + gtk::Label { + set_label: concat!( + "An Nvidia GPU has been detected, but it ", + "seems you don't have the Monado Vulkan Layers ", + "installed on your system.\n\nInstall the ", + "Monado Vulkan Layers or your XR session will ", + "crash." + ), + 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, @@ -934,13 +963,6 @@ impl AsyncComponent for MainView { let profile_delete_confirm_dialog = adw::AlertDialog::builder() .heading("Are you sure you want to delete this profile?") - .extra_child( - >k::CheckButton::builder() - .label("Delete all files and folders associated with profile") - .halign(gtk::Align::Center) - .hexpand(true) - .build(), - ) .build(); profile_delete_confirm_dialog.add_response("no", "_No"); profile_delete_confirm_dialog.add_response("yes", "_Yes"); @@ -952,19 +974,10 @@ impl AsyncComponent for MainView { clone!( #[strong] sender, - move |dialog, res| { - let delete_files_checkbox = dialog - .extra_child() - .and_then(|child| child.downcast::().ok()); - let delete_files = delete_files_checkbox - .as_ref() - .is_some_and(|c| c.is_active()); - if let Some(check) = delete_files_checkbox { - check.set_active(false); - } + move |_, res| { if res == "yes" { sender - .output(Self::Output::DeleteProfile(delete_files)) + .output(Self::Output::DeleteProfile) .expect("Sender output failed"); } } @@ -1090,6 +1103,7 @@ impl AsyncComponent for MainView { xrservice_ready: false, profile_delete_action, profile_export_action, + vkinfo: init.vkinfo, wivrn_pairing_mode: false, wivrn_supports_pairing: false, wivrn_pin: None, diff --git a/src/ui/plugins/add_custom_plugin_win.rs b/src/ui/plugins/add_custom_plugin_win.rs index 734a4ea..c06f0c8 100644 --- a/src/ui/plugins/add_custom_plugin_win.rs +++ b/src/ui/plugins/add_custom_plugin_win.rs @@ -31,7 +31,6 @@ pub enum AddCustomPluginWinMsg { Present, Close, OnNameChange(String), - OnArgsChange(String), OnExecPathChange(Option), Add, } @@ -96,11 +95,7 @@ impl SimpleComponent for AddCustomPluginWin { "", clone!( #[strong] sender, - move |row| sender.input( - Self::Input::OnNameChange( - row.text().to_string() - ) - ) + move |row| sender.input(Self::Input::OnNameChange(row.text().to_string())) ) ), add: &file_row( @@ -110,23 +105,9 @@ impl SimpleComponent for AddCustomPluginWin { Some(model.parent.clone()), clone!( #[strong] sender, - move |path_s| sender.input( - Self::Input::OnExecPathChange(path_s) - ) + move |path_s| sender.input(Self::Input::OnExecPathChange(path_s)) ) - ), - add: &entry_row( - "Plugin Arguments", - "", - clone!( - #[strong] sender, - move |row| sender.input( - Self::Input::OnArgsChange( - row.text().to_string() - ) - ) - ) - ), + ) }, }, }, @@ -158,17 +139,6 @@ impl SimpleComponent for AddCustomPluginWin { self.plugin.name = name; self.set_can_add(self.plugin.validate()); } - Self::Input::OnArgsChange(args) => { - let args = args.trim().to_string(); - self.plugin.args = if args.is_empty() { - None - } else { - // it's fine to have them joined - // since they will ultimately be - // passed as a joined string - Some(vec![args]) - } - } Self::Input::OnExecPathChange(ep) => { self.plugin.exec_path = ep.map(PathBuf::from); self.set_can_add(self.plugin.validate()); diff --git a/src/ui/plugins/mod.rs b/src/ui/plugins/mod.rs index cb18440..8d2d792 100644 --- a/src/ui/plugins/mod.rs +++ b/src/ui/plugins/mod.rs @@ -165,8 +165,8 @@ impl Plugin { /// each manifest should be json and the link should always point to the latest version const MANIFESTS: [&str;3] = [ "https://github.com/galister/wlx-overlay-s/raw/refs/heads/meta/com.github.galister.wlx-overlay-s.json", - "https://github.com/StardustXR/telescope/raw/refs/heads/main/envision/org.stardustxr.telescope.json", "https://github.com/olekolek1000/wayvr-dashboard/raw/refs/heads/meta/dev.oo8.wayvr_dashboard.json", + "https://github.com/StardustXR/telescope/raw/refs/heads/main/envision/org.stardustxr.telescope.json", ]; pub async fn refresh_plugins() -> anyhow::Result>> { diff --git a/src/ui/preference_rows.rs b/src/ui/preference_rows.rs index bace44c..4502ebf 100644 --- a/src/ui/preference_rows.rs +++ b/src/ui/preference_rows.rs @@ -213,7 +213,7 @@ pub fn file_row) + 'static + Clone>( let filedialog = gtk::FileDialog::builder() .modal(true) - .title(format!("Select {title}")) + .title(format!("Select {}", title)) .build(); row.connect_activated(clone!( @@ -255,7 +255,7 @@ pub fn path_row) + 'static + Clone>( let (row, path_label) = filedialog_row_base(title, description, value, cb.clone()); let filedialog = gtk::FileDialog::builder() .modal(true) - .title(format!("Select Path for {title}")) + .title(format!("Select Path for {}", title)) .build(); row.connect_activated(clone!( diff --git a/src/ui/steam_launch_options_box.rs b/src/ui/steam_launch_options_box.rs index 28991b0..6956bfe 100644 --- a/src/ui/steam_launch_options_box.rs +++ b/src/ui/steam_launch_options_box.rs @@ -45,7 +45,8 @@ impl SimpleComponent for SteamLaunchOptionsBox { add_css_class: "dim-label", set_hexpand: true, set_label: format!( - "Set this string in the launch options of Steam games, so that they can pick up the {APP_NAME} runtime correctly") + "Set this string in the launch options of Steam games, so that they can pick up the {app} runtime correctly", + app = APP_NAME) .as_str(), set_xalign: 0.0, set_wrap: true, diff --git a/src/ui/wivrn_wired_start_box.rs b/src/ui/wivrn_wired_start_box.rs index b121c5f..503bcac 100644 --- a/src/ui/wivrn_wired_start_box.rs +++ b/src/ui/wivrn_wired_start_box.rs @@ -112,7 +112,7 @@ impl AsyncComponent for WivrnWiredStartBox { Self::Input::UpdateSelectedProfile(p) => self.set_selected_profile(p), Self::Input::StartWivrnClient => { if !dep_adb().check() { - alert("ADB is not installed", Some(&format!("Please install ADB on your computer to start the WiVRn client from {APP_NAME}.")), Some(&self.root_win)); + alert("ADB is not installed", Some(&format!("Please install ADB on your computer to start the WiVRn client from {}.", APP_NAME)), Some(&self.root_win)); return; } self.set_start_client_status(StartClientStatus::InProgress); diff --git a/src/util/file_utils.rs b/src/util/file_utils.rs index 04efb13..ff56926 100644 --- a/src/util/file_utils.rs +++ b/src/util/file_utils.rs @@ -1,4 +1,4 @@ -use crate::{async_process::async_process, depcheck::common::dep_getcap_setcap, profile::Profile}; +use crate::{async_process::async_process, profile::Profile}; use anyhow::bail; use nix::{ errno::Errno, @@ -79,29 +79,9 @@ pub fn set_file_readonly(path: &Path, readonly: bool) -> anyhow::Result<()> { Ok(fs::set_permissions(path, perms)?) } -pub fn setcap_executable() -> Option { - if dep_getcap_setcap().check() { - Some("setcap".into()) - } else if Path::new("/sbin/setcap").try_exists().unwrap_or_default() { - Some("/sbin/setcap".into()) - } else { - None - } -} - -pub fn getcap_executable() -> Option { - if dep_getcap_setcap().check() { - Some("getcap".into()) - } else if Path::new("/sbin/getcap").try_exists().unwrap_or_default() { - Some("/sbin/getcap".into()) - } else { - None - } -} - pub fn setcap_cap_sys_nice_eip_cmd(profile: &Profile) -> Vec { vec![ - setcap_executable().unwrap_or("setcap".into()), + "setcap".into(), "CAP_SYS_NICE=eip".into(), profile .prefix @@ -113,29 +93,24 @@ pub fn setcap_cap_sys_nice_eip_cmd(profile: &Profile) -> Vec { pub async fn verify_cap_sys_nice_eip(profile: &Profile) -> bool { let xrservice_binary = profile.xrservice_binary().to_string_lossy().to_string(); - if let Some(getcap_exec) = getcap_executable() { - match async_process(&getcap_exec, Some(&[&xrservice_binary]), None).await { - Err(e) => { - error!("failed to run `getcap {xrservice_binary}`: {e:?}"); + match async_process("getcap", Some(&[&xrservice_binary]), None).await { + Err(e) => { + error!("failed to run `getcap {xrservice_binary}`: {e:?}"); + false + } + Ok(out) => { + debug!("getcap {xrservice_binary} stdout: {}", out.stdout); + debug!("getcap {xrservice_binary} stderr: {}", out.stderr); + if out.exit_code != 0 { + error!( + "command `getcap {xrservice_binary}` failed with status code {}", + out.exit_code + ); false - } - Ok(out) => { - debug!("getcap {xrservice_binary} stdout: {}", out.stdout); - debug!("getcap {xrservice_binary} stderr: {}", out.stderr); - if out.exit_code != 0 { - error!( - "command `getcap {xrservice_binary}` failed with status code {}", - out.exit_code - ); - false - } else { - out.stdout.to_lowercase().contains("cap_sys_nice=eip") - } + } else { + out.stdout.to_lowercase().contains("cap_sys_nice=eip") } } - } else { - error!("getcap executable does not exist"); - false } } diff --git a/src/vulkaninfo.rs b/src/vulkaninfo.rs index 6d76a92..a8f8110 100644 --- a/src/vulkaninfo.rs +++ b/src/vulkaninfo.rs @@ -5,10 +5,12 @@ use ash::{ #[derive(Debug, Clone)] pub struct VulkanInfo { + pub has_nvidia_gpu: bool, + pub has_monado_vulkan_layers: bool, pub gpu_names: Vec, } -// const NVIDIA_VENDOR_ID: u32 = 0x10de; +const NVIDIA_VENDOR_ID: u32 = 0x10de; impl VulkanInfo { /// # Safety @@ -23,19 +25,40 @@ impl VulkanInfo { None, ) }?; + let mut has_nvidia_gpu = false; + let mut has_monado_vulkan_layers = false; let gpu_names = unsafe { instance.enumerate_physical_devices() }? .into_iter() .filter_map(|d| { - Some( - unsafe { instance.get_physical_device_properties(d) } - .device_name_as_c_str() - .ok()? - .to_string_lossy() - .to_string(), - ) + let props = unsafe { instance.get_physical_device_properties(d) }; + if props.vendor_id == NVIDIA_VENDOR_ID { + has_nvidia_gpu = true; + } + if !has_monado_vulkan_layers { + has_monado_vulkan_layers = + unsafe { instance.enumerate_device_layer_properties(d) } + .ok() + .map(|layerprops| { + layerprops.iter().any(|lp| { + lp.layer_name_as_c_str().is_ok_and(|name| { + name.to_string_lossy() + == "VK_LAYER_MND_enable_timeline_semaphore" + }) + }) + }) + == Some(true); + } + props + .device_name_as_c_str() + .ok() + .map(|cs| cs.to_string_lossy().to_string()) }) .collect(); unsafe { instance.destroy_instance(None) }; - Ok(Self { gpu_names }) + Ok(Self { + gpu_names, + has_nvidia_gpu, + has_monado_vulkan_layers, + }) } } diff --git a/test/files/wivrn_config2.json b/test/files/wivrn_config2.json index 7bd87ec..84676be 100644 --- a/test/files/wivrn_config2.json +++ b/test/files/wivrn_config2.json @@ -12,5 +12,5 @@ } ], "application": ["foobar", "baz"], - "tcp-only": true + "tcp_only": true }