feat: command line options to list profiles and select profile

This commit is contained in:
Gabriele Musco 2024-02-05 17:28:13 +01:00
commit a59eee3ca6
No known key found for this signature in database
GPG key ID: 1068D795C80E51DE
4 changed files with 85 additions and 29 deletions

View file

@ -1,6 +1,13 @@
use crate::{ use crate::{
constants::CMD_NAME, device_prober::get_xr_usb_devices, file_utils::get_writer, constants::CMD_NAME,
paths::get_config_dir, profile::Profile, device_prober::get_xr_usb_devices,
file_utils::get_writer,
paths::get_config_dir,
profile::Profile,
profiles::{
lighthouse::lighthouse_profile, openhmd::openhmd_profile, simulated::simulated_profile,
survive::survive_profile, wivrn::wivrn_profile, wmr::wmr_profile,
},
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{fs::File, io::BufReader}; use std::{fs::File, io::BufReader};
@ -87,6 +94,20 @@ impl Config {
pub fn set_profiles(&mut self, profiles: &[Profile]) { pub fn set_profiles(&mut self, profiles: &[Profile]) {
self.user_profiles = profiles.iter().filter(|p| p.editable).cloned().collect(); self.user_profiles = profiles.iter().filter(|p| p.editable).cloned().collect();
} }
pub fn profiles(&self) -> Vec<Profile> {
let mut profiles = vec![
lighthouse_profile(),
survive_profile(),
wivrn_profile(),
wmr_profile(),
openhmd_profile(),
simulated_profile(),
];
profiles.extend(self.user_profiles.clone());
profiles.sort_unstable_by(|a, b| a.name.cmp(&b.name));
profiles
}
} }
#[cfg(test)] #[cfg(test)]

View file

@ -100,6 +100,9 @@ fn main() -> Result<()> {
CmdLineOpts::init(&main_app); CmdLineOpts::init(&main_app);
let sender = BROKER.sender(); let sender = BROKER.sender();
main_app.connect_command_line(move |this, cmdline| { main_app.connect_command_line(move |this, cmdline| {
if CmdLineOpts::handle_non_activating_opts(cmdline) {
return 0;
}
this.activate(); this.activate();
sender.emit(Msg::HandleCommandLine(CmdLineOpts::from_cmdline(cmdline))); sender.emit(Msg::HandleCommandLine(CmdLineOpts::from_cmdline(cmdline)));
0 0

View file

@ -38,12 +38,6 @@ use crate::linux_distro::LinuxDistro;
use crate::log_parser::MonadoLog; use crate::log_parser::MonadoLog;
use crate::paths::{get_data_dir, get_ipc_file_path}; use crate::paths::{get_data_dir, get_ipc_file_path};
use crate::profile::{Profile, XRServiceType}; use crate::profile::{Profile, XRServiceType};
use crate::profiles::lighthouse::lighthouse_profile;
use crate::profiles::openhmd::openhmd_profile;
use crate::profiles::simulated::simulated_profile;
use crate::profiles::survive::survive_profile;
use crate::profiles::wivrn::wivrn_profile;
use crate::profiles::wmr::wmr_profile;
use crate::stateless_action; use crate::stateless_action;
use crate::ui::build_window::{BuildWindowMsg, BuildWindowOutMsg}; use crate::ui::build_window::{BuildWindowMsg, BuildWindowOutMsg};
use crate::ui::debug_view::{DebugViewInit, DebugViewOutMsg}; use crate::ui::debug_view::{DebugViewInit, DebugViewOutMsg};
@ -277,20 +271,6 @@ impl App {
.emit(DebugViewMsg::XRServiceActiveChanged(false)); .emit(DebugViewMsg::XRServiceActiveChanged(false));
self.xr_devices = vec![]; self.xr_devices = vec![];
} }
pub fn profiles_list(config: &Config) -> Vec<Profile> {
let mut profiles = vec![
lighthouse_profile(),
survive_profile(),
wivrn_profile(),
wmr_profile(),
openhmd_profile(),
simulated_profile(),
];
profiles.extend(config.user_profiles.clone());
profiles.sort_unstable_by(|a, b| a.name.cmp(&b.name));
profiles
}
} }
#[derive(Debug)] #[derive(Debug)]
@ -637,7 +617,7 @@ impl SimpleComponent for App {
if todel.editable { if todel.editable {
self.config.user_profiles.retain(|p| p.uuid != todel.uuid); self.config.user_profiles.retain(|p| p.uuid != todel.uuid);
self.config.save(); self.config.save();
self.profiles = Self::profiles_list(&self.config); self.profiles = self.config.profiles();
self.main_view self.main_view
.sender() .sender()
.emit(MainViewMsg::UpdateSelectedProfile( .emit(MainViewMsg::UpdateSelectedProfile(
@ -739,6 +719,15 @@ impl SimpleComponent for App {
self.wivrn_conf_editor = Some(editor); self.wivrn_conf_editor = Some(editor);
} }
Msg::HandleCommandLine(opts) => { Msg::HandleCommandLine(opts) => {
if let Some(prof_uuid) = opts.profile_uuid {
if let Some(index) = self.profiles.iter().position(|p| p.uuid == prof_uuid) {
let target = self.profiles.get(index).unwrap();
sender.input(Msg::ProfileSelected(target.clone()));
self.main_view
.sender()
.emit(MainViewMsg::SetSelectedProfile(index as u32));
}
}
if opts.start { if opts.start {
sender.input(Msg::DoStartStopXRService) sender.input(Msg::DoStartStopXRService)
} }
@ -753,7 +742,7 @@ impl SimpleComponent for App {
) -> ComponentParts<Self> { ) -> ComponentParts<Self> {
let config = Config::get_config(); let config = Config::get_config();
let win_size = config.win_size; let win_size = config.win_size;
let profiles = Self::profiles_list(&config); let profiles = config.profiles();
let setcap_confirm_dialog = adw::MessageDialog::builder() let setcap_confirm_dialog = adw::MessageDialog::builder()
.modal(true) .modal(true)
.transient_for(root) .transient_for(root)

View file

@ -1,29 +1,72 @@
use crate::config::Config;
use gtk4::{ use gtk4::{
gio::{prelude::ApplicationExt, Application, ApplicationCommandLine}, gio::{
prelude::{ApplicationCommandLineExt, ApplicationExt},
Application, ApplicationCommandLine,
},
glib::{self, IsA}, glib::{self, IsA},
}; };
use zoha_vte4::ApplicationCommandLineExt;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct CmdLineOpts { pub struct CmdLineOpts {
pub start: bool, pub start: bool,
pub profile_uuid: Option<String>,
} }
impl CmdLineOpts { impl CmdLineOpts {
const OPT_START: (&'static str, char) = ("start", 'S');
const OPT_LIST_PROFILES: (&'static str, char) = ("list-profiles", 'l');
const OPT_PROFILE: (&'static str, char) = ("profile", 'p');
pub fn init(app: &impl IsA<Application>) { pub fn init(app: &impl IsA<Application>) {
app.add_main_option( app.add_main_option(
"start", Self::OPT_START.0,
glib::Char::try_from('S').unwrap(), glib::Char::try_from(Self::OPT_START.1).unwrap(),
glib::OptionFlags::IN_MAIN, glib::OptionFlags::IN_MAIN,
glib::OptionArg::None, glib::OptionArg::None,
"Start the XR Service right away", "Start the XR Service right away",
None, None,
); );
app.add_main_option(
Self::OPT_LIST_PROFILES.0,
glib::Char::try_from(Self::OPT_LIST_PROFILES.1).unwrap(),
glib::OptionFlags::IN_MAIN,
glib::OptionArg::None,
"List the available profiles",
None,
);
app.add_main_option(
Self::OPT_PROFILE.0,
glib::Char::try_from(Self::OPT_PROFILE.1).unwrap(),
glib::OptionFlags::IN_MAIN,
glib::OptionArg::String,
"Switch to the profile indicated by the UUID",
None,
);
}
/// returns true if the application should quit
pub fn handle_non_activating_opts(cmdline: &ApplicationCommandLine) -> bool {
if cmdline.options_dict().contains(Self::OPT_LIST_PROFILES.0) {
println!("Available profiles\nUUID: \"name\"");
let profiles = Config::get_config().profiles();
profiles.iter().for_each(|p| {
println!("{}: \"{}\"", p.uuid, p.name);
});
return true;
}
false
} }
pub fn from_cmdline(cmdline: &ApplicationCommandLine) -> Self { pub fn from_cmdline(cmdline: &ApplicationCommandLine) -> Self {
let opts = cmdline.options_dict();
Self { Self {
start: cmdline.options_dict().contains("start"), start: opts.contains(Self::OPT_START.0),
profile_uuid: match opts.lookup::<String>(Self::OPT_PROFILE.0) {
Err(_) => None,
Ok(None) => None,
Ok(Some(variant)) => Some(variant),
},
} }
} }
} }