diff --git a/src/ui/alert.rs b/src/ui/alert.rs index b9930b0..b919b5b 100644 --- a/src/ui/alert.rs +++ b/src/ui/alert.rs @@ -1,26 +1,27 @@ -use gtk::prelude::{GtkApplicationExt, GtkWindowExt}; -use relm4::{adw::prelude::MessageDialogExt, prelude::*}; +use gtk::prelude::GtkApplicationExt; +use relm4::{adw::prelude::*, prelude::*}; -fn alert_base(title: &str, msg: Option<&str>, parent: Option<>k::Window>) -> adw::MessageDialog { - let d = adw::MessageDialog::builder() - .modal(true) - .heading(title) - .build(); +fn alert_base(title: &str, msg: Option<&str>) -> adw::AlertDialog { + let d = adw::AlertDialog::builder().heading(title).build(); if let Some(m) = msg { d.set_body(m); } - if parent.is_some() { - d.set_transient_for(parent); - } else { - d.set_transient_for(gtk::Application::default().active_window().as_ref()); - } d.add_response("ok", "_Ok"); d } +fn present_alert(d: adw::AlertDialog, parent: Option<>k::Window>) { + if parent.is_some() { + d.present(parent); + } else { + let active_win = gtk::Application::default().active_window(); + d.present(active_win.as_ref()); + }; +} + pub fn alert(title: &str, msg: Option<&str>, parent: Option<>k::Window>) { - let d = alert_base(title, msg, parent); - d.present(); + let d = alert_base(title, msg); + present_alert(d, parent); } pub fn alert_w_widget( @@ -29,9 +30,9 @@ pub fn alert_w_widget( widget: Option<>k::Widget>, parent: Option<>k::Window>, ) { - let d = alert_base(title, msg, parent); + let d = alert_base(title, msg); if let Some(w) = widget { d.set_extra_child(Some(w)); } - d.present(); + present_alert(d, parent); } diff --git a/src/ui/app.rs b/src/ui/app.rs index 7ff8a9f..017790e 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -50,7 +50,6 @@ use crate::xr_devices::XRDevice; use adw::prelude::*; use gtk::glib::clone; use relm4::actions::{AccelsPlus, ActionGroupName, RelmAction, RelmActionGroup}; -use relm4::adw::prelude::MessageDialogExt; use relm4::adw::ResponseAppearance; use relm4::gtk::glib; use relm4::{new_action_group, new_stateful_action, new_stateless_action, prelude::*}; @@ -69,7 +68,7 @@ pub struct App { split_view: Option, about_dialog: adw::AboutDialog, build_window: Controller, - setcap_confirm_dialog: adw::MessageDialog, + setcap_confirm_dialog: adw::AlertDialog, libsurvive_setup_window: Controller, config: Config, @@ -530,7 +529,7 @@ impl SimpleComponent for App { let profile = self.get_selected_profile(); if profile.xrservice_type == XRServiceType::Monado { if dep_pkexec().check() { - self.setcap_confirm_dialog.present(); + self.setcap_confirm_dialog.present(Some(&self.app_win)); } else { alert_w_widget( "pkexec not found", @@ -741,16 +740,13 @@ impl SimpleComponent for App { let config = Config::get_config(); let win_size = config.win_size; let profiles = config.profiles(); - let setcap_confirm_dialog = adw::MessageDialog::builder() - .modal(true) - .transient_for(&root) + let setcap_confirm_dialog = adw::AlertDialog::builder() .heading("Set Capabilities") .body(concat!( "We need to set certain capabilities (CAP_SYS_NICE=eip) on the ", "OpenXR server 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"); diff --git a/src/ui/main_view.rs b/src/ui/main_view.rs index ba9e22a..20a1376 100644 --- a/src/ui/main_view.rs +++ b/src/ui/main_view.rs @@ -23,10 +23,9 @@ use crate::ui::profile_editor::ProfileEditorInit; use crate::ui::steamvr_calibration_box::SteamVrCalibrationBoxMsg; use crate::ui::util::{limit_dropdown_width, warning_heading}; use crate::xr_devices::XRDevice; -use adw::prelude::*; +use adw::{prelude::*, ResponseAppearance}; use gtk::glib::clone; use relm4::actions::{ActionGroupName, RelmAction, RelmActionGroup}; -use relm4::adw::{prelude::MessageDialogExt, ResponseAppearance}; use relm4::{new_action_group, new_stateless_action, prelude::*}; use relm4::{ComponentParts, ComponentSender, SimpleComponent}; @@ -46,9 +45,9 @@ pub struct MainView { #[tracker::do_not_track] devices_box: Controller, #[tracker::do_not_track] - profile_not_editable_dialog: adw::MessageDialog, + profile_not_editable_dialog: adw::AlertDialog, #[tracker::do_not_track] - profile_delete_confirm_dialog: adw::MessageDialog, + profile_delete_confirm_dialog: adw::AlertDialog, #[tracker::do_not_track] profile_editor: Option>, #[tracker::do_not_track] @@ -521,14 +520,16 @@ impl SimpleComponent for MainView { self.selected_profile.clone(), )); } else { - self.profile_not_editable_dialog.present(); + self.profile_not_editable_dialog + .present(Some(&self.root_win)); } } Self::Input::CreateProfile => { sender.input(Self::Input::OpenProfileEditor(Profile::default())); } Self::Input::DeleteProfile => { - self.profile_delete_confirm_dialog.present(); + self.profile_delete_confirm_dialog + .present(Some(&self.root_win)); } Self::Input::SaveProfile(prof) => { sender @@ -678,10 +679,7 @@ impl SimpleComponent for MainView { root: Self::Root, sender: ComponentSender, ) -> ComponentParts { - let profile_not_editable_dialog = adw::MessageDialog::builder() - .modal(true) - .transient_for(&init.root_win) - .hide_on_close(true) + let profile_not_editable_dialog = adw::AlertDialog::builder() .heading("This profile is not editable") .body(concat!( "You can duplicate it and edit the new copy. ", @@ -690,40 +688,43 @@ impl SimpleComponent for MainView { .build(); profile_not_editable_dialog.add_response("no", "_No"); profile_not_editable_dialog.add_response("yes", "_Yes"); - profile_not_editable_dialog.set_response_appearance("no", ResponseAppearance::Destructive); profile_not_editable_dialog.set_response_appearance("yes", ResponseAppearance::Suggested); - { - let pne_sender = sender.clone(); - profile_not_editable_dialog.connect_response(None, move |_, res| { - if res == "yes" { - pne_sender.input(Self::Input::DuplicateProfile); + profile_not_editable_dialog.connect_response( + None, + clone!( + #[strong] + sender, + move |_, res| { + if res == "yes" { + sender.input(Self::Input::DuplicateProfile); + } } - }); - } + ), + ); - let profile_delete_confirm_dialog = adw::MessageDialog::builder() - .modal(true) - .transient_for(&init.root_win) - .hide_on_close(true) + let profile_delete_confirm_dialog = adw::AlertDialog::builder() .heading("Are you sure you want to delete this profile?") .build(); profile_delete_confirm_dialog.add_response("no", "_No"); profile_delete_confirm_dialog.add_response("yes", "_Yes"); profile_delete_confirm_dialog - .set_response_appearance("no", ResponseAppearance::Destructive); - profile_delete_confirm_dialog.set_response_appearance("yes", ResponseAppearance::Suggested); + .set_response_appearance("yes", ResponseAppearance::Destructive); - { - let pdc_sender = sender.clone(); - profile_delete_confirm_dialog.connect_response(None, move |_, res| { - if res == "yes" { - pdc_sender - .output(Self::Output::DeleteProfile) - .expect("Sender output failed"); + profile_delete_confirm_dialog.connect_response( + None, + clone!( + #[strong] + sender, + move |_, res| { + if res == "yes" { + sender + .output(Self::Output::DeleteProfile) + .expect("Sender output failed"); + } } - }); - } + ), + ); let steamvr_calibration_box = SteamVrCalibrationBox::builder().launch(()).detach(); steamvr_calibration_box