feat: ask to set monado-service capabilities on build finished

This commit is contained in:
Gabriele Musco 2023-06-15 23:17:10 +02:00
commit f524cb68e4
No known key found for this signature in database
GPG key ID: 1068D795C80E51DE
2 changed files with 58 additions and 19 deletions

View file

@ -15,6 +15,7 @@ use crate::file_builders::active_runtime_json::{
use crate::file_builders::openvrpaths_vrpath::{ use crate::file_builders::openvrpaths_vrpath::{
set_current_openvrpaths_to_profile, set_current_openvrpaths_to_steam, set_current_openvrpaths_to_profile, set_current_openvrpaths_to_steam,
}; };
use crate::file_utils::setcap_cap_sys_nice_eip;
use crate::profile::Profile; use crate::profile::Profile;
use crate::profiles::valve_index::valve_index_profile; use crate::profiles::valve_index::valve_index_profile;
use crate::runner::{Runner, RunnerStatus}; use crate::runner::{Runner, RunnerStatus};
@ -25,6 +26,7 @@ use crate::ui::main_view::{MainView, MainViewInit, MainViewOutMsg};
use expect_dialog::ExpectDialog; use expect_dialog::ExpectDialog;
use gtk::prelude::*; use gtk::prelude::*;
use relm4::actions::{ActionGroupName, RelmAction, RelmActionGroup}; use relm4::actions::{ActionGroupName, RelmAction, RelmActionGroup};
use relm4::adw::ResponseAppearance;
use relm4::adw::traits::MessageDialogExt; use relm4::adw::traits::MessageDialogExt;
use relm4::gtk::glib; use relm4::gtk::glib;
use relm4::{new_action_group, new_stateful_action, new_stateless_action, prelude::*}; use relm4::{new_action_group, new_stateful_action, new_stateless_action, prelude::*};
@ -45,6 +47,8 @@ pub struct App {
build_window: Controller<BuildWindow>, build_window: Controller<BuildWindow>,
#[tracker::do_not_track] #[tracker::do_not_track]
dependencies_dialog: adw::MessageDialog, dependencies_dialog: adw::MessageDialog,
#[tracker::do_not_track]
setcap_confirm_dialog: adw::MessageDialog,
#[tracker::do_not_track] #[tracker::do_not_track]
config: Config, config: Config,
@ -66,6 +70,7 @@ pub enum Msg {
DoStartStopMonado, DoStartStopMonado,
ProfileSelected(String), ProfileSelected(String),
SetMonadoRuntime(bool), SetMonadoRuntime(bool),
RunSetCap,
} }
impl App { impl App {
@ -150,28 +155,30 @@ impl SimpleComponent for App {
.emit(DebugViewMsg::LogUpdated(self.monado_log.clone())); .emit(DebugViewMsg::LogUpdated(self.monado_log.clone()));
} }
match runner.status() { match runner.status() {
RunnerStatus::Running => {}, RunnerStatus::Running => {}
RunnerStatus::Stopped => { RunnerStatus::Stopped => {
self.main_view.sender().emit(MainViewMsg::MonadoActiveChanged(false)); self.main_view
.sender()
.emit(MainViewMsg::MonadoActiveChanged(false));
} }
}; };
} }
}; };
match &mut self.build_pipeline { match &mut self.build_pipeline {
None => {} None => {}
Some(pipeline) => match pipeline.is_running() { Some(pipeline) => {
true => { pipeline.update();
pipeline.update(); self.build_window
self.build_window .sender()
.sender() .emit(BuildWindowMsg::UpdateContent(pipeline.get_log()));
.emit(BuildWindowMsg::UpdateContent(pipeline.get_log())); if !pipeline.is_running() {
} self.setcap_confirm_dialog.present();
false => {
self.build_window self.build_window
.sender() .sender()
.emit(BuildWindowMsg::UpdateCanClose(true)); .emit(BuildWindowMsg::UpdateCanClose(true));
self.build_pipeline.take();
} }
}, }
}; };
} }
Msg::EnableDebugViewChanged(val) => { Msg::EnableDebugViewChanged(val) => {
@ -257,12 +264,16 @@ impl SimpleComponent for App {
pipeline.start(); pipeline.start();
self.build_window self.build_window
.sender() .sender()
.emit(BuildWindowMsg::UpdateTitle("Building Monado".into())); .emit(BuildWindowMsg::UpdateTitle(format!("Building Profile {}", profile.name)));
self.build_window self.build_window
.sender() .sender()
.emit(BuildWindowMsg::UpdateCanClose(false)); .emit(BuildWindowMsg::UpdateCanClose(false));
self.build_pipeline = Some(pipeline); self.build_pipeline = Some(pipeline);
} }
Msg::RunSetCap => {
let profile = self.get_selected_profile();
setcap_cap_sys_nice_eip(format!("{pfx}/bin/monado-service", pfx = profile.prefix));
}
Msg::ProfileSelected(prof_name) => { Msg::ProfileSelected(prof_name) => {
self.config.selected_profile_name = prof_name; self.config.selected_profile_name = prof_name;
save_config(&self.config); save_config(&self.config);
@ -294,6 +305,31 @@ impl SimpleComponent for App {
.hide_on_close(true) .hide_on_close(true)
.build(); .build();
dependencies_dialog.add_response("ok", "_Ok"); dependencies_dialog.add_response("ok", "_Ok");
let setcap_confirm_dialog = adw::MessageDialog::builder()
.modal(true)
.transient_for(root)
.heading("Set monado-service Capabilities")
.body(concat!(
"We need to set certain capabilities (CAP_SYS_NICE=eip) on the ",
"monado-service executable. This requires your superuser password.\n\n",
"Do you want to continue?",
))
.hide_on_close(true)
.build();
setcap_confirm_dialog.add_response("no", "_No");
setcap_confirm_dialog.add_response("yes", "_Yes");
setcap_confirm_dialog.set_response_appearance("no", ResponseAppearance::Destructive);
setcap_confirm_dialog.set_response_appearance("yes", ResponseAppearance::Suggested);
{
let setcap_sender = sender.clone();
setcap_confirm_dialog.connect_response(None, move |_, res| {
if res == "yes" {
setcap_sender.input(Msg::RunSetCap);
}
});
}
let model = App { let model = App {
main_view: MainView::builder() main_view: MainView::builder()
.launch(MainViewInit { .launch(MainViewInit {
@ -322,6 +358,7 @@ impl SimpleComponent for App {
.launch(()) .launch(())
.detach(), .detach(),
dependencies_dialog, dependencies_dialog,
setcap_confirm_dialog,
enable_debug_view: config.debug_view_enabled, enable_debug_view: config.debug_view_enabled,
config, config,
tracker: 0, tracker: 0,

View file

@ -94,13 +94,15 @@ impl SimpleComponent for BuildWindow {
self.set_title(t); self.set_title(t);
}, },
BuildWindowMsg::UpdateContent(c) => { BuildWindowMsg::UpdateContent(c) => {
self.set_content(c); if self.content != c {
self.textbuf.set_text(&self.content); self.set_content(c);
let sw = self.scrolled_win.as_ref().unwrap().clone(); self.textbuf.set_text(&self.content);
let adj = sw.vadjustment(); let sw = self.scrolled_win.as_ref().unwrap().clone();
// upper means highest value = lowest point in the sw let adj = sw.vadjustment();
adj.set_value(adj.upper()); // upper means highest value = lowest point in the sw
sw.set_vadjustment(Some(&adj)); adj.set_value(adj.upper());
sw.set_vadjustment(Some(&adj));
}
}, },
BuildWindowMsg::UpdateCanClose(val) => { BuildWindowMsg::UpdateCanClose(val) => {
self.set_can_close(val); self.set_can_close(val);