From 32b222cd9e2749cfdecb216189f954c719e3f66e Mon Sep 17 00:00:00 2001 From: Gabriele Musco Date: Tue, 19 Aug 2025 08:16:44 +0200 Subject: [PATCH] feat: button to launch monado-gui --- src/profile.rs | 13 +++++++++++++ src/ui/app.rs | 31 +++++++++++++++++++++++++++++++ src/ui/main_view.rs | 14 ++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/src/profile.rs b/src/profile.rs index 2666291..19be887 100644 --- a/src/profile.rs +++ b/src/profile.rs @@ -689,6 +689,19 @@ impl Profile { }) } + pub fn monado_gui_binary(&self) -> Option { + if self.xrservice_type != XRServiceType::Monado { + None + } else { + let p = self.prefix.join("bin").join("monado-gui"); + if p.is_file() { + Some(p.canonicalize().ok()?) + } else { + None + } + } + } + pub fn can_start(&self) -> bool { self.xrservice_binary().is_file() } diff --git a/src/ui/app.rs b/src/ui/app.rs index a9b9265..e31e3eb 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -87,6 +87,7 @@ pub struct App { plugins_worker: Option, restart_xrservice: bool, build_worker: Option, + monado_gui_worker: Option, profiles: Vec, xr_devices: Vec, libmonado: Option, @@ -138,6 +139,8 @@ pub enum Msg { UpdateConfigPlugins(HashMap), ShowThemeManager, SaveThemeConfig, + LaunchMonadoGui, + OnMonadoGuiExit, NoOp, } @@ -339,6 +342,9 @@ impl App { if let Some(w) = self.plugins_worker.as_ref() { w.stop(); } + if let Some(w) = self.monado_gui_worker.as_ref() { + w.stop(); + } if let Some(w) = self.openxr_prober_worker.as_ref() { w.stop(); // this can cause threads to remain hanging... @@ -919,6 +925,29 @@ impl AsyncComponent for App { self.config.plugins = cp; self.config.save(); } + Msg::LaunchMonadoGui => { + if self.monado_gui_worker.is_some() { + return; + } + let profile = self.get_selected_profile(); + if let Some(bin) = profile.monado_gui_binary() { + let mut jobs = VecDeque::new(); + jobs.push_back(WorkerJob::new_cmd( + Some(profile.environment.clone()), + bin.to_string_lossy().to_string(), + None, + )); + let worker = JobWorker::new(jobs, sender.input_sender(), |msg| match msg { + JobWorkerOut::Log(rows) => Msg::OnServiceLog(rows), + JobWorkerOut::Exit(_) => Msg::OnMonadoGuiExit, + }); + worker.start(); + self.monado_gui_worker = Some(worker); + } + } + Msg::OnMonadoGuiExit => { + self.monado_gui_worker = None; + } } } @@ -1087,6 +1116,7 @@ impl AsyncComponent for App { MainViewOutMsg::SaveProfile(p) => Msg::SaveProfile(p), MainViewOutMsg::OpenLibsurviveSetup => Msg::OpenLibsurviveSetup, MainViewOutMsg::BuildProfile(clean) => Msg::BuildProfile(clean), + MainViewOutMsg::LaunchMonadoGui => Msg::LaunchMonadoGui, }), vkinfo, debug_view: DebugView::builder() @@ -1126,6 +1156,7 @@ impl AsyncComponent for App { xrservice_worker: None, plugins_worker: None, build_worker: None, + monado_gui_worker: None, xr_devices: vec![], restart_xrservice: false, libmonado: None, diff --git a/src/ui/main_view.rs b/src/ui/main_view.rs index 8a2c145..a7bbe32 100644 --- a/src/ui/main_view.rs +++ b/src/ui/main_view.rs @@ -119,6 +119,7 @@ pub enum MainViewOutMsg { OpenLibsurviveSetup, /// params: clean BuildProfile(bool), + LaunchMonadoGui, } pub struct MainViewInit { @@ -385,6 +386,19 @@ impl AsyncComponent for MainView { } }, }, + gtk::Button { + #[track = "model.changed(Self::xrservice_active()) || model.changed(Self::xrservice_ready())"] + set_visible: model.xrservice_active + && model.xrservice_ready + && model.selected_profile.xrservice_type == XRServiceType::Monado + && model.selected_profile.monado_gui_binary().is_some(), + set_label: "Launch Monado GUI", + connect_clicked[sender] => move |_| { + sender + .output(Self::Output::LaunchMonadoGui) + .expect(SENDER_IO_ERR_MSG); + }, + }, gtk::Box { set_orientation: gtk::Orientation::Vertical, set_hexpand: true,