mirror of
https://gitlab.com/gabmus/envision.git
synced 2025-08-04 15:18:58 +00:00
fix: clippy cleanup
This commit is contained in:
parent
2addb6ae63
commit
8907767135
34 changed files with 252 additions and 217 deletions
8
Cargo.lock
generated
8
Cargo.lock
generated
|
@ -2140,18 +2140,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracker"
|
name = "tracker"
|
||||||
version = "0.2.1"
|
version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ff9636d15e370187f6bf55b79ce62ebf4221998bc0ba1774d7fa208b007f6bf8"
|
checksum = "ce5c98457ff700aaeefcd4a4a492096e78a2af1dd8523c66e94a3adb0fdbd415"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"tracker-macros",
|
"tracker-macros",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracker-macros"
|
name = "tracker-macros"
|
||||||
version = "0.2.1"
|
version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ca029746fbe0efda3298205de77bf759d7fef23ac97902641e0b49a623b0455f"
|
checksum = "dc19eb2373ccf3d1999967c26c3d44534ff71ae5d8b9dacf78f4b13132229e48"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use std::path::PathBuf;
|
use std::path::Path;
|
||||||
|
|
||||||
use crate::cmd_runner::CmdRunner;
|
use crate::cmd_runner::CmdRunner;
|
||||||
|
|
||||||
pub fn get_adb_install_runner(path: &PathBuf) -> CmdRunner {
|
pub fn get_adb_install_runner(path: &Path) -> CmdRunner {
|
||||||
path.try_exists().expect("APK file provided does not exist");
|
path.try_exists().expect("APK file provided does not exist");
|
||||||
CmdRunner::new(
|
CmdRunner::new(
|
||||||
None,
|
None,
|
||||||
|
|
|
@ -52,17 +52,11 @@ pub fn get_build_monado_jobs(profile: &Profile, clean_build: bool) -> VecDeque<W
|
||||||
);
|
);
|
||||||
cmake_vars.insert(
|
cmake_vars.insert(
|
||||||
"CMAKE_C_FLAGS".into(),
|
"CMAKE_C_FLAGS".into(),
|
||||||
format!(
|
format!("-Wl,-rpath='{}/lib'", profile.prefix.to_string_lossy(),),
|
||||||
"-Wl,-rpath='{}/lib'",
|
|
||||||
profile.prefix.to_string_lossy().to_string(),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
cmake_vars.insert(
|
cmake_vars.insert(
|
||||||
"CMAKE_CXX_FLAGS".into(),
|
"CMAKE_CXX_FLAGS".into(),
|
||||||
format!(
|
format!("-Wl,-rpath='{}/lib'", profile.prefix.to_string_lossy(),),
|
||||||
"-Wl,-rpath='{}/lib'",
|
|
||||||
profile.prefix.to_string_lossy().to_string(),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
profile.xrservice_cmake_flags.iter().for_each(|(k, v)| {
|
profile.xrservice_cmake_flags.iter().for_each(|(k, v)| {
|
||||||
if k == "CMAKE_C_FLAGS" || k == "CMAKE_CXX_FLAGS" {
|
if k == "CMAKE_C_FLAGS" || k == "CMAKE_CXX_FLAGS" {
|
||||||
|
|
|
@ -14,7 +14,7 @@ use crate::{
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
io::{BufRead, BufReader, Write},
|
io::{BufRead, BufReader, Write},
|
||||||
path::PathBuf,
|
path::Path,
|
||||||
process::{Child, Command, Stdio},
|
process::{Child, Command, Stdio},
|
||||||
sync::{
|
sync::{
|
||||||
mpsc::{sync_channel, Receiver, SyncSender},
|
mpsc::{sync_channel, Receiver, SyncSender},
|
||||||
|
@ -174,13 +174,13 @@ impl CmdRunner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn save_log(path: &PathBuf, log: &[String]) -> Result<(), std::io::Error> {
|
fn save_log(path: &Path, log: &[String]) -> Result<(), std::io::Error> {
|
||||||
let mut writer = get_writer(path).map_err(std::io::Error::other)?;
|
let mut writer = get_writer(path).map_err(std::io::Error::other)?;
|
||||||
let log_s = log.concat();
|
let log_s = log.concat();
|
||||||
writer.write_all(log_s.as_ref())
|
writer.write_all(log_s.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save_output(&mut self, path: &PathBuf) -> Result<(), std::io::Error> {
|
pub fn save_output(&mut self, path: &Path) -> Result<(), std::io::Error> {
|
||||||
CmdRunner::save_log(path, &self.output)
|
CmdRunner::save_log(path, &self.output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,7 +222,7 @@ mod tests {
|
||||||
use crate::profile::Profile;
|
use crate::profile::Profile;
|
||||||
use crate::runner::Runner;
|
use crate::runner::Runner;
|
||||||
use core::time;
|
use core::time;
|
||||||
use std::{collections::HashMap, thread::sleep};
|
use std::{collections::HashMap, path::Path, thread::sleep};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_run_command_and_read_env() {
|
fn can_run_command_and_read_env() {
|
||||||
|
@ -254,14 +254,14 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
runner
|
runner
|
||||||
.save_output(&"./target/testout/testlog".into())
|
.save_output(Path::new("./target/testout/testlog"))
|
||||||
.expect("Failed to save output file");
|
.expect("Failed to save output file");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_create_from_profile() {
|
fn can_create_from_profile() {
|
||||||
CmdRunner::xrservice_runner_from_profile(&Profile::load_profile(
|
CmdRunner::xrservice_runner_from_profile(&Profile::load_profile(Path::new(
|
||||||
&"./test/files/profile.json".into(),
|
"./test/files/profile.json",
|
||||||
));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,11 @@ use crate::{
|
||||||
survive::survive_profile, wivrn::wivrn_profile, wmr::wmr_profile,
|
survive::survive_profile, wivrn::wivrn_profile, wmr::wmr_profile,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use std::{fs::File, io::BufReader, path::PathBuf};
|
use std::{
|
||||||
|
fs::File,
|
||||||
|
io::BufReader,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
fn default_win_size() -> [i32; 2] {
|
fn default_win_size() -> [i32; 2] {
|
||||||
[360, 400]
|
[360, 400]
|
||||||
|
@ -40,14 +44,14 @@ impl Default for Config {
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
pub fn get_selected_profile(&self, profiles: &[Profile]) -> Profile {
|
pub fn get_selected_profile(&self, profiles: &[Profile]) -> Profile {
|
||||||
let def = || profiles.get(0).expect("No profiles found").clone();
|
let def = || profiles.first().expect("No profiles found").clone();
|
||||||
|
|
||||||
match profiles
|
match profiles
|
||||||
.iter()
|
.iter()
|
||||||
.find(|p| p.uuid == self.selected_profile_uuid)
|
.find(|p| p.uuid == self.selected_profile_uuid)
|
||||||
{
|
{
|
||||||
Some(p) => p.clone(),
|
Some(p) => p.clone(),
|
||||||
None => match get_xr_usb_devices().get(0) {
|
None => match get_xr_usb_devices().first() {
|
||||||
Some(dev) => match dev.get_default_profile() {
|
Some(dev) => match dev.get_default_profile() {
|
||||||
Some(p) => p,
|
Some(p) => p,
|
||||||
None => def(),
|
None => def(),
|
||||||
|
@ -61,7 +65,7 @@ impl Config {
|
||||||
get_config_dir().join(format!("{CMD_NAME}.json"))
|
get_config_dir().join(format!("{CMD_NAME}.json"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_path(path: &PathBuf) -> Self {
|
fn from_path(path: &Path) -> Self {
|
||||||
match File::open(path) {
|
match File::open(path) {
|
||||||
Ok(file) => {
|
Ok(file) => {
|
||||||
let reader = BufReader::new(file);
|
let reader = BufReader::new(file);
|
||||||
|
@ -74,7 +78,7 @@ impl Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn save_to_path(&self, path: &PathBuf) -> Result<(), serde_json::Error> {
|
fn save_to_path(&self, path: &Path) -> Result<(), serde_json::Error> {
|
||||||
let writer = get_writer(path).map_err(serde_json::Error::custom)?;
|
let writer = get_writer(path).map_err(serde_json::Error::custom)?;
|
||||||
serde_json::to_writer_pretty(writer, self)
|
serde_json::to_writer_pretty(writer, self)
|
||||||
}
|
}
|
||||||
|
@ -109,13 +113,12 @@ impl Config {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn will_load_default_if_config_does_not_exist() {
|
fn will_load_default_if_config_does_not_exist() {
|
||||||
assert_eq!(
|
assert!(!Config::from_path(Path::new("/non/existing/file.json")).debug_view_enabled,)
|
||||||
Config::from_path(&"/non/existing/file.json".into()).debug_view_enabled,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,5 +24,5 @@ pub fn pkg_data_dir() -> PathBuf {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resources() -> String {
|
pub fn resources() -> String {
|
||||||
format!("{}/resources.gresource", pkg_data_dir().to_string_lossy().to_string())
|
format!("{}/resources.gresource", pkg_data_dir().to_string_lossy())
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ fn backup_steam_active_runtime() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_active_runtime_from_path(path: &PathBuf) -> Option<ActiveRuntime> {
|
fn get_active_runtime_from_path(path: &Path) -> Option<ActiveRuntime> {
|
||||||
deserialize_file(path)
|
deserialize_file(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ pub fn get_current_active_runtime() -> Option<ActiveRuntime> {
|
||||||
|
|
||||||
fn dump_active_runtime_to_path(
|
fn dump_active_runtime_to_path(
|
||||||
active_runtime: &ActiveRuntime,
|
active_runtime: &ActiveRuntime,
|
||||||
path: &PathBuf,
|
path: &Path,
|
||||||
) -> Result<(), serde_json::Error> {
|
) -> Result<(), serde_json::Error> {
|
||||||
let writer = get_writer(path).map_err(serde_json::Error::custom)?;
|
let writer = get_writer(path).map_err(serde_json::Error::custom)?;
|
||||||
serde_json::to_writer_pretty(writer, active_runtime)
|
serde_json::to_writer_pretty(writer, active_runtime)
|
||||||
|
@ -101,7 +101,9 @@ pub fn set_current_active_runtime_to_steam() -> anyhow::Result<()> {
|
||||||
|
|
||||||
pub fn build_profile_active_runtime(profile: &Profile) -> ActiveRuntime {
|
pub fn build_profile_active_runtime(profile: &Profile) -> ActiveRuntime {
|
||||||
let build_path = |lib64: bool, prefix: &str| {
|
let build_path = |lib64: bool, prefix: &str| {
|
||||||
PathBuf::from(profile.prefix.clone())
|
profile
|
||||||
|
.prefix
|
||||||
|
.clone()
|
||||||
.join(match lib64 {
|
.join(match lib64 {
|
||||||
true => "lib64",
|
true => "lib64",
|
||||||
false => "lib",
|
false => "lib",
|
||||||
|
@ -144,7 +146,7 @@ pub fn build_profile_active_runtime(profile: &Profile) -> ActiveRuntime {
|
||||||
}
|
}
|
||||||
|
|
||||||
// for system installs
|
// for system installs
|
||||||
fn relativize_active_runtime_lib_path(ar: &ActiveRuntime, path: &PathBuf) -> ActiveRuntime {
|
fn relativize_active_runtime_lib_path(ar: &ActiveRuntime, path: &Path) -> ActiveRuntime {
|
||||||
let mut res = ar.clone();
|
let mut res = ar.clone();
|
||||||
let mut rel_chain = path
|
let mut rel_chain = path
|
||||||
.components()
|
.components()
|
||||||
|
@ -177,7 +179,7 @@ pub fn set_current_active_runtime_to_profile(profile: &Profile) -> anyhow::Resul
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
dump_active_runtime_to_path, get_active_runtime_from_path,
|
dump_active_runtime_to_path, get_active_runtime_from_path,
|
||||||
|
@ -186,8 +188,9 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_read_active_runtime_json_steamvr() {
|
fn can_read_active_runtime_json_steamvr() {
|
||||||
let ar = get_active_runtime_from_path(&"./test/files/active_runtime.json.steamvr".into())
|
let ar =
|
||||||
.unwrap();
|
get_active_runtime_from_path(Path::new("./test/files/active_runtime.json.steamvr"))
|
||||||
|
.unwrap();
|
||||||
assert_eq!(ar.file_format_version, "1.0.0");
|
assert_eq!(ar.file_format_version, "1.0.0");
|
||||||
assert!(ar.runtime.valve_runtime_is_steamvr.unwrap());
|
assert!(ar.runtime.valve_runtime_is_steamvr.unwrap());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -212,8 +215,11 @@ mod tests {
|
||||||
name: Some("SteamVR".into()),
|
name: Some("SteamVR".into()),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
dump_active_runtime_to_path(&ar, &"./target/testout/active_runtime.json.steamvr".into())
|
dump_active_runtime_to_path(
|
||||||
.expect("could not dump active runtime to path");
|
&ar,
|
||||||
|
Path::new("./target/testout/active_runtime.json.steamvr"),
|
||||||
|
)
|
||||||
|
.expect("could not dump active runtime to path");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -229,7 +235,7 @@ mod tests {
|
||||||
};
|
};
|
||||||
let relativized = relativize_active_runtime_lib_path(
|
let relativized = relativize_active_runtime_lib_path(
|
||||||
&ar,
|
&ar,
|
||||||
&PathBuf::from("/home/user/.config/openxr/1/active_runtime.json"),
|
Path::new("/home/user/.config/openxr/1/active_runtime.json"),
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
relativized
|
relativized
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
file_utils::{deserialize_file, get_writer},
|
file_utils::{deserialize_file, get_writer},
|
||||||
|
@ -34,16 +34,15 @@ fn get_monado_autorun_config_path() -> PathBuf {
|
||||||
XDG.get_config_home().join("monado/autorun_v0.json")
|
XDG.get_config_home().join("monado/autorun_v0.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_monado_autorun_config_from_path(path: &PathBuf) -> Option<MonadoAutorunConfig> {
|
fn get_monado_autorun_config_from_path(path: &Path) -> Option<MonadoAutorunConfig> {
|
||||||
deserialize_file(path)
|
deserialize_file(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_monado_autorun_config() -> MonadoAutorunConfig {
|
pub fn get_monado_autorun_config() -> MonadoAutorunConfig {
|
||||||
get_monado_autorun_config_from_path(&get_monado_autorun_config_path())
|
get_monado_autorun_config_from_path(&get_monado_autorun_config_path()).unwrap_or_default()
|
||||||
.unwrap_or(MonadoAutorunConfig::default())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dump_monado_autorun_config_to_path(config: &MonadoAutorunConfig, path: &PathBuf) {
|
fn dump_monado_autorun_config_to_path(config: &MonadoAutorunConfig, path: &Path) {
|
||||||
let writer = get_writer(path).expect("Unable to save Monado Autorun config");
|
let writer = get_writer(path).expect("Unable to save Monado Autorun config");
|
||||||
serde_json::to_writer_pretty(writer, config).expect("Unable to save Monado Autorun config");
|
serde_json::to_writer_pretty(writer, config).expect("Unable to save Monado Autorun config");
|
||||||
}
|
}
|
||||||
|
@ -54,21 +53,24 @@ pub fn dump_monado_autorun_config(config: &MonadoAutorunConfig) {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use super::get_monado_autorun_config_from_path;
|
use super::get_monado_autorun_config_from_path;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_read_monado_autorun_config() {
|
fn can_read_monado_autorun_config() {
|
||||||
let conf =
|
let conf = get_monado_autorun_config_from_path(Path::new(
|
||||||
get_monado_autorun_config_from_path(&"./test/files/monado_autorun_config.json".into())
|
"./test/files/monado_autorun_config.json",
|
||||||
.expect("Could not find monado autorun config");
|
))
|
||||||
|
.expect("Could not find monado autorun config");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
conf._schema,
|
conf._schema,
|
||||||
Some("https://monado.pages.freedesktop.org/monado/autorun_v0.schema.json".into())
|
Some("https://monado.pages.freedesktop.org/monado/autorun_v0.schema.json".into())
|
||||||
);
|
);
|
||||||
assert_eq!(conf.autoruns.len(), 1);
|
assert_eq!(conf.autoruns.len(), 1);
|
||||||
assert_eq!(conf.autoruns.get(0).unwrap().exec, "foobar");
|
assert_eq!(conf.autoruns.first().unwrap().exec, "foobar");
|
||||||
assert_eq!(conf.autoruns.get(0).unwrap().args.len(), 2);
|
assert_eq!(conf.autoruns.first().unwrap().args.len(), 2);
|
||||||
assert_eq!(conf.autoruns.get(0).unwrap().args.get(0).unwrap(), "bar");
|
assert_eq!(conf.autoruns.first().unwrap().args.first().unwrap(), "bar");
|
||||||
assert_eq!(conf.autoruns.get(0).unwrap().args.get(1).unwrap(), "baz");
|
assert_eq!(conf.autoruns.first().unwrap().args.get(1).unwrap(), "baz");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
file_utils::{copy_file, deserialize_file, get_writer, set_file_readonly},
|
file_utils::{copy_file, deserialize_file, get_writer, set_file_readonly},
|
||||||
|
@ -53,7 +53,7 @@ fn backup_steam_openvrpaths() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_openvrpaths_from_path(path: &PathBuf) -> Option<OpenVrPaths> {
|
fn get_openvrpaths_from_path(path: &Path) -> Option<OpenVrPaths> {
|
||||||
deserialize_file(path)
|
deserialize_file(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,10 +61,7 @@ pub fn get_current_openvrpaths() -> Option<OpenVrPaths> {
|
||||||
get_openvrpaths_from_path(&get_openvrpaths_vrpath_path())
|
get_openvrpaths_from_path(&get_openvrpaths_vrpath_path())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dump_openvrpaths_to_path(
|
fn dump_openvrpaths_to_path(ovr_paths: &OpenVrPaths, path: &Path) -> Result<(), serde_json::Error> {
|
||||||
ovr_paths: &OpenVrPaths,
|
|
||||||
path: &PathBuf,
|
|
||||||
) -> Result<(), serde_json::Error> {
|
|
||||||
let writer = get_writer(path).map_err(serde_json::Error::custom)?;
|
let writer = get_writer(path).map_err(serde_json::Error::custom)?;
|
||||||
serde_json::to_writer_pretty(writer, ovr_paths)
|
serde_json::to_writer_pretty(writer, ovr_paths)
|
||||||
}
|
}
|
||||||
|
@ -117,17 +114,17 @@ pub fn set_current_openvrpaths_to_profile(profile: &Profile) -> anyhow::Result<(
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::path::PathBuf;
|
use std::path::Path;
|
||||||
|
|
||||||
use super::{dump_openvrpaths_to_path, get_openvrpaths_from_path, OpenVrPaths};
|
use super::{dump_openvrpaths_to_path, get_openvrpaths_from_path, OpenVrPaths};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_read_openvrpaths_vrpath_steamvr() {
|
fn can_read_openvrpaths_vrpath_steamvr() {
|
||||||
let ovrp = get_openvrpaths_from_path(&"./test/files/openvrpaths.vrpath".into()).unwrap();
|
let ovrp = get_openvrpaths_from_path(Path::new("./test/files/openvrpaths.vrpath")).unwrap();
|
||||||
assert_eq!(ovrp.config.len(), 1);
|
assert_eq!(ovrp.config.len(), 1);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
ovrp.config.get(0).unwrap(),
|
ovrp.config.first().unwrap(),
|
||||||
&PathBuf::from("/home/user/.local/share/Steam/config")
|
&Path::new("/home/user/.local/share/Steam/config")
|
||||||
);
|
);
|
||||||
assert_eq!(ovrp.external_drivers, None);
|
assert_eq!(ovrp.external_drivers, None);
|
||||||
assert_eq!(ovrp.jsonid, "vrpathreg");
|
assert_eq!(ovrp.jsonid, "vrpathreg");
|
||||||
|
@ -144,7 +141,7 @@ mod tests {
|
||||||
runtime: vec!["/home/user/.local/share/Steam/steamapps/common/SteamVR".into()],
|
runtime: vec!["/home/user/.local/share/Steam/steamapps/common/SteamVR".into()],
|
||||||
version: 1,
|
version: 1,
|
||||||
};
|
};
|
||||||
dump_openvrpaths_to_path(&ovrp, &"./target/testout/openvrpaths.vrpath".into())
|
dump_openvrpaths_to_path(&ovrp, Path::new("./target/testout/openvrpaths.vrpath"))
|
||||||
.expect("could not dump openvrpaths to path");
|
.expect("could not dump openvrpaths to path");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,11 @@ use crate::{
|
||||||
xdg::XDG,
|
xdg::XDG,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{fmt::Display, path::PathBuf, slice::Iter};
|
use std::{
|
||||||
|
fmt::Display,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
slice::Iter,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "lowercase")]
|
#[serde(rename_all = "lowercase")]
|
||||||
|
@ -127,15 +131,15 @@ fn get_wivrn_config_path() -> PathBuf {
|
||||||
XDG.get_config_home().join("wivrn/config.json")
|
XDG.get_config_home().join("wivrn/config.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_wivrn_config_from_path(path: &PathBuf) -> Option<WivrnConfig> {
|
fn get_wivrn_config_from_path(path: &Path) -> Option<WivrnConfig> {
|
||||||
deserialize_file(path)
|
deserialize_file(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_wivrn_config() -> WivrnConfig {
|
pub fn get_wivrn_config() -> WivrnConfig {
|
||||||
get_wivrn_config_from_path(&get_wivrn_config_path()).unwrap_or(WivrnConfig::default())
|
get_wivrn_config_from_path(&get_wivrn_config_path()).unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dump_wivrn_config_to_path(config: &WivrnConfig, path: &PathBuf) {
|
fn dump_wivrn_config_to_path(config: &WivrnConfig, path: &Path) {
|
||||||
let writer = get_writer(path).expect("Unable to save WiVRn config");
|
let writer = get_writer(path).expect("Unable to save WiVRn config");
|
||||||
serde_json::to_writer_pretty(writer, config).expect("Unable to save WiVRn config");
|
serde_json::to_writer_pretty(writer, config).expect("Unable to save WiVRn config");
|
||||||
}
|
}
|
||||||
|
@ -146,22 +150,24 @@ pub fn dump_wivrn_config(config: &WivrnConfig) {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use crate::file_builders::wivrn_config::{Codec, Encoder};
|
use crate::file_builders::wivrn_config::{Codec, Encoder};
|
||||||
|
|
||||||
use super::get_wivrn_config_from_path;
|
use super::get_wivrn_config_from_path;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_read_wivrn_config() {
|
fn can_read_wivrn_config() {
|
||||||
let conf = get_wivrn_config_from_path(&"./test/files/wivrn_config.json".into())
|
let conf = get_wivrn_config_from_path(Path::new("./test/files/wivrn_config.json"))
|
||||||
.expect("Couldn't find wivrn config");
|
.expect("Couldn't find wivrn config");
|
||||||
assert_eq!(conf.scale, Some([0.8, 0.8]));
|
assert_eq!(conf.scale, Some([0.8, 0.8]));
|
||||||
assert_eq!(conf.encoders.len(), 1);
|
assert_eq!(conf.encoders.len(), 1);
|
||||||
assert_eq!(conf.encoders.get(0).unwrap().encoder, Encoder::X264);
|
assert_eq!(conf.encoders.first().unwrap().encoder, Encoder::X264);
|
||||||
assert_eq!(conf.encoders.get(0).unwrap().codec, Codec::H264);
|
assert_eq!(conf.encoders.first().unwrap().codec, Codec::H264);
|
||||||
assert_eq!(conf.bitrate, Some(100000000));
|
assert_eq!(conf.bitrate, Some(100000000));
|
||||||
assert_eq!(conf.encoders.get(0).unwrap().width, Some(1.0));
|
assert_eq!(conf.encoders.first().unwrap().width, Some(1.0));
|
||||||
assert_eq!(conf.encoders.get(0).unwrap().height, Some(1.0));
|
assert_eq!(conf.encoders.first().unwrap().height, Some(1.0));
|
||||||
assert_eq!(conf.encoders.get(0).unwrap().offset_x, Some(0.0));
|
assert_eq!(conf.encoders.first().unwrap().offset_x, Some(0.0));
|
||||||
assert_eq!(conf.encoders.get(0).unwrap().offset_y, Some(0.0));
|
assert_eq!(conf.encoders.first().unwrap().offset_y, Some(0.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,10 @@ use nix::{
|
||||||
use std::{
|
use std::{
|
||||||
fs::{self, copy, create_dir_all, remove_dir_all, File, OpenOptions},
|
fs::{self, copy, create_dir_all, remove_dir_all, File, OpenOptions},
|
||||||
io::{BufReader, BufWriter},
|
io::{BufReader, BufWriter},
|
||||||
path::{Path, PathBuf},
|
path::Path,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn get_writer(path: &PathBuf) -> anyhow::Result<BufWriter<std::fs::File>> {
|
pub fn get_writer(path: &Path) -> anyhow::Result<BufWriter<std::fs::File>> {
|
||||||
if let Some(parent) = path.parent() {
|
if let Some(parent) = path.parent() {
|
||||||
if !parent.is_dir() {
|
if !parent.is_dir() {
|
||||||
create_dir_all(parent)?;
|
create_dir_all(parent)?;
|
||||||
|
@ -23,7 +23,7 @@ pub fn get_writer(path: &PathBuf) -> anyhow::Result<BufWriter<std::fs::File>> {
|
||||||
Ok(BufWriter::new(file))
|
Ok(BufWriter::new(file))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_reader(path: &PathBuf) -> Option<BufReader<File>> {
|
pub fn get_reader(path: &Path) -> Option<BufReader<File>> {
|
||||||
if !(path.is_file() || path.is_symlink()) {
|
if !(path.is_file() || path.is_symlink()) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ pub fn get_reader(path: &PathBuf) -> Option<BufReader<File>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deserialize_file<T: serde::de::DeserializeOwned>(path: &PathBuf) -> Option<T> {
|
pub fn deserialize_file<T: serde::de::DeserializeOwned>(path: &Path) -> Option<T> {
|
||||||
match get_reader(path) {
|
match get_reader(path) {
|
||||||
None => None,
|
None => None,
|
||||||
Some(reader) => match serde_json::from_reader(reader) {
|
Some(reader) => match serde_json::from_reader(reader) {
|
||||||
|
@ -49,7 +49,7 @@ pub fn deserialize_file<T: serde::de::DeserializeOwned>(path: &PathBuf) -> Optio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_file_readonly(path: &PathBuf, readonly: bool) -> Result<(), std::io::Error> {
|
pub fn set_file_readonly(path: &Path, readonly: bool) -> Result<(), std::io::Error> {
|
||||||
if !path.is_file() {
|
if !path.is_file() {
|
||||||
println!("WARN: trying to set readonly on a file that does not exist");
|
println!("WARN: trying to set readonly on a file that does not exist");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -61,7 +61,7 @@ pub fn set_file_readonly(path: &PathBuf, readonly: bool) -> Result<(), std::io::
|
||||||
fs::set_permissions(path, perms)
|
fs::set_permissions(path, perms)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setcap_cap_sys_nice_eip(file: &PathBuf) {
|
pub fn setcap_cap_sys_nice_eip(file: &Path) {
|
||||||
let mut runner = CmdRunner::new(
|
let mut runner = CmdRunner::new(
|
||||||
None,
|
None,
|
||||||
"pkexec".into(),
|
"pkexec".into(),
|
||||||
|
@ -75,13 +75,13 @@ pub fn setcap_cap_sys_nice_eip(file: &PathBuf) {
|
||||||
runner.join();
|
runner.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rm_rf(path: &PathBuf) {
|
pub fn rm_rf(path: &Path) {
|
||||||
if remove_dir_all(path).is_err() {
|
if remove_dir_all(path).is_err() {
|
||||||
println!("Failed to remove path {}", path.to_string_lossy());
|
println!("Failed to remove path {}", path.to_string_lossy());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn copy_file(source: &PathBuf, dest: &PathBuf) {
|
pub fn copy_file(source: &Path, dest: &Path) {
|
||||||
if let Some(parent) = dest.parent() {
|
if let Some(parent) = dest.parent() {
|
||||||
if !parent.is_dir() {
|
if !parent.is_dir() {
|
||||||
create_dir_all(parent)
|
create_dir_all(parent)
|
||||||
|
@ -99,7 +99,7 @@ pub fn copy_file(source: &PathBuf, dest: &PathBuf) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mount_has_nosuid(path: &PathBuf) -> Result<bool, Errno> {
|
pub fn mount_has_nosuid(path: &Path) -> Result<bool, Errno> {
|
||||||
match statvfs(path) {
|
match statvfs(path) {
|
||||||
Ok(fstats) => Ok(fstats.flags().contains(FsFlags::ST_NOSUID)),
|
Ok(fstats) => Ok(fstats.flags().contains(FsFlags::ST_NOSUID)),
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
|
@ -108,12 +108,13 @@ pub fn mount_has_nosuid(path: &PathBuf) -> Result<bool, Errno> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::path::PathBuf;
|
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use crate::file_utils::mount_has_nosuid;
|
use crate::file_utils::mount_has_nosuid;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_get_nosuid() {
|
fn can_get_nosuid() {
|
||||||
mount_has_nosuid(&PathBuf::from("/tmp")).expect("Error running statvfs");
|
mount_has_nosuid(Path::new("/tmp")).expect("Error running statvfs");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,8 +33,8 @@ impl Runner for FuncRunner {
|
||||||
if self.res.is_some() {
|
if self.res.is_some() {
|
||||||
panic!("Cannot start a FuncRunner twice!");
|
panic!("Cannot start a FuncRunner twice!");
|
||||||
}
|
}
|
||||||
let f = mem::replace(&mut self.func, Box::new(move || FuncRunnerOut::default()));
|
let f = mem::replace(&mut self.func, Box::new(FuncRunnerOut::default));
|
||||||
self.thread = Some(thread::spawn(move || f()));
|
self.thread = Some(thread::spawn(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn status(&mut self) -> RunnerStatus {
|
fn status(&mut self) -> RunnerStatus {
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
use crate::file_utils::get_reader;
|
use crate::file_utils::get_reader;
|
||||||
use std::{error::Error, fmt::Display, io::Read, path::PathBuf, str::FromStr};
|
use std::{
|
||||||
|
error::Error,
|
||||||
|
fmt::Display,
|
||||||
|
io::Read,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
str::FromStr,
|
||||||
|
};
|
||||||
|
|
||||||
// const POW_PROF_PATH: &str = "/sys/class/drm/card0/device/pp_power_profile_mode";
|
// const POW_PROF_PATH: &str = "/sys/class/drm/card0/device/pp_power_profile_mode";
|
||||||
|
|
||||||
fn power_profile_mode_file(card_dir: &PathBuf) -> PathBuf {
|
fn power_profile_mode_file(card_dir: &Path) -> PathBuf {
|
||||||
card_dir.join("device/pp_power_profile_mode")
|
card_dir.join("device/pp_power_profile_mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_set_amd_vr_pow_prof_cmd(card_dir: &PathBuf) -> String {
|
pub fn get_set_amd_vr_pow_prof_cmd(card_dir: &Path) -> String {
|
||||||
format!(
|
format!(
|
||||||
"sudo sh -c \"echo '4' > {}\"",
|
"sudo sh -c \"echo '4' > {}\"",
|
||||||
power_profile_mode_file(card_dir).to_string_lossy()
|
power_profile_mode_file(card_dir).to_string_lossy()
|
||||||
|
@ -35,6 +41,12 @@ impl GpuPowerProfileParseErr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for GpuPowerProfileParseErr {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Display for GpuPowerProfileParseErr {
|
impl Display for GpuPowerProfileParseErr {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
f.write_str("GpuPowerProfileParseErr")
|
f.write_str("GpuPowerProfileParseErr")
|
||||||
|
@ -123,8 +135,7 @@ fn list_gpus() -> Vec<GpuSysDrm> {
|
||||||
pub fn get_first_amd_gpu() -> Option<GpuSysDrm> {
|
pub fn get_first_amd_gpu() -> Option<GpuSysDrm> {
|
||||||
list_gpus()
|
list_gpus()
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|g| matches!(g, GpuSysDrm::Amd(_)))
|
.find(|g| matches!(g, GpuSysDrm::Amd(_)))
|
||||||
.next()
|
|
||||||
.cloned()
|
.cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::file_utils::get_reader;
|
use crate::file_utils::get_reader;
|
||||||
use std::{
|
use std::{
|
||||||
io::{BufRead, Read},
|
io::{BufRead, Read},
|
||||||
path::PathBuf,
|
path::Path,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||||
|
@ -17,14 +17,14 @@ pub enum LinuxDistro {
|
||||||
|
|
||||||
impl LinuxDistro {
|
impl LinuxDistro {
|
||||||
pub fn get() -> Option<Self> {
|
pub fn get() -> Option<Self> {
|
||||||
Self::get_from_etc_os_release().or_else(|| Self::get_from_etc_issue())
|
Self::get_from_etc_os_release().or_else(Self::get_from_etc_issue)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_from_etc_os_release() -> Option<Self> {
|
fn get_from_etc_os_release() -> Option<Self> {
|
||||||
Self::get_from_etc_os_release_file(&"/etc/os-release".into())
|
Self::get_from_etc_os_release_file(Path::new("/etc/os-release"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_from_etc_os_release_file(fp: &PathBuf) -> Option<Self> {
|
fn get_from_etc_os_release_file(fp: &Path) -> Option<Self> {
|
||||||
if let Some(mut reader) = get_reader(fp) {
|
if let Some(mut reader) = get_reader(fp) {
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
loop {
|
loop {
|
||||||
|
@ -33,7 +33,7 @@ impl LinuxDistro {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
if buf.starts_with("NAME=\"") {
|
if buf.starts_with("NAME=\"") {
|
||||||
let name = buf
|
let name = buf
|
||||||
.split("=")
|
.split('=')
|
||||||
.last()
|
.last()
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.to_string()
|
.to_string()
|
||||||
|
@ -50,7 +50,7 @@ impl LinuxDistro {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_from_etc_issue() -> Option<Self> {
|
fn get_from_etc_issue() -> Option<Self> {
|
||||||
if let Some(mut reader) = get_reader(&"/etc/issue".into()) {
|
if let Some(mut reader) = get_reader(Path::new("/etc/issue")) {
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
if reader.read_to_string(&mut buf).is_ok() {
|
if reader.read_to_string(&mut buf).is_ok() {
|
||||||
buf = buf.trim().to_lowercase();
|
buf = buf.trim().to_lowercase();
|
||||||
|
@ -109,12 +109,16 @@ impl LinuxDistro {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use super::LinuxDistro;
|
use super::LinuxDistro;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_detect_arch_linux_from_etc_os_release() {
|
fn can_detect_arch_linux_from_etc_os_release() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
LinuxDistro::get_from_etc_os_release_file(&"./test/files/archlinux-os-release".into()),
|
LinuxDistro::get_from_etc_os_release_file(Path::new(
|
||||||
|
"./test/files/archlinux-os-release"
|
||||||
|
)),
|
||||||
Some(LinuxDistro::Arch)
|
Some(LinuxDistro::Arch)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,7 +97,7 @@ fn main() -> Result<()> {
|
||||||
let main_app = adw::Application::builder()
|
let main_app = adw::Application::builder()
|
||||||
.application_id(APP_ID)
|
.application_id(APP_ID)
|
||||||
.flags(gio::ApplicationFlags::HANDLES_COMMAND_LINE)
|
.flags(gio::ApplicationFlags::HANDLES_COMMAND_LINE)
|
||||||
.resource_base_path(format!("/{}", APP_ID.replace(".", "/")))
|
.resource_base_path(format!("/{}", APP_ID.replace('.', "/")))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
static BROKER: MessageBroker<Msg> = MessageBroker::new();
|
static BROKER: MessageBroker<Msg> = MessageBroker::new();
|
||||||
|
|
|
@ -348,13 +348,13 @@ impl Profile {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_profile(path: &PathBuf) -> Self {
|
pub fn load_profile(path: &Path) -> Self {
|
||||||
let file = File::open(path).expect("Unable to open profile");
|
let file = File::open(path).expect("Unable to open profile");
|
||||||
let reader = BufReader::new(file);
|
let reader = BufReader::new(file);
|
||||||
serde_json::from_reader(reader).expect("Faiuled to deserialize profile")
|
serde_json::from_reader(reader).expect("Faiuled to deserialize profile")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dump_profile(&self, path: &PathBuf) {
|
pub fn dump_profile(&self, path: &Path) {
|
||||||
let writer = get_writer(path).expect("Could not write profile");
|
let writer = get_writer(path).expect("Could not write profile");
|
||||||
serde_json::to_writer_pretty(writer, self).expect("Could not write profile")
|
serde_json::to_writer_pretty(writer, self).expect("Could not write profile")
|
||||||
}
|
}
|
||||||
|
@ -367,35 +367,43 @@ impl Profile {
|
||||||
dup.editable = true;
|
dup.editable = true;
|
||||||
return dup;
|
return dup;
|
||||||
}
|
}
|
||||||
let mut dup = Self::default();
|
let mut dup = Self {
|
||||||
dup.name = format!("Duplicate of {}", self.name);
|
name: format!("Duplicate of {}", self.name),
|
||||||
dup.xrservice_type = self.xrservice_type.clone();
|
xrservice_type: self.xrservice_type.clone(),
|
||||||
dup.xrservice_repo = self.xrservice_repo.clone();
|
xrservice_repo: self.xrservice_repo.clone(),
|
||||||
dup.xrservice_branch = self.xrservice_branch.clone();
|
xrservice_branch: self.xrservice_branch.clone(),
|
||||||
dup.xrservice_cmake_flags = self.xrservice_cmake_flags.clone();
|
xrservice_cmake_flags: self.xrservice_cmake_flags.clone(),
|
||||||
dup.features.libsurvive.enabled = self.features.libsurvive.enabled;
|
features: ProfileFeatures {
|
||||||
dup.features.libsurvive.repo = self.features.libsurvive.repo.clone();
|
libsurvive: ProfileFeature {
|
||||||
dup.features.libsurvive.branch = self.features.libsurvive.branch.clone();
|
enabled: self.features.libsurvive.enabled,
|
||||||
dup.features.basalt.enabled = self.features.basalt.enabled;
|
repo: self.features.libsurvive.repo.clone(),
|
||||||
dup.features.basalt.repo = self.features.basalt.repo.clone();
|
branch: self.features.libsurvive.branch.clone(),
|
||||||
dup.features.basalt.branch = self.features.basalt.branch.clone();
|
..Default::default()
|
||||||
dup.features.openhmd.enabled = self.features.openhmd.enabled;
|
},
|
||||||
dup.features.openhmd.repo = self.features.openhmd.repo.clone();
|
basalt: ProfileFeature {
|
||||||
dup.features.openhmd.branch = self.features.openhmd.branch.clone();
|
enabled: self.features.basalt.enabled,
|
||||||
dup.features.mercury_enabled = self.features.mercury_enabled;
|
repo: self.features.basalt.repo.clone(),
|
||||||
dup.environment = self.environment.clone();
|
branch: self.features.basalt.branch.clone(),
|
||||||
if dup.environment.contains_key("LD_LIBRARY_PATH".into()) {
|
..Default::default()
|
||||||
|
},
|
||||||
|
|
||||||
|
openhmd: ProfileFeature {
|
||||||
|
enabled: self.features.openhmd.enabled,
|
||||||
|
repo: self.features.openhmd.repo.clone(),
|
||||||
|
branch: self.features.openhmd.branch.clone(),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
mercury_enabled: self.features.mercury_enabled,
|
||||||
|
},
|
||||||
|
environment: self.environment.clone(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
if dup.environment.contains_key("LD_LIBRARY_PATH") {
|
||||||
dup.environment.insert(
|
dup.environment.insert(
|
||||||
"LD_LIBRARY_PATH".into(),
|
"LD_LIBRARY_PATH".into(),
|
||||||
prepare_ld_library_path(&dup.prefix),
|
prepare_ld_library_path(&dup.prefix),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
dup.pull_on_build = self.pull_on_build;
|
|
||||||
dup.opencomposite_repo = self.opencomposite_repo.clone();
|
|
||||||
dup.opencomposite_branch = self.opencomposite_branch.clone();
|
|
||||||
dup.lighthouse_driver = self.lighthouse_driver;
|
|
||||||
dup.xrservice_launch_options = self.xrservice_launch_options.clone();
|
|
||||||
dup.autostart_command = self.autostart_command.clone();
|
|
||||||
dup
|
dup
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,9 +465,16 @@ impl Profile {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn prepare_ld_library_path(prefix: &Path) -> String {
|
||||||
|
format!("{pfx}/lib:{pfx}/lib64", pfx = prefix.to_string_lossy())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::{collections::HashMap, path::PathBuf};
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::profile::{ProfileFeature, ProfileFeatureType, ProfileFeatures, XRServiceType};
|
use crate::profile::{ProfileFeature, ProfileFeatureType, ProfileFeatures, XRServiceType};
|
||||||
|
|
||||||
|
@ -467,7 +482,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn profile_can_be_loaded() {
|
fn profile_can_be_loaded() {
|
||||||
let profile = Profile::load_profile(&"./test/files/profile.json".into());
|
let profile = Profile::load_profile(Path::new("./test/files/profile.json"));
|
||||||
assert_eq!(profile.name, "Demo profile");
|
assert_eq!(profile.name, "Demo profile");
|
||||||
assert_eq!(profile.xrservice_path, PathBuf::from("/home/user/monado"));
|
assert_eq!(profile.xrservice_path, PathBuf::from("/home/user/monado"));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -480,9 +495,9 @@ mod tests {
|
||||||
Some(PathBuf::from("/home/user/libsurvive"))
|
Some(PathBuf::from("/home/user/libsurvive"))
|
||||||
);
|
);
|
||||||
assert_eq!(profile.features.basalt.path, None);
|
assert_eq!(profile.features.basalt.path, None);
|
||||||
assert_eq!(profile.features.libsurvive.enabled, true);
|
assert!(profile.features.libsurvive.enabled);
|
||||||
assert_eq!(profile.features.basalt.enabled, false);
|
assert!(!profile.features.basalt.enabled);
|
||||||
assert_eq!(profile.features.mercury_enabled, false);
|
assert!(!profile.features.mercury_enabled);
|
||||||
assert!(profile
|
assert!(profile
|
||||||
.environment
|
.environment
|
||||||
.contains_key("XRT_COMPOSITOR_SCALE_PERCENTAGE"));
|
.contains_key("XRT_COMPOSITOR_SCALE_PERCENTAGE"));
|
||||||
|
@ -537,7 +552,3 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prepare_ld_library_path(prefix: &PathBuf) -> String {
|
|
||||||
format!("{pfx}/lib:{pfx}/lib64", pfx = prefix.to_string_lossy())
|
|
||||||
}
|
|
||||||
|
|
|
@ -11,19 +11,19 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
fn get_runtime_entrypoint_path() -> Option<PathBuf> {
|
fn get_runtime_entrypoint_path() -> Option<PathBuf> {
|
||||||
vec![get_home_dir()
|
Some(
|
||||||
.join(".steam/steam/steamapps/common/SteamLinuxRuntime_sniper/_v2-entry-point")]
|
get_home_dir()
|
||||||
.iter()
|
.join(".steam/steam/steamapps/common/SteamLinuxRuntime_sniper/_v2-entry-point"),
|
||||||
.find(|p| p.is_file())
|
)
|
||||||
.cloned()
|
.filter(|p| p.is_file())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_backup_runtime_entrypoint_location() -> PathBuf {
|
fn get_backup_runtime_entrypoint_location() -> PathBuf {
|
||||||
get_backup_dir().join("_v2-entry-point.bak")
|
get_backup_dir().join("_v2-entry-point.bak")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn backup_runtime_entrypoint(path: &PathBuf) {
|
fn backup_runtime_entrypoint(path: &Path) {
|
||||||
copy_file(&path, &get_backup_runtime_entrypoint_location());
|
copy_file(path, &get_backup_runtime_entrypoint_location());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn restore_runtime_entrypoint() {
|
pub fn restore_runtime_entrypoint() {
|
||||||
|
@ -35,14 +35,14 @@ pub fn restore_runtime_entrypoint() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn append_to_runtime_entrypoint(data: &str, path: &PathBuf) -> anyhow::Result<()> {
|
fn append_to_runtime_entrypoint(data: &str, path: &Path) -> anyhow::Result<()> {
|
||||||
let existing = read_to_string(path)?;
|
let existing = read_to_string(path)?;
|
||||||
let new = existing.replace(
|
let new = existing.replace(
|
||||||
"exec \"${here}/${run}\" \"$@\"\nexit 125",
|
"exec \"${here}/${run}\" \"$@\"\nexit 125",
|
||||||
&format!("\n\n# envision\n{data}\n\nexec \"${{here}}/${{run}}\" \"$@\"\nexit 125"),
|
&format!("\n\n# envision\n{data}\n\nexec \"${{here}}/${{run}}\" \"$@\"\nexit 125"),
|
||||||
);
|
);
|
||||||
let mut writer = get_writer(path)?;
|
let mut writer = get_writer(path)?;
|
||||||
writer.write(&new.as_bytes())?;
|
writer.write_all(new.as_bytes())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -190,7 +190,7 @@ impl App {
|
||||||
self.debug_view.sender().emit(DebugViewMsg::ClearLog);
|
self.debug_view.sender().emit(DebugViewMsg::ClearLog);
|
||||||
self.xr_devices = vec![];
|
self.xr_devices = vec![];
|
||||||
if prof.can_start() {
|
if prof.can_start() {
|
||||||
remove_file(&get_ipc_file_path(&prof.xrservice_type))
|
remove_file(get_ipc_file_path(&prof.xrservice_type))
|
||||||
.is_err()
|
.is_err()
|
||||||
.then(|| println!("Failed to remove xrservice IPC file"));
|
.then(|| println!("Failed to remove xrservice IPC file"));
|
||||||
let worker = JobWorker::xrservice_worker_wrap_from_profile(
|
let worker = JobWorker::xrservice_worker_wrap_from_profile(
|
||||||
|
@ -364,10 +364,11 @@ impl SimpleComponent for App {
|
||||||
Msg::ClockTicking => {
|
Msg::ClockTicking => {
|
||||||
self.main_view.sender().emit(MainViewMsg::ClockTicking);
|
self.main_view.sender().emit(MainViewMsg::ClockTicking);
|
||||||
if let Some(w) = self.xrservice_worker.as_ref() {
|
if let Some(w) = self.xrservice_worker.as_ref() {
|
||||||
if {
|
let stop_condition = {
|
||||||
let state = w.state.lock().unwrap();
|
let state = w.state.lock().unwrap();
|
||||||
state.exit_status.is_none() && !state.stop_requested
|
state.exit_status.is_none() && !state.stop_requested
|
||||||
} {
|
};
|
||||||
|
if stop_condition {
|
||||||
if let Some(monado) = self.libmonado.as_ref() {
|
if let Some(monado) = self.libmonado.as_ref() {
|
||||||
self.xr_devices = XRDevice::merge(
|
self.xr_devices = XRDevice::merge(
|
||||||
&self.xr_devices,
|
&self.xr_devices,
|
||||||
|
@ -376,12 +377,10 @@ impl SimpleComponent for App {
|
||||||
self.main_view
|
self.main_view
|
||||||
.sender()
|
.sender()
|
||||||
.emit(MainViewMsg::UpdateDevices(self.xr_devices.clone()));
|
.emit(MainViewMsg::UpdateDevices(self.xr_devices.clone()));
|
||||||
} else {
|
} else if let Some(so) = self.get_selected_profile().libmonado_so() {
|
||||||
if let Some(so) = self.get_selected_profile().libmonado_so() {
|
self.libmonado = libmonado_rs::Monado::create(so).ok();
|
||||||
self.libmonado = libmonado_rs::Monado::create(so).ok();
|
if self.libmonado.is_some() {
|
||||||
if self.libmonado.is_some() {
|
sender.input(Msg::ClockTicking);
|
||||||
sender.input(Msg::ClockTicking);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -410,7 +409,7 @@ impl SimpleComponent for App {
|
||||||
self.start_xrservice(sender, false);
|
self.start_xrservice(sender, false);
|
||||||
}
|
}
|
||||||
Some(worker) => {
|
Some(worker) => {
|
||||||
let status = worker.state.lock().unwrap().exit_status.clone();
|
let status = worker.state.lock().unwrap().exit_status;
|
||||||
match status {
|
match status {
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
self.start_xrservice(sender, false);
|
self.start_xrservice(sender, false);
|
||||||
|
@ -472,9 +471,7 @@ impl SimpleComponent for App {
|
||||||
{
|
{
|
||||||
let packages = missing_deps
|
let packages = missing_deps
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|dep| {
|
.filter_map(|dep| dep.packages.get(&d).cloned())
|
||||||
dep.packages.get(&d).and_then(|s| Some(s.clone()))
|
|
||||||
})
|
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
if packages.is_empty() {
|
if packages.is_empty() {
|
||||||
None
|
None
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use crate::ui::SENDER_IO_ERR_MSG;
|
||||||
|
|
||||||
use super::term_widget::TermWidget;
|
use super::term_widget::TermWidget;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use relm4::prelude::*;
|
use relm4::prelude::*;
|
||||||
|
@ -91,16 +93,13 @@ impl SimpleComponent for BuildWindow {
|
||||||
},
|
},
|
||||||
gtk::Button {
|
gtk::Button {
|
||||||
#[track = "model.changed(BuildWindow::build_status())"]
|
#[track = "model.changed(BuildWindow::build_status())"]
|
||||||
set_visible: match &model.build_status {
|
set_visible: matches!(&model.build_status, BuildStatus::Building),
|
||||||
BuildStatus::Building => true,
|
|
||||||
_ => false,
|
|
||||||
},
|
|
||||||
add_css_class: "destructive-action",
|
add_css_class: "destructive-action",
|
||||||
add_css_class: "circular",
|
add_css_class: "circular",
|
||||||
set_icon_name: "window-close-symbolic",
|
set_icon_name: "window-close-symbolic",
|
||||||
set_tooltip_text: Some("Cancel build"),
|
set_tooltip_text: Some("Cancel build"),
|
||||||
connect_clicked[sender] => move |_| {
|
connect_clicked[sender] => move |_| {
|
||||||
sender.output(Self::Output::CancelBuild);
|
sender.output(Self::Output::CancelBuild).expect(SENDER_IO_ERR_MSG);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -175,7 +175,7 @@ impl SimpleComponent for DebugView {
|
||||||
lvl = o.level,
|
lvl = o.level,
|
||||||
file = o.file,
|
file = o.file,
|
||||||
func = o.func,
|
func = o.func,
|
||||||
msg = o.message.replace("\n", "\r\n")
|
msg = o.message.replace('\n', "\r\n")
|
||||||
)),
|
)),
|
||||||
},
|
},
|
||||||
None => Some(row),
|
None => Some(row),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use super::factories::device_row_factory::{DeviceRowModel, DeviceRowModelInit, DeviceRowState};
|
use super::factories::device_row_factory::{DeviceRowModel, DeviceRowModelInit, DeviceRowState};
|
||||||
use crate::xr_devices::{XRDevice, XRDeviceRole};
|
use crate::xr_devices::{XRDevice, XRDeviceRole};
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
use relm4::{factory::AsyncFactoryVecDeque, prelude::*, Sender};
|
use relm4::{factory::AsyncFactoryVecDeque, prelude::*};
|
||||||
|
|
||||||
#[tracker::track]
|
#[tracker::track]
|
||||||
pub struct DevicesBox {
|
pub struct DevicesBox {
|
||||||
|
@ -34,7 +34,7 @@ impl SimpleComponent for DevicesBox {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
|
fn update(&mut self, message: Self::Input, _sender: ComponentSender<Self>) {
|
||||||
self.reset();
|
self.reset();
|
||||||
|
|
||||||
match message {
|
match message {
|
||||||
|
@ -52,7 +52,7 @@ impl SimpleComponent for DevicesBox {
|
||||||
match dev.dev_type {
|
match dev.dev_type {
|
||||||
XRDeviceRole::Head => {
|
XRDeviceRole::Head => {
|
||||||
has_head = true;
|
has_head = true;
|
||||||
let mut init = DeviceRowModelInit::from_xr_device(&dev);
|
let mut init = DeviceRowModelInit::from_xr_device(dev);
|
||||||
if dev.name == "Simulated HMD" {
|
if dev.name == "Simulated HMD" {
|
||||||
init.state = Some(DeviceRowState::Warning);
|
init.state = Some(DeviceRowState::Warning);
|
||||||
init.subtitle = Some("No HMD detected (Simulated HMD)".into());
|
init.subtitle = Some("No HMD detected (Simulated HMD)".into());
|
||||||
|
@ -61,17 +61,17 @@ impl SimpleComponent for DevicesBox {
|
||||||
}
|
}
|
||||||
XRDeviceRole::Left => {
|
XRDeviceRole::Left => {
|
||||||
has_left = true;
|
has_left = true;
|
||||||
models.push(DeviceRowModelInit::from_xr_device(&dev));
|
models.push(DeviceRowModelInit::from_xr_device(dev));
|
||||||
}
|
}
|
||||||
XRDeviceRole::Right => {
|
XRDeviceRole::Right => {
|
||||||
has_right = true;
|
has_right = true;
|
||||||
models.push(DeviceRowModelInit::from_xr_device(&dev));
|
models.push(DeviceRowModelInit::from_xr_device(dev));
|
||||||
}
|
}
|
||||||
XRDeviceRole::GenericTracker => {
|
XRDeviceRole::GenericTracker => {
|
||||||
generic.push(dev);
|
generic.push(dev);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
models.push(DeviceRowModelInit::from_xr_device(&dev));
|
models.push(DeviceRowModelInit::from_xr_device(dev));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
ui::{battery_status::BatteryStatus, devices_box::DevicesBoxMsg},
|
ui::battery_status::BatteryStatus,
|
||||||
xr_devices::{XRDevice, XRDeviceRole},
|
xr_devices::{XRDevice, XRDeviceRole},
|
||||||
};
|
};
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
|
|
|
@ -55,13 +55,13 @@ impl AsyncFactoryComponent for EnvVarModel {
|
||||||
async fn update(&mut self, message: Self::Input, sender: AsyncFactorySender<Self>) {
|
async fn update(&mut self, message: Self::Input, sender: AsyncFactorySender<Self>) {
|
||||||
match message {
|
match message {
|
||||||
Self::Input::Changed(val) => {
|
Self::Input::Changed(val) => {
|
||||||
self.value = val.clone();
|
self.value.clone_from(&val);
|
||||||
sender
|
sender
|
||||||
.output_sender()
|
.output_sender()
|
||||||
.emit(Self::Output::Changed(self.name.clone(), val));
|
.emit(Self::Output::Changed(self.name.clone(), val));
|
||||||
}
|
}
|
||||||
Self::Input::Delete => {
|
Self::Input::Delete => {
|
||||||
sender.output(Self::Output::Delete(self.name.clone()));
|
let _ = sender.output(Self::Output::Delete(self.name.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
file_builders::wivrn_config::{Codec, Encoder, WivrnConfEncoder},
|
file_builders::wivrn_config::{Codec, Encoder, WivrnConfEncoder},
|
||||||
ui::preference_rows::{combo_row, spin_row},
|
ui::{
|
||||||
|
preference_rows::{combo_row, spin_row},
|
||||||
|
SENDER_IO_ERR_MSG,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use relm4::{adw::prelude::*, factory::AsyncFactoryComponent, prelude::*, AsyncFactorySender};
|
use relm4::{adw::prelude::*, factory::AsyncFactoryComponent, prelude::*, AsyncFactorySender};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
@ -183,7 +186,9 @@ impl AsyncFactoryComponent for WivrnEncoderModel {
|
||||||
self.encoder_conf.group = val;
|
self.encoder_conf.group = val;
|
||||||
}
|
}
|
||||||
Self::Input::Delete => {
|
Self::Input::Delete => {
|
||||||
sender.output(Self::Output::Delete(self.uid.clone()));
|
sender
|
||||||
|
.output(Self::Output::Delete(self.uid.clone()))
|
||||||
|
.expect(SENDER_IO_ERR_MSG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ pub struct InstallWivrnBox {
|
||||||
root_win: gtk::Window,
|
root_win: gtk::Window,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum InstallWivrnBoxMsg {
|
pub enum InstallWivrnBoxMsg {
|
||||||
ClockTicking,
|
ClockTicking,
|
||||||
|
|
|
@ -2,7 +2,10 @@ use super::{
|
||||||
job::{CmdWorkerData, FuncWorkerOut, WorkerJob},
|
job::{CmdWorkerData, FuncWorkerOut, WorkerJob},
|
||||||
state::JobWorkerState,
|
state::JobWorkerState,
|
||||||
};
|
};
|
||||||
use crate::profile::{LighthouseDriver, Profile};
|
use crate::{
|
||||||
|
profile::{LighthouseDriver, Profile},
|
||||||
|
ui::SENDER_IO_ERR_MSG,
|
||||||
|
};
|
||||||
use nix::unistd::Pid;
|
use nix::unistd::Pid;
|
||||||
use relm4::{prelude::*, Worker};
|
use relm4::{prelude::*, Worker};
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -102,7 +105,7 @@ impl Worker for InternalJobWorker {
|
||||||
));
|
));
|
||||||
let stdout = cmd.stdout.take().unwrap();
|
let stdout = cmd.stdout.take().unwrap();
|
||||||
let stderr = cmd.stderr.take().unwrap();
|
let stderr = cmd.stderr.take().unwrap();
|
||||||
let stdin = cmd.stdin.take().unwrap();
|
let _stdin = cmd.stdin.take().unwrap();
|
||||||
let stdout_sender = sender.clone();
|
let stdout_sender = sender.clone();
|
||||||
let stderr_sender = sender.clone();
|
let stderr_sender = sender.clone();
|
||||||
let stdout_logger = logger_thread!(stdout, stdout_sender);
|
let stdout_logger = logger_thread!(stdout, stdout_sender);
|
||||||
|
@ -120,18 +123,20 @@ impl Worker for InternalJobWorker {
|
||||||
stderr_logger.join().expect("Failed to join reader thread");
|
stderr_logger.join().expect("Failed to join reader thread");
|
||||||
} else {
|
} else {
|
||||||
let msg = "Failed to run command".to_string();
|
let msg = "Failed to run command".to_string();
|
||||||
sender.output(Self::Output::Log(vec![msg]));
|
sender
|
||||||
|
.output(Self::Output::Log(vec![msg]))
|
||||||
|
.expect(SENDER_IO_ERR_MSG);
|
||||||
self.state.lock().unwrap().exit_status = Some(1);
|
self.state.lock().unwrap().exit_status = Some(1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WorkerJob::Func(data) => {
|
WorkerJob::Func(data) => {
|
||||||
let func = mem::replace(
|
let func =
|
||||||
&mut data.func,
|
mem::replace(&mut data.func, Box::new(FuncWorkerOut::default));
|
||||||
Box::new(move || FuncWorkerOut::default()),
|
|
||||||
);
|
|
||||||
let out = func();
|
let out = func();
|
||||||
sender.output(Self::Output::Log(out.out.clone()));
|
sender
|
||||||
|
.output(Self::Output::Log(out.out.clone()))
|
||||||
|
.expect(SENDER_IO_ERR_MSG);
|
||||||
if !out.success {
|
if !out.success {
|
||||||
self.state.lock().unwrap().exit_status = Some(1);
|
self.state.lock().unwrap().exit_status = Some(1);
|
||||||
break;
|
break;
|
||||||
|
@ -196,7 +201,7 @@ impl InternalJobWorker {
|
||||||
match launch_opts.contains(LAUNCH_OPTS_CMD_PLACEHOLDER) {
|
match launch_opts.contains(LAUNCH_OPTS_CMD_PLACEHOLDER) {
|
||||||
true => launch_opts.replacen(
|
true => launch_opts.replacen(
|
||||||
LAUNCH_OPTS_CMD_PLACEHOLDER,
|
LAUNCH_OPTS_CMD_PLACEHOLDER,
|
||||||
&prof.xrservice_binary().to_string_lossy().to_string(),
|
prof.xrservice_binary().to_string_lossy().as_ref(),
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
false => format!(
|
false => format!(
|
||||||
|
|
|
@ -7,13 +7,7 @@ use crate::{
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
use relm4::prelude::*;
|
use relm4::prelude::*;
|
||||||
use std::{
|
use std::{cell::Cell, collections::HashMap, path::Path, rc::Rc, time::Duration};
|
||||||
cell::Cell,
|
|
||||||
collections::HashMap,
|
|
||||||
path::{Path, PathBuf},
|
|
||||||
rc::Rc,
|
|
||||||
time::Duration,
|
|
||||||
};
|
|
||||||
|
|
||||||
const NO_FILE_MSG: &str = "(No file selected)";
|
const NO_FILE_MSG: &str = "(No file selected)";
|
||||||
const CALIBRATION_RUN_TIME_SECONDS: f64 = 30.0;
|
const CALIBRATION_RUN_TIME_SECONDS: f64 = 30.0;
|
||||||
|
@ -52,6 +46,7 @@ pub struct LibsurviveSetupWindow {
|
||||||
calibration_runner: Option<CmdRunner>,
|
calibration_runner: Option<CmdRunner>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum LibsurviveSetupMsg {
|
pub enum LibsurviveSetupMsg {
|
||||||
Present(Profile),
|
Present(Profile),
|
||||||
|
@ -63,13 +58,13 @@ pub enum LibsurviveSetupMsg {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LibsurviveSetupWindow {
|
impl LibsurviveSetupWindow {
|
||||||
fn create_calibration_runner(&mut self, survive_cli_path: &PathBuf) -> CmdRunner {
|
fn create_calibration_runner(&mut self, survive_cli_path: &Path) -> CmdRunner {
|
||||||
let lh_path = self.steam_lighthouse_path.clone();
|
let lh_path = self.steam_lighthouse_path.clone();
|
||||||
let mut env = HashMap::new();
|
let mut env = HashMap::new();
|
||||||
let profile_prefix = &self.profile.as_ref().unwrap().prefix;
|
let profile_prefix = &self.profile.as_ref().unwrap().prefix;
|
||||||
env.insert(
|
env.insert(
|
||||||
"LD_LIBRARY_PATH".into(),
|
"LD_LIBRARY_PATH".into(),
|
||||||
prepare_ld_library_path(&profile_prefix),
|
prepare_ld_library_path(profile_prefix),
|
||||||
);
|
);
|
||||||
CmdRunner::new(
|
CmdRunner::new(
|
||||||
Some(env),
|
Some(env),
|
||||||
|
|
|
@ -8,7 +8,7 @@ use crate::config::Config;
|
||||||
use crate::dependencies::common::dep_pkexec;
|
use crate::dependencies::common::dep_pkexec;
|
||||||
use crate::file_utils::mount_has_nosuid;
|
use crate::file_utils::mount_has_nosuid;
|
||||||
use crate::gpu_profile::{get_amd_gpu_power_profile, GpuPowerProfile};
|
use crate::gpu_profile::{get_amd_gpu_power_profile, GpuPowerProfile};
|
||||||
use crate::profile::{LighthouseDriver, Profile, XRServiceType};
|
use crate::profile::{LighthouseDriver, Profile};
|
||||||
use crate::steamvr_utils::chaperone_info_exists;
|
use crate::steamvr_utils::chaperone_info_exists;
|
||||||
use crate::ui::app::{
|
use crate::ui::app::{
|
||||||
AboutAction, BuildProfileAction, BuildProfileCleanAction, ConfigureWivrnAction,
|
AboutAction, BuildProfileAction, BuildProfileCleanAction, ConfigureWivrnAction,
|
||||||
|
@ -434,13 +434,10 @@ impl SimpleComponent for MainView {
|
||||||
self.steam_launch_options_box.sender().emit(
|
self.steam_launch_options_box.sender().emit(
|
||||||
SteamLaunchOptionsBoxMsg::UpdateXRServiceActive(show_launch_opts),
|
SteamLaunchOptionsBoxMsg::UpdateXRServiceActive(show_launch_opts),
|
||||||
);
|
);
|
||||||
match profile {
|
if let Some(prof) = profile {
|
||||||
None => {}
|
self.steam_launch_options_box
|
||||||
Some(prof) => {
|
.sender()
|
||||||
self.steam_launch_options_box
|
.emit(SteamLaunchOptionsBoxMsg::UpdateLaunchOptions(prof));
|
||||||
.sender()
|
|
||||||
.emit(SteamLaunchOptionsBoxMsg::UpdateLaunchOptions(prof));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::Input::EnableDebugViewChanged(val) => {
|
Self::Input::EnableDebugViewChanged(val) => {
|
||||||
|
|
|
@ -19,3 +19,5 @@ mod steamvr_calibration_box;
|
||||||
mod term_widget;
|
mod term_widget;
|
||||||
mod util;
|
mod util;
|
||||||
mod wivrn_conf_editor;
|
mod wivrn_conf_editor;
|
||||||
|
|
||||||
|
pub const SENDER_IO_ERR_MSG: &str = "relm4 sender i/o failed";
|
||||||
|
|
|
@ -61,11 +61,11 @@ pub fn entry_row<F: Fn(&adw::EntryRow) + 'static>(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_int(t: &str) -> bool {
|
fn is_int(t: &str) -> bool {
|
||||||
t.find(|c: char| !c.is_digit(10)).is_none()
|
t.find(|c: char| !c.is_ascii_digit()).is_none()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_to_int(t: &str) -> String {
|
fn convert_to_int(t: &str) -> String {
|
||||||
t.trim().chars().filter(|c| c.is_digit(10)).collect()
|
t.trim().chars().filter(|c| c.is_ascii_digit()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_float(t: &str) -> bool {
|
fn is_float(t: &str) -> bool {
|
||||||
|
@ -76,7 +76,7 @@ fn is_float(t: &str) -> bool {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
has_dot = true;
|
has_dot = true;
|
||||||
} else if !c.is_digit(10) {
|
} else if !c.is_ascii_digit() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ fn convert_to_float(t: &str) -> String {
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
let mut has_dot = false;
|
let mut has_dot = false;
|
||||||
for c in t.trim().chars() {
|
for c in t.trim().chars() {
|
||||||
if c.is_digit(10) {
|
if c.is_ascii_digit() {
|
||||||
s.push(c);
|
s.push(c);
|
||||||
} else if c == '.' && !has_dot {
|
} else if c == '.' && !has_dot {
|
||||||
s.push(c);
|
s.push(c);
|
||||||
|
|
|
@ -9,6 +9,7 @@ pub struct SteamLaunchOptionsBox {
|
||||||
launch_options: String,
|
launch_options: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum SteamLaunchOptionsBoxMsg {
|
pub enum SteamLaunchOptionsBoxMsg {
|
||||||
UpdateXRServiceActive(bool),
|
UpdateXRServiceActive(bool),
|
||||||
|
|
|
@ -190,7 +190,10 @@ impl SimpleComponent for SteamVrCalibrationBox {
|
||||||
self.server_worker = Some(server_worker);
|
self.server_worker = Some(server_worker);
|
||||||
self.calibration_worker = Some(cal_worker);
|
self.calibration_worker = Some(cal_worker);
|
||||||
}
|
}
|
||||||
Self::Input::OnServerWorkerExit(_) => {
|
Self::Input::OnServerWorkerExit(code) => {
|
||||||
|
if code != 0 {
|
||||||
|
eprintln!("Calibration exited with code {code}");
|
||||||
|
}
|
||||||
self.calibration_running = false;
|
self.calibration_running = false;
|
||||||
}
|
}
|
||||||
Self::Input::OnCalWorkerExit(code) => {
|
Self::Input::OnCalWorkerExit(code) => {
|
||||||
|
@ -209,7 +212,7 @@ impl SimpleComponent for SteamVrCalibrationBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(
|
fn init(
|
||||||
init: Self::Init,
|
_init: Self::Init,
|
||||||
root: Self::Root,
|
root: Self::Root,
|
||||||
sender: ComponentSender<Self>,
|
sender: ComponentSender<Self>,
|
||||||
) -> ComponentParts<Self> {
|
) -> ComponentParts<Self> {
|
||||||
|
|
|
@ -26,8 +26,8 @@ impl TermWidget {
|
||||||
.vexpand(true)
|
.vexpand(true)
|
||||||
.child(&term)
|
.child(&term)
|
||||||
.build();
|
.build();
|
||||||
let this = Self { container, term };
|
|
||||||
this
|
Self { container, term }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_color_scheme(&self) {
|
pub fn set_color_scheme(&self) {
|
||||||
|
@ -51,8 +51,7 @@ impl TermWidget {
|
||||||
|
|
||||||
pub fn set_search_term(&self, term: Option<&str>) {
|
pub fn set_search_term(&self, term: Option<&str>) {
|
||||||
self.term.search_set_regex(
|
self.term.search_set_regex(
|
||||||
term.map(|txt| vte4::Regex::for_search(txt, 0).ok())
|
term.and_then(|txt| vte4::Regex::for_search(txt, 0).ok())
|
||||||
.flatten()
|
|
||||||
.as_ref(),
|
.as_ref(),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
|
|
@ -116,11 +116,7 @@ impl SimpleComponent for WivrnConfEditor {
|
||||||
add: bitrate_row = &number_entry_row(
|
add: bitrate_row = &number_entry_row(
|
||||||
"Bitrate (Mbps)",
|
"Bitrate (Mbps)",
|
||||||
&model.conf.bitrate
|
&model.conf.bitrate
|
||||||
.and_then(|n| if let Some(mbits) = bits_to_mbits(n) {
|
.and_then(|n| bits_to_mbits(n).map(|mbits| mbits.to_string()))
|
||||||
Some(mbits.to_string())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
})
|
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
false,
|
false,
|
||||||
move |_| {}
|
move |_| {}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue