feat: show steam launch options on start; rename openovr to opencomposite; fallback for selected profile

This commit is contained in:
Gabriele Musco 2023-06-15 17:25:26 +02:00
parent f373b725b4
commit 7da1f6f7ae
No known key found for this signature in database
GPG key ID: 1068D795C80E51DE
7 changed files with 141 additions and 44 deletions

View file

@ -13,7 +13,7 @@ relm4 = { version = "0.6.0", features = [
] }
relm4-components = "0.6.0"
relm4-icons = { version = "0.6.0", features = [
"menu", "loupe"
"menu", "loupe", "copy"
] }
serde = { version = "1.0.163", features = [
"derive"

View file

@ -23,7 +23,7 @@ fn config_file_path() -> String {
fn default_config() -> Config {
Config {
// TODO: handle first start with no profile selected
selected_profile_name: "Demo profile".to_string(),
selected_profile_name: "".to_string(),
debug_view_enabled: false,
}
}

View file

@ -8,7 +8,7 @@ use crate::file_utils::get_writer;
pub struct Profile {
pub name: String,
pub monado_path: String,
pub openovr_path: String,
pub opencomposite_path: String,
pub libsurvive_path: Option<String>,
pub basalt_path: Option<String>,
pub mercury_path: Option<String>,
@ -26,6 +26,16 @@ impl Display for Profile {
}
}
impl Profile {
pub fn get_steam_launch_options(&self) -> String {
let mut opts = vec![];
opts.push(format!("XR_RUNTIME_JSON={prefix}/share/openxr/1/openxr_monado.json", prefix = self.prefix));
opts.push(format!("PRESSURE_VESSEL_FILESYSTEMS_RW=$XDG_RUNTIME_DIR/monado_comp_ipc"));
opts.push("%command%".into());
opts.join(" ")
}
}
pub fn load_profile(path: &String) -> Profile {
let file = File::open(path).expect_dialog("Unable to open profile");
let reader = BufReader::new(file);
@ -48,7 +58,7 @@ mod tests {
let profile = load_profile(&"./test/files/profile.json".to_string());
assert_eq!(profile.name, "Demo profile");
assert_eq!(profile.monado_path, "/home/user/monado");
assert_eq!(profile.openovr_path, "/home/user/openovr");
assert_eq!(profile.opencomposite_path, "/home/user/opencomposite");
assert_eq!(profile.prefix, "/home/user/rex2prefix");
assert_eq!(
profile.libsurvive_path.as_deref(),
@ -76,7 +86,7 @@ mod tests {
let p = Profile {
name: "Demo profile".into(),
monado_path: String::from("/home/user/monado"),
openovr_path: String::from("/home/user/openovr"),
opencomposite_path: String::from("/home/user/opencomposite"),
libsurvive_path: Some(String::from("/home/user/libsurvive")),
basalt_path: None,
mercury_path: None,

View file

@ -13,7 +13,7 @@ pub fn valve_index_profile() -> Profile {
Profile {
name: format!("Valve Index - {name} Default", name = APP_NAME),
monado_path: format!("{data}/monado", data = data_dir),
openovr_path: format!("{data}/openovr", data = data_dir),
opencomposite_path: format!("{data}/opencomposite", data = data_dir),
libsurvive_path: Some(format!("{data}/libsurvive", data = data_dir)),
basalt_path: None,
mercury_path: None,

View file

@ -1,11 +1,14 @@
use std::time::Duration;
use super::about_dialog::AboutDialog;
use super::build_window::BuildWindow;
use super::debug_view::{DebugView, DebugViewMsg};
use super::main_view::MainViewMsg;
use crate::builders::build_libsurvive::get_build_libsurvive_runner;
use crate::builders::build_monado::get_build_monado_runner;
use crate::builders::build_opencomposite::get_build_opencomposite_runner;
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::{check_monado_deps, get_missing_monado_deps};
use crate::dependencies::monado_deps::get_missing_monado_deps;
use crate::profile::Profile;
use crate::profiles::valve_index::valve_index_profile;
use crate::runner::{Runner, RunnerStatus};
@ -20,12 +23,7 @@ use relm4::adw::traits::MessageDialogExt;
use relm4::gtk::glib;
use relm4::{new_action_group, new_stateful_action, new_stateless_action, prelude::*};
use relm4::{ComponentParts, ComponentSender, SimpleComponent};
use relm4_components::alert::{Alert, AlertSettings};
use super::about_dialog::AboutDialog;
use super::build_window::BuildWindow;
use super::debug_view::{DebugView, DebugViewMsg};
use super::main_view::MainViewMsg;
use std::time::Duration;
#[tracker::track]
pub struct App {
@ -74,8 +72,10 @@ impl App {
}
pub fn get_selected_profile(&self) -> &Profile {
self.get_profile_by_name(&self.config.selected_profile_name)
.expect_dialog("Could not find selected profile")
match self.get_profile_by_name(&self.config.selected_profile_name) {
Some(profile) => profile,
None => self.profiles.get(0).expect_dialog("No profiles found"),
}
}
pub fn start_monado(&mut self) {
@ -152,7 +152,7 @@ impl SimpleComponent for App {
self.build_window
.sender()
.emit(BuildWindowMsg::UpdateContent(pipeline.get_log()));
},
}
false => {
self.build_window
.sender()
@ -181,6 +181,11 @@ impl SimpleComponent for App {
self.main_view
.sender()
.emit(MainViewMsg::MonadoActiveChanged(true));
self.main_view
.sender()
.emit(MainViewMsg::SteamLaunchOptionsChanged(
self.get_selected_profile().get_steam_launch_options(),
));
}
Some(runner) => match runner.status() {
RunnerStatus::Running => {
@ -217,6 +222,8 @@ impl SimpleComponent for App {
// runners.push(get_build_mercury_runner(profile.clone()));
// }
runners.push(get_build_monado_runner(profile.clone()));
// no listed deps for opencomp
runners.push(get_build_opencomposite_runner(profile.clone()));
if !missing_deps.is_empty() {
self.dependencies_dialog.set_body(
missing_deps

View file

@ -1,16 +1,17 @@
use gtk::prelude::*;
use relm4::prelude::*;
use relm4::{SimpleComponent, ComponentSender, ComponentParts};
use relm4_icons::icon_name;
use crate::config::Config;
use crate::constants::APP_NAME;
use crate::ui::app::{AboutAction, DebugViewToggleAction, BuildProfileAction};
use crate::ui::app::{AboutAction, BuildProfileAction, DebugViewToggleAction};
use gtk::prelude::*;
use relm4::prelude::*;
use relm4::{ComponentParts, ComponentSender, SimpleComponent};
use relm4_icons::icon_name;
#[tracker::track]
pub struct MainView {
monado_active: bool,
enable_debug_view: bool,
profile_names: Vec<String>,
steam_launch_options: String,
}
#[derive(Debug)]
@ -19,6 +20,7 @@ pub enum MainViewMsg {
MonadoActiveChanged(bool),
EnableDebugViewChanged(bool),
UpdateProfileNames(Vec<String>),
SteamLaunchOptionsChanged(String),
}
#[derive(Debug)]
@ -84,26 +86,98 @@ impl SimpleComponent for MainView {
set_show_end_title_buttons: !model.enable_debug_view,
},
},
gtk::Box {
set_spacing: 12,
set_margin_all: 12,
gtk::Button {
add_css_class: "pill",
add_css_class: "suggested-action",
add_css_class: "destructive-action",
set_hexpand: true,
set_halign: gtk::Align::Center,
#[track = "model.changed(MainView::monado_active())"]
set_class_active: ("suggested-action", !model.monado_active),
#[track = "model.changed(MainView::monado_active())"]
set_label: match model.monado_active {
true => "Stop",
false => "Start",
gtk::ScrolledWindow {
set_hscrollbar_policy: gtk::PolicyType::Never,
set_hexpand: true,
set_vexpand: true,
gtk::Box {
set_spacing: 12,
set_margin_top: 12,
set_margin_bottom: 12,
set_orientation: gtk::Orientation::Vertical,
gtk::Button {
add_css_class: "pill",
add_css_class: "suggested-action",
add_css_class: "destructive-action",
set_hexpand: true,
set_halign: gtk::Align::Center,
#[track = "model.changed(MainView::monado_active())"]
set_class_active: ("suggested-action", !model.monado_active),
#[track = "model.changed(MainView::monado_active())"]
set_label: match model.monado_active {
true => "Stop",
false => "Start",
},
connect_clicked[sender] => move |_| {
sender.input(MainViewMsg::StartStopClicked)
},
},
connect_clicked[sender] => move |_| {
sender.input(MainViewMsg::StartStopClicked)
gtk::Box {
set_orientation: gtk::Orientation::Vertical,
set_hexpand: true,
set_vexpand: false,
set_spacing: 12,
set_margin_top: 12,
set_margin_bottom: 12,
#[track = "model.changed(MainView::monado_active())"]
set_visible: model.monado_active,
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: "Steam Launch Options",
set_wrap: true,
set_wrap_mode: gtk::pango::WrapMode::Word,
},
gtk::Label {
add_css_class: "dim-label",
set_hexpand: true,
set_xalign: 0.0,
set_margin_start: 12,
set_margin_end: 12,
set_label: "Set this string in the launch options of Steam games, so that they can pick up Monado and OpenOVR correctly",
set_wrap: true,
set_wrap_mode: gtk::pango::WrapMode::Word,
},
gtk::Box {
set_margin_start: 12,
set_margin_end: 12,
set_orientation: gtk::Orientation::Horizontal,
set_spacing: 6,
gtk::TextView {
add_css_class: "card",
set_hexpand: true,
set_vexpand: false,
set_monospace: true,
set_editable: false,
set_wrap_mode: gtk::WrapMode::Word,
set_left_margin: 6,
set_right_margin: 6,
set_top_margin: 6,
set_bottom_margin: 6,
set_size_request: (-1, 150),
#[wrap(Some)]
set_buffer: cmdbuf = &gtk::TextBuffer {
#[track = "model.changed(MainView::steam_launch_options())"]
set_text: model.steam_launch_options.as_str(),
}
},
gtk::Button {
add_css_class: "flat",
add_css_class: "circular",
set_icon_name: icon_name::COPY,
set_vexpand: false,
set_valign: gtk::Align::Center,
},
},
}
},
}
}
}
}
@ -114,7 +188,7 @@ impl SimpleComponent for MainView {
match message {
MainViewMsg::StartStopClicked => {
sender.output(MainViewOutMsg::DoStartStopMonado);
},
}
MainViewMsg::MonadoActiveChanged(active) => {
self.set_monado_active(active);
}
@ -124,14 +198,20 @@ impl SimpleComponent for MainView {
MainViewMsg::UpdateProfileNames(names) => {
self.set_profile_names(names);
}
MainViewMsg::SteamLaunchOptionsChanged(lo) => self.set_steam_launch_options(lo),
}
}
fn init(init: Self::Init, root: &Self::Root, sender: ComponentSender<Self>) -> ComponentParts<Self> {
fn init(
init: Self::Init,
root: &Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let model = MainView {
monado_active: false,
enable_debug_view: init.config.debug_view_enabled,
profile_names: vec![],
steam_launch_options: "".into(),
tracker: 0,
};
let widgets = view_output!();

View file

@ -1,7 +1,7 @@
{
"name": "Demo profile",
"monado_path": "/home/user/monado",
"openovr_path": "/home/user/openovr",
"opencomposite_path": "/home/user/opencomposite",
"libsurvive_path": "/home/user/libsurvive",
"basalt_path": null,
"mercury_path": null,