From 3effef9080a377954ba8ddaa3303a357a0c7f888 Mon Sep 17 00:00:00 2001 From: Gabriele Musco Date: Thu, 15 Jun 2023 19:05:05 +0200 Subject: [PATCH] feat: can switch between steam and monado runtimes --- src/file_builders/active_runtime_json.rs | 7 ++-- src/file_builders/openvrpaths_vrpath.rs | 8 ++-- src/file_utils.rs | 28 ++++++++------ src/ui/app.rs | 15 ++++++++ src/ui/main_view.rs | 48 ++++++++++++++++++++++++ 5 files changed, 87 insertions(+), 19 deletions(-) diff --git a/src/file_builders/active_runtime_json.rs b/src/file_builders/active_runtime_json.rs index 6da1cb8..87f528f 100644 --- a/src/file_builders/active_runtime_json.rs +++ b/src/file_builders/active_runtime_json.rs @@ -3,7 +3,7 @@ use std::{fs::File, io::BufReader, path::Path}; use expect_dialog::ExpectDialog; use serde::{Deserialize, Serialize}; -use crate::{file_utils::{get_config_dir, get_data_dir, get_writer, set_file_radonly}, profile::Profile}; +use crate::{file_utils::{get_xdg_config_dir, get_xdg_data_dir, get_writer, set_file_radonly}, profile::Profile}; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct ActiveRuntimeInnerRuntime { @@ -22,7 +22,7 @@ pub struct ActiveRuntime { fn get_active_runtime_json_path() -> String { format!( "{config}/openxr/1/active_runtime.json", - config = get_config_dir() + config = get_xdg_config_dir() ) } @@ -50,7 +50,6 @@ pub fn get_current_active_runtime() -> Option { fn dump_active_runtime_to_path(active_runtime: ActiveRuntime, path_s: String) { set_file_radonly(&path_s, false); let writer = get_writer(&path_s); - // TODO: deal with write protection serde_json::to_writer_pretty(writer, &active_runtime) .expect_dialog("Unable to save active runtime"); set_file_radonly(&path_s, true); @@ -67,7 +66,7 @@ fn build_steam_active_runtime() -> ActiveRuntime { valve_runtime_is_steamvr: Some(true), library_path: format!( "{data}/Steam/steamapps/common/SteamVR/bin/linux64/vrclient.so", - data = get_data_dir() + data = get_xdg_data_dir() ), name: Some("SteamVR".into()), }, diff --git a/src/file_builders/openvrpaths_vrpath.rs b/src/file_builders/openvrpaths_vrpath.rs index 1bb1de3..b6ebcdb 100644 --- a/src/file_builders/openvrpaths_vrpath.rs +++ b/src/file_builders/openvrpaths_vrpath.rs @@ -3,7 +3,7 @@ use std::{fs::File, io::BufReader, path::Path}; use expect_dialog::ExpectDialog; use serde::{Deserialize, Serialize}; -use crate::{file_utils::{get_config_dir, get_data_dir, get_writer, set_file_radonly}, profile::Profile}; +use crate::{file_utils::{get_xdg_config_dir, get_xdg_data_dir, get_writer, set_file_radonly}, profile::Profile}; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct OpenVrPaths { @@ -18,7 +18,7 @@ pub struct OpenVrPaths { fn get_openvrpaths_vrpath_path() -> String { format!( "{config}/openvr/openvrpaths.vrpath", - config = get_config_dir() + config = get_xdg_config_dir() ) } @@ -59,7 +59,7 @@ pub fn dump_current_openvrpaths(ovr_paths: OpenVrPaths) { } fn build_steam_openvrpaths() -> OpenVrPaths { - let datadir = get_data_dir(); + let datadir = get_xdg_data_dir(); OpenVrPaths { config: vec![format!("{data}/Steam/config", data = datadir)], external_drivers: None, @@ -75,7 +75,7 @@ pub fn set_current_openvrpaths_to_steam() { } fn build_profile_openvrpaths(profile: Profile) -> OpenVrPaths { - let datadir = get_data_dir(); + let datadir = get_xdg_data_dir(); OpenVrPaths { config: vec![format!("{data}/Steam/config", data = datadir)], external_drivers: None, diff --git a/src/file_utils.rs b/src/file_utils.rs index 91f0c06..5a54521 100644 --- a/src/file_utils.rs +++ b/src/file_utils.rs @@ -1,6 +1,6 @@ use std::{ env, - fs::{self, create_dir_all, OpenOptions}, + fs::{self, create_dir_all, OpenOptions, remove_file}, io::BufWriter, path::Path, }; @@ -32,28 +32,34 @@ pub fn get_home_dir() -> String { env::var("HOME").expect_dialog("HOME env var not defined") } -pub fn get_config_dir() -> String { +pub fn get_xdg_config_dir() -> String { match env::var("XDG_CONFIG_HOME") { - Ok(conf_home) => format!("{conf_home}/{name}", conf_home = conf_home, name = CMD_NAME), + Ok(conf_home) => conf_home, Err(_) => format!( - "{home}/.config/{name}", - home = get_home_dir(), - name = CMD_NAME + "{home}/.config", + home = get_home_dir() ), } } -pub fn get_data_dir() -> String { +pub fn get_xdg_data_dir() -> String { match env::var("XDG_DATA_HOME") { - Ok(data_home) => format!("{data_home}/{name}", data_home = data_home, name = CMD_NAME), + Ok(data_home) => data_home, Err(_) => format!( - "{home}/.local/share/{name}", - home = get_home_dir(), - name = CMD_NAME + "{home}/.local/share", + home = get_home_dir() ), } } +pub fn get_config_dir() -> String { + format!("{config}/{name}", config = get_xdg_config_dir(), name = CMD_NAME) +} + +pub fn get_data_dir() -> String { + format!("{data}/{name}", data = get_xdg_data_dir(), name = CMD_NAME) +} + pub fn set_file_radonly(path_s: &String, readonly: bool) { let path = Path::new(&path_s); if !path.is_file() { diff --git a/src/ui/app.rs b/src/ui/app.rs index 5b87b70..fc4e1b1 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -9,6 +9,8 @@ use crate::config::{get_config, save_config, Config}; use crate::constants::APP_NAME; use crate::dependencies::libsurvive_deps::get_missing_libsurvive_deps; use crate::dependencies::monado_deps::get_missing_monado_deps; +use crate::file_builders::active_runtime_json::{set_current_active_runtime_to_profile, set_current_active_runtime_to_steam}; +use crate::file_builders::openvrpaths_vrpath::{set_current_openvrpaths_to_profile, set_current_openvrpaths_to_steam}; use crate::profile::Profile; use crate::profiles::valve_index::valve_index_profile; use crate::runner::{Runner, RunnerStatus}; @@ -59,6 +61,7 @@ pub enum Msg { EnableDebugViewChanged(bool), DoStartStopMonado, ProfileSelected(String), + SetMonadoRuntime(bool), } impl App { @@ -254,6 +257,17 @@ impl SimpleComponent for App { self.config.selected_profile_name = prof_name; save_config(&self.config); } + Msg::SetMonadoRuntime(monado) => { + if monado { + let profile = self.get_selected_profile(); + set_current_active_runtime_to_profile(profile.clone()); + set_current_openvrpaths_to_profile(profile.clone()); + } + else { + set_current_active_runtime_to_steam(); + set_current_openvrpaths_to_steam(); + } + } } } @@ -281,6 +295,7 @@ impl SimpleComponent for App { MainViewOutMsg::EnableDebugViewChanged(val) => Msg::EnableDebugViewChanged(val), MainViewOutMsg::DoStartStopMonado => Msg::DoStartStopMonado, MainViewOutMsg::ProfileSelected(name) => Msg::ProfileSelected(name), + MainViewOutMsg::SetMonadoRuntime(monado) => Msg::SetMonadoRuntime(monado), }), debug_view: DebugView::builder() .launch(DebugViewInit { diff --git a/src/ui/main_view.rs b/src/ui/main_view.rs index ea4d009..0f6b7e4 100644 --- a/src/ui/main_view.rs +++ b/src/ui/main_view.rs @@ -1,5 +1,6 @@ use crate::config::Config; use crate::constants::APP_NAME; +use crate::file_builders::active_runtime_json::{self, get_current_active_runtime}; use crate::ui::app::{AboutAction, BuildProfileAction, DebugViewToggleAction}; use expect_dialog::ExpectDialog; use gtk::prelude::*; @@ -31,6 +32,7 @@ pub enum MainViewOutMsg { EnableDebugViewChanged(bool), DoStartStopMonado, ProfileSelected(String), + SetMonadoRuntime(bool), } pub struct MainViewInit { @@ -114,6 +116,37 @@ impl SimpleComponent for MainView { sender.input(MainViewMsg::StartStopClicked) }, }, + gtk::Separator { + set_orientation: gtk::Orientation::Horizontal, + set_hexpand: true, + }, + gtk::Label { + add_css_class: "heading", + set_hexpand: true, + set_xalign: 0.0, + set_margin_start: 12, + set_margin_end: 12, + set_label: "OpenXR/OpenVR Runtime", + set_wrap: true, + set_wrap_mode: gtk::pango::WrapMode::Word, + }, + gtk::Box { + set_orientation: gtk::Orientation::Horizontal, + set_hexpand: true, + set_halign: gtk::Align::Start, + set_margin_start: 12, + set_margin_end: 12, + set_spacing: 12, + gtk::Label { + set_label: "Steam", + }, + #[name(runtime_switch)] + gtk::Switch { + }, + gtk::Label { + set_label: "Monado" + }, + }, gtk::Box { set_orientation: gtk::Orientation::Vertical, set_hexpand: true, @@ -226,6 +259,21 @@ impl SimpleComponent for MainView { }; let widgets = view_output!(); + { + match get_current_active_runtime() { + None => {} + Some(runtime) => { + widgets + .runtime_switch + .set_active(!active_runtime_json::is_steam(runtime)); + } + } + widgets.runtime_switch.connect_state_set(move |_, state| { + sender.output(MainViewOutMsg::SetMonadoRuntime(state)); + gtk::Inhibit(false) + }); + } + ComponentParts { model, widgets } } }