diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 407601c..086c19c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -22,8 +22,8 @@ cargo:test: script: - echo 'deb http://deb.debian.org/debian experimental main' > /etc/apt/sources.list.d/experimental.list - apt-get update - - apt-get -t experimental install libgtk-4-dev libadwaita-1-dev libgtksourceview-5-dev libssl-dev -y - - apt-get install meson ninja-build git desktop-file-utils gettext libjxl-dev file libusb-dev libusb-1.0-0-dev curl -y + - apt-get -t experimental install libgtk-4-dev libadwaita-1-dev libgtksourceview-5-dev libssl-dev libjxl-dev -y + - apt-get install meson ninja-build git desktop-file-utils gettext file libusb-dev libusb-1.0-0-dev curl -y - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/rustup.sh - chmod +x /tmp/rustup.sh - /tmp/rustup.sh -y @@ -41,8 +41,8 @@ appimage: script: - echo 'deb http://deb.debian.org/debian experimental main' > /etc/apt/sources.list.d/experimental.list - apt-get update - - apt-get -t experimental install libgtk-4-dev libadwaita-1-dev libgtksourceview-5-dev libssl-dev -y - - apt-get install meson ninja-build git desktop-file-utils gettext libjxl-dev file libusb-dev libusb-1.0-0-dev curl -y + - apt-get -t experimental install libgtk-4-dev libadwaita-1-dev libgtksourceview-5-dev libssl-dev libjxl-dev -y + - apt-get install meson ninja-build git desktop-file-utils gettext file libusb-dev libusb-1.0-0-dev curl -y - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/rustup.sh - chmod +x /tmp/rustup.sh - /tmp/rustup.sh -y diff --git a/Cargo.lock b/Cargo.lock index 9e7d88d..f48193a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1068,7 +1068,7 @@ dependencies = [ [[package]] name = "libmonado-rs" version = "0.1.0" -source = "git+https://github.com/technobaboo/libmonado-rs#3b3f098cb131843ee90f078e26362fcefe02b822" +source = "git+https://github.com/technobaboo/libmonado-rs#d79d5bf11586b8010d8aa016097ebdb07f683c64" dependencies = [ "bindgen", "cmake", diff --git a/README.md b/README.md index b5056bb..68a2fa9 100644 --- a/README.md +++ b/README.md @@ -33,14 +33,6 @@ cd envision ./dist/appimage/build_appimage.sh ``` - - # Common issues ## NOSUID with systemd-homed diff --git a/meson.build b/meson.build index f9f34a6..36ec669 100644 --- a/meson.build +++ b/meson.build @@ -61,6 +61,7 @@ meson.add_dist_script( global_conf = configuration_data() global_conf.set('APP_ID', application_id) +global_conf.set('RESOURCES_BASE_PATH', '/' + base_id.replace('.', '/')) global_conf.set('PKGDATADIR', pkgdatadir) global_conf.set('PROFILE', profile) global_conf.set('VERSION', version + version_suffix) diff --git a/src/builders/build_libsurvive.rs b/src/builders/build_libsurvive.rs index 4545c99..61dd992 100644 --- a/src/builders/build_libsurvive.rs +++ b/src/builders/build_libsurvive.rs @@ -30,6 +30,7 @@ pub fn get_build_libsurvive_jobs(profile: &Profile, clean_build: bool) -> VecDeq let mut cmake_vars: HashMap = HashMap::new(); cmake_vars.insert("CMAKE_BUILD_TYPE".into(), "Release".into()); cmake_vars.insert("ENABLE_api_example".into(), "OFF".into()); + cmake_vars.insert("USE_HIDAPI".into(), "ON".into()); cmake_vars.insert("CMAKE_SKIP_INSTALL_RPATH".into(), "YES".into()); cmake_vars.insert("CMAKE_INSTALL_PREFIX".into(), profile.prefix.clone()); cmake_vars.insert( diff --git a/src/constants.rs.in b/src/constants.rs.in index 79639a5..a77737c 100644 --- a/src/constants.rs.in +++ b/src/constants.rs.in @@ -2,6 +2,7 @@ use crate::paths::get_exec_prefix; pub const APP_NAME: &str = "@PRETTY_NAME@"; pub const APP_ID: &str = "@APP_ID@"; +pub const RESOURCES_BASE_PATH: &str = "@RESOURCES_BASE_PATH@"; pub const PKG_DATA_DIR: &str = "@PKGDATADIR@"; pub const RESOURCES: &str = concat!("@PKGDATADIR@", "/resources.gresource"); pub const CMD_NAME: &str = "@CMD_NAME@"; diff --git a/src/downloader.rs b/src/downloader.rs index bc78be6..5e1d3f8 100644 --- a/src/downloader.rs +++ b/src/downloader.rs @@ -1,4 +1,4 @@ -use crate::file_utils::get_writer; +use crate::{constants::APP_ID, file_utils::get_writer}; use reqwest::{ header::{HeaderMap, USER_AGENT}, Method, @@ -11,7 +11,7 @@ const CHUNK_SIZE: usize = 1024; fn headers() -> HeaderMap { let mut headers = HeaderMap::new(); - headers.insert(USER_AGENT, "org.gabmus.envision/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 d71b94b..e5b5f21 100644 --- a/src/env_var_descriptions.rs +++ b/src/env_var_descriptions.rs @@ -22,7 +22,7 @@ pub static ENV_VAR_DESCRIPTIONS: Map<&str, &str> = phf_map! { pub fn env_var_descriptions_as_paragraph() -> String { ENV_VAR_DESCRIPTIONS .into_iter() - .map(|(k, v)| format!("{}: {}", k, v)) + .map(|(k, v)| format!(" \u{2022} {}: {}", k, v)) .collect::>() .join("\n\n") } diff --git a/src/main.rs b/src/main.rs index a02f595..43d775e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,10 @@ -use std::env; - use anyhow::Result; -use constants::{resources, APP_ID, APP_NAME, GETTEXT_PACKAGE, LOCALE_DIR}; +use constants::{resources, APP_ID, APP_NAME, GETTEXT_PACKAGE, LOCALE_DIR, RESOURCES_BASE_PATH}; use file_builders::{ active_runtime_json::{get_current_active_runtime, set_current_active_runtime_to_steam}, openvrpaths_vrpath::{get_current_openvrpaths, set_current_openvrpaths_to_steam}, }; use gettextrs::LocaleCategory; -use gtk::prelude::ObjectExt; use relm4::{ adw, gtk::{self, gdk, gio, glib}, @@ -83,7 +80,7 @@ fn main() -> Result<()> { } let provider = gtk::CssProvider::new(); - provider.load_from_resource("/org/gabmus/envision/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/profile.rs b/src/profile.rs index ed7694b..651f224 100644 --- a/src/profile.rs +++ b/src/profile.rs @@ -236,26 +236,45 @@ impl Display for Profile { impl Default for Profile { fn default() -> Self { + let uuid = Uuid::new_v4().to_string(); + let profile_dir = format!("{}/{}", get_data_dir(), uuid); Self { - uuid: Uuid::new_v4().to_string(), name: "Default profile name".into(), - xrservice_path: data_monado_path(), + xrservice_path: format!("{}/xrservice", profile_dir), xrservice_type: XRServiceType::Monado, xrservice_repo: None, xrservice_cmake_flags: HashMap::::default(), - opencomposite_path: data_opencomposite_path(), - features: ProfileFeatures::default(), + features: ProfileFeatures { + libsurvive: ProfileFeature { + enabled: false, + path: Some(format!("{}/libsurvive", profile_dir)), + repo: None, + feature_type: ProfileFeatureType::Libsurvive, + }, + basalt: ProfileFeature { + enabled: false, + path: Some(format!("{}/basalt", profile_dir)), + repo: None, + feature_type: ProfileFeatureType::Basalt, + }, + openhmd: ProfileFeature { + enabled: false, + path: Some(format!("{}/openhmd", profile_dir)), + repo: None, + feature_type: ProfileFeatureType::OpenHmd, + }, + mercury_enabled: false, + }, environment: HashMap::new(), - prefix: format!( - "{data}/prefixes/default_profile_prefix", - data = get_data_dir() - ), + prefix: format!("{}/prefixes/{}", get_data_dir(), uuid), can_be_built: true, pull_on_build: true, opencomposite_repo: None, + opencomposite_path: format!("{}/opencomposite", profile_dir), editable: true, lighthouse_driver: LighthouseDriver::default(), xrservice_launch_options: String::default(), + uuid, } } } @@ -307,10 +326,30 @@ impl Profile { } pub fn create_duplicate(&self) -> Self { - let mut dup = self.clone(); - dup.uuid = Uuid::new_v4().to_string(); - dup.editable = true; - dup.name = format!("Duplicate of {}", dup.name); + if !self.can_be_built { + let mut dup = self.clone(); + dup.uuid = Uuid::new_v4().to_string(); + dup.name = format!("Duplicate of {}", dup.name); + dup.editable = true; + return dup; + } + let mut dup = Self::default(); + dup.name = format!("Duplicate of {}", self.name); + dup.xrservice_type = self.xrservice_type.clone(); + dup.xrservice_repo = self.xrservice_repo.clone(); + dup.xrservice_cmake_flags = self.xrservice_cmake_flags.clone(); + dup.features.libsurvive.enabled = self.features.libsurvive.enabled; + dup.features.libsurvive.repo = self.features.libsurvive.repo.clone(); + dup.features.basalt.enabled = self.features.basalt.enabled; + dup.features.basalt.repo = self.features.basalt.repo.clone(); + dup.features.openhmd.enabled = self.features.openhmd.enabled; + dup.features.openhmd.repo = self.features.openhmd.repo.clone(); + dup.features.mercury_enabled = self.features.mercury_enabled; + dup.environment = self.environment.clone(); + dup.pull_on_build = self.pull_on_build; + dup.opencomposite_repo = self.opencomposite_repo.clone(); + dup.lighthouse_driver = self.lighthouse_driver; + dup.xrservice_launch_options = self.xrservice_launch_options.clone(); dup } @@ -347,10 +386,14 @@ impl Profile { } pub fn xrservice_binary(&self) -> String { - match self.xrservice_type { - XRServiceType::Monado => format!("{pfx}/bin/monado-service", pfx = self.prefix), - XRServiceType::Wivrn => format!("{pfx}/bin/wivrn-server", pfx = self.prefix), - } + format!( + "{}/bin/{}", + self.prefix, + match self.xrservice_type { + XRServiceType::Monado => "monado-service", + XRServiceType::Wivrn => "wivrn-server", + } + ) } pub fn can_start(&self) -> bool { diff --git a/src/ui/debug_view.rs b/src/ui/debug_view.rs index 4eb7657..d695a82 100644 --- a/src/ui/debug_view.rs +++ b/src/ui/debug_view.rs @@ -61,7 +61,7 @@ impl SimpleComponent for DebugView { menu! { debug_menu: { section! { - "Open Envision _Data Folder" => DebugOpenDataAction, + "Open _Data Folder" => DebugOpenDataAction, "Open _Prefix Folder" => DebugOpenPrefixAction, }, } diff --git a/src/ui/feature_flags.rs b/src/ui/feature_flags.rs deleted file mode 100644 index 3697538..0000000 --- a/src/ui/feature_flags.rs +++ /dev/null @@ -1,11 +0,0 @@ -use lazy_static::lazy_static; -use std::env; - -fn get_ff_libmonado_device_enumeration_enabled() -> bool { - env::var("ENVISION_FF_USE_LIBMONADO").unwrap_or_default() == "1" -} - -lazy_static! { - pub static ref FF_LIBMONADO_DEVICE_ENUMERATION_ENABLED: bool = - get_ff_libmonado_device_enumeration_enabled(); -} diff --git a/src/ui/main_view.rs b/src/ui/main_view.rs index 5f067c5..0274790 100644 --- a/src/ui/main_view.rs +++ b/src/ui/main_view.rs @@ -228,7 +228,7 @@ impl SimpleComponent for MainView { set_label: concat!( "Your current prefix is inside a partition ", "mounted with the nosuid option. This will prevent ", - "the Envision runtime from acquiring certain privileges ", + "the XR runtime from acquiring certain privileges ", "and will cause noticeable stutter when running XR ", "applications." ), diff --git a/src/ui/mod.rs b/src/ui/mod.rs index e5f0204..5250eae 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -6,7 +6,6 @@ pub mod debug_view; pub mod devices_box; pub mod factories; pub mod fbt_config_editor; -pub mod feature_flags; pub mod install_wivrn_box; pub mod job_worker; pub mod libsurvive_setup_window; diff --git a/src/ui/preference_rows.rs b/src/ui/preference_rows.rs index 9947d3e..b0f6d99 100644 --- a/src/ui/preference_rows.rs +++ b/src/ui/preference_rows.rs @@ -179,6 +179,7 @@ pub fn path_row) + 'static + Clone>( None => "(None)", Some(p) => p.as_str(), }) + .wrap(true) .build(); row.add_suffix(path_label); diff --git a/src/ui/profile_editor.rs b/src/ui/profile_editor.rs index 20e1ed2..b3127b3 100644 --- a/src/ui/profile_editor.rs +++ b/src/ui/profile_editor.rs @@ -146,9 +146,9 @@ impl SimpleComponent for ProfileEditor { "Lighthouse Driver", Some(concat!( "Driver for lighhouse tracked XR devices (ie: Valve Index, HTC Vive...). Only applicable for Monado.\n\n", - "Vive: 3DOF tracking\n\n", - "Survive: 6DOF reverse engineered lighthouse tracking provided by Libsurvive\n\n", - "SteamVR: 6DOF lighthouse tracking using the proprietary SteamVR driver", + " \u{2022} Vive: 3DOF tracking\n", + " \u{2022} Survive: 6DOF reverse engineered lighthouse tracking provided by Libsurvive\n", + " \u{2022} SteamVR: 6DOF lighthouse tracking using the proprietary SteamVR driver", )), model.profile.borrow().lighthouse_driver.to_string().as_str(), LighthouseDriver::iter() diff --git a/src/ui/steamvr_calibration_box.rs b/src/ui/steamvr_calibration_box.rs index 58c8988..21061b7 100644 --- a/src/ui/steamvr_calibration_box.rs +++ b/src/ui/steamvr_calibration_box.rs @@ -69,11 +69,11 @@ impl SimpleComponent for SteamVrCalibrationBox { set_hexpand: true, set_label: concat!( "Run a quick SteamVR calibration.\n\n", - "\u{2022} Plug in your HMD and place it on the floor, ", + " \u{2022} Plug in your HMD and place it on the floor, ", "approximately in the middle of your play area\n", - "\u{2022} Make sure your controllers and other VR devices ", + " \u{2022} Make sure your controllers and other VR devices ", "are turned off\n", - "\u{2022} Click the Calibrate button and wait for the ", + " \u{2022} Click the Calibrate button and wait for the ", "process to finish\n\n", "Note that the orientation of your HMD during this process ", "will dictate the forward direction of your play area.", diff --git a/src/xr_devices.rs b/src/xr_devices.rs index c7b8122..dce6af6 100644 --- a/src/xr_devices.rs +++ b/src/xr_devices.rs @@ -11,6 +11,21 @@ pub enum XRDeviceRole { Eyes, HandTrackingLeft, HandTrackingRight, + + HandheldObject, + LeftFoot, + RightFoot, + LeftShoulder, + RightShoulder, + LeftElbow, + RightElbow, + LeftKnee, + RightKnee, + Waist, + Chest, + Camera, + Keyboard, + GenericTracker, /** * Devices with no role @@ -34,6 +49,21 @@ impl Display for XRDeviceRole { Self::Eyes => "Eye Tracking", Self::HandTrackingLeft => "Hand tracking left", Self::HandTrackingRight => "Hand tracking right", + + Self::HandheldObject => "Handheld object", + Self::LeftFoot => "Left foot", + Self::RightFoot => "Right foot", + Self::LeftShoulder => "Left shoulder", + Self::RightShoulder => "Right shoulder", + Self::LeftElbow => "Left elbow", + Self::RightElbow => "Right elbow", + Self::LeftKnee => "Left knee", + Self::RightKnee => "Right knee", + Self::Waist => "Waist", + Self::Chest => "Chest", + Self::Camera => "Camera", + Self::Keyboard => "Keyboard", + Self::GenericTracker => "Generic tracker", Self::Other => "", }) @@ -62,6 +92,19 @@ impl XRDeviceRole { Self::Eyes, Self::HandTrackingLeft, Self::HandTrackingRight, + Self::HandheldObject, + Self::LeftFoot, + Self::RightFoot, + Self::LeftShoulder, + Self::RightShoulder, + Self::LeftElbow, + Self::RightElbow, + Self::LeftKnee, + Self::RightKnee, + Self::Waist, + Self::Chest, + Self::Camera, + Self::Keyboard, Self::GenericTracker, ] .iter() @@ -76,6 +119,21 @@ impl XRDeviceRole { Self::Eyes => "eyes", Self::HandTrackingLeft => "hand-tracking-left", Self::HandTrackingRight => "hand-tracking-right", + + Self::HandheldObject => "handheld-object", + Self::LeftFoot => "left-foot", + Self::RightFoot => "right-foot", + Self::LeftShoulder => "left-shoulder", + Self::RightShoulder => "right-shoulder", + Self::LeftElbow => "left-elbow", + Self::RightElbow => "right-elbow", + Self::LeftKnee => "left-knee", + Self::RightKnee => "right-knee", + Self::Waist => "waist", + Self::Chest => "chest", + Self::Camera => "camera", + Self::Keyboard => "keyboard", + Self::GenericTracker => "generic-tracker", // not actually in monado Self::Other => "other", // not actually in monado } @@ -90,8 +148,23 @@ impl XRDeviceRole { Self::Eyes => 4, Self::HandTrackingLeft => 5, Self::HandTrackingRight => 6, - Self::GenericTracker => 7, - Self::Other => 8, + + Self::HandheldObject => 7, + Self::LeftFoot => 8, + Self::RightFoot => 9, + Self::LeftShoulder => 10, + Self::RightShoulder => 11, + Self::LeftElbow => 12, + Self::RightElbow => 13, + Self::LeftKnee => 14, + Self::RightKnee => 15, + Self::Waist => 16, + Self::Chest => 17, + Self::Camera => 18, + Self::Keyboard => 19, + + Self::GenericTracker => 20, + Self::Other => 21, } } @@ -104,6 +177,19 @@ impl XRDeviceRole { "eyes" => Some(Self::Eyes), "hand-tracking-left" => Some(Self::HandTrackingLeft), "hand-tracking-right" => Some(Self::HandTrackingRight), + "handheld-object" => Some(Self::HandheldObject), + "left-foot" => Some(Self::LeftFoot), + "right-foot" => Some(Self::RightFoot), + "left-shoulder" => Some(Self::LeftShoulder), + "right-shoulder" => Some(Self::RightShoulder), + "left-elbow" => Some(Self::LeftElbow), + "right-elbow" => Some(Self::RightElbow), + "left-knee" => Some(Self::LeftKnee), + "right-knee" => Some(Self::RightKnee), + "waist" => Some(Self::Waist), + "chest" => Some(Self::Chest), + "camera" => Some(Self::Camera), + "keyboard" => Some(Self::Keyboard), _ => None, } } @@ -117,6 +203,21 @@ impl XRDeviceRole { "Eye Tracking" => Self::Eyes, "Hand tracking left" => Self::HandTrackingLeft, "Hand tracking right" => Self::HandTrackingRight, + + "Handheld object" => Self::HandheldObject, + "Left foot" => Self::LeftFoot, + "Right foot" => Self::RightFoot, + "Left shoulder" => Self::LeftShoulder, + "Right shoulder" => Self::RightShoulder, + "Left elbow" => Self::LeftElbow, + "Right elbow" => Self::RightElbow, + "Left knee" => Self::LeftKnee, + "Right knee" => Self::RightKnee, + "Waist" => Self::Waist, + "Chest" => Self::Chest, + "Camera" => Self::Camera, + "Keyboard" => Self::Keyboard, + "Generic tracker" => Self::GenericTracker, _ => Self::GenericTracker, } @@ -179,6 +280,19 @@ impl XRDevice { XRDeviceRole::Right, XRDeviceRole::HandTrackingLeft, XRDeviceRole::HandTrackingRight, + XRDeviceRole::HandheldObject, + XRDeviceRole::LeftFoot, + XRDeviceRole::RightFoot, + XRDeviceRole::LeftShoulder, + XRDeviceRole::RightShoulder, + XRDeviceRole::LeftElbow, + XRDeviceRole::RightElbow, + XRDeviceRole::LeftKnee, + XRDeviceRole::RightKnee, + XRDeviceRole::Waist, + XRDeviceRole::Chest, + XRDeviceRole::Camera, + XRDeviceRole::Keyboard, XRDeviceRole::Gamepad, XRDeviceRole::Eyes, ]