diff --git a/lact-client/src/lib.rs b/lact-client/src/lib.rs index 40c415d..392b5c7 100644 --- a/lact-client/src/lib.rs +++ b/lact-client/src/lib.rs @@ -116,6 +116,7 @@ impl DaemonClient { request_plain!(enable_overdrive, EnableOverdrive, String); request_plain!(disable_overdrive, DisableOverdrive, String); request_plain!(generate_debug_snapshot, GenerateSnapshot, String); + request_plain!(reset_config, RestConfig, ()); request_with_id!(get_device_info, DeviceInfo, DeviceInfo); request_with_id!(get_device_stats, DeviceStats, DeviceStats); request_with_id!(get_device_clocks_info, DeviceClocksInfo, ClocksInfo); diff --git a/lact-daemon/src/config.rs b/lact-daemon/src/config.rs index 9671d77..c380045 100644 --- a/lact-daemon/src/config.rs +++ b/lact-daemon/src/config.rs @@ -62,7 +62,7 @@ impl Default for Daemon { pub struct Gpu { pub fan_control_enabled: bool, pub fan_control_settings: Option, - #[serde(default)] + #[serde(default, skip_serializing_if = "PmfwOptions::is_empty")] pub pmfw_options: PmfwOptions, pub power_cap: Option, pub performance_level: Option, @@ -70,9 +70,9 @@ pub struct Gpu { pub clocks_configuration: ClocksConfiguration, pub power_profile_mode_index: Option, /// Outer vector is for power profile components, inner vector is for the heuristics within a component - #[serde(default)] + #[serde(default, skip_serializing_if = "Vec::is_empty")] pub custom_power_profile_mode_hueristics: Vec>>, - #[serde(default)] + #[serde(default, skip_serializing_if = "HashMap::is_empty")] pub power_states: HashMap>, } diff --git a/lact-daemon/src/server/handler.rs b/lact-daemon/src/server/handler.rs index ec79a34..3a6c4b6 100644 --- a/lact-daemon/src/server/handler.rs +++ b/lact-daemon/src/server/handler.rs @@ -246,7 +246,7 @@ impl<'a> Handler { config_guard.gpus.insert(id, new_config); if let Err(err) = config_guard.save() { - error!("{err}"); + error!("{err:#}"); } *handler.config_last_saved.lock().unwrap() = Instant::now(); @@ -604,7 +604,21 @@ impl<'a> Handler { } } - pub async fn cleanup(self) { + pub async fn reset_config(&self) { + self.cleanup().await; + + let mut config = self.config.borrow_mut(); + config.gpus.clear(); + + *self.config_last_saved.lock().unwrap() = Instant::now(); + if let Err(err) = config.save() { + error!("could not save config: {err:#}"); + } + + *self.config_last_saved.lock().unwrap() = Instant::now(); + } + + pub async fn cleanup(&self) { let disable_clocks_cleanup = self .config .try_borrow() diff --git a/lact-daemon/src/server/mod.rs b/lact-daemon/src/server/mod.rs index 5d03a7b..581f8ef 100644 --- a/lact-daemon/src/server/mod.rs +++ b/lact-daemon/src/server/mod.rs @@ -119,6 +119,10 @@ async fn handle_request<'a>(request: Request<'a>, handler: &'a Handler) -> anyho Request::ConfirmPendingConfig(command) => { ok_response(handler.confirm_pending_config(command)?) } + Request::RestConfig => { + handler.reset_config().await; + ok_response(()) + } } } diff --git a/lact-gui/src/app/header.rs b/lact-gui/src/app/header.rs index 1b3e96e..43063be 100644 --- a/lact-gui/src/app/header.rs +++ b/lact-gui/src/app/header.rs @@ -39,6 +39,8 @@ impl Header { ) } + menu.append(Some("Reset all configuration"), Some("app.reset-config")); + let menu_button = MenuButton::builder() .icon_name("open-menu-symbolic") .menu_model(&menu) diff --git a/lact-gui/src/app/mod.rs b/lact-gui/src/app/mod.rs index aa442e4..c4410c8 100644 --- a/lact-gui/src/app/mod.rs +++ b/lact-gui/src/app/mod.rs @@ -281,11 +281,25 @@ impl App { )) .build(); + let reset_config_action = ActionEntry::builder("reset-config") + .activate(clone!( + #[strong] + app, + #[strong] + current_gpu_id, + move |_, _, _| { + let gpu_id = current_gpu_id.borrow().clone(); + app.reset_config(gpu_id); + } + )) + .build(); + app.application.add_action_entries([ snapshot_action, disable_overdive_action, show_graphs_window_action, dump_vbios_action, + reset_config_action, ]); app.start_stats_update_loop(current_gpu_id); @@ -616,7 +630,7 @@ impl App { .daemon_client .batch_set_clocks_value(&gpu_id, clocks_commands) .context("Could not commit clocks settings")?; - self.ask_confirmation(gpu_id.clone(), delay); + self.ask_settings_confirmation(gpu_id.clone(), delay); } self.set_initial(&gpu_id); @@ -809,7 +823,37 @@ impl App { } } - fn ask_confirmation(&self, gpu_id: String, mut delay: u64) { + fn reset_config(&self, gpu_id: String) { + let dialog = MessageDialog::builder() + .title("Reset configuration") + .text("Are you sure you want to reset all GPU configuration?") + .message_type(MessageType::Question) + .buttons(ButtonsType::YesNo) + .transient_for(&self.window) + .build(); + + dialog.run_async(clone!( + #[strong(rename_to = app)] + self, + move |diag, response| { + diag.hide(); + + if response == ResponseType::Yes { + if let Err(err) = app + .daemon_client + .reset_config() + .and_then(|response| response.inner()) + { + show_error(&app.window, err); + } + + app.set_initial(&gpu_id); + } + } + )); + } + + fn ask_settings_confirmation(&self, gpu_id: String, mut delay: u64) { let text = confirmation_text(delay); let dialog = MessageDialog::builder() .title("Confirm settings") diff --git a/lact-schema/src/lib.rs b/lact-schema/src/lib.rs index a6e6300..dd102eb 100644 --- a/lact-schema/src/lib.rs +++ b/lact-schema/src/lib.rs @@ -277,6 +277,12 @@ pub struct PmfwOptions { pub target_temperature: Option, } +impl PmfwOptions { + pub fn is_empty(&self) -> bool { + *self == Self::default() + } +} + #[skip_serializing_none] #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)] pub struct FanOptions<'a> { diff --git a/lact-schema/src/request.rs b/lact-schema/src/request.rs index b0bab03..cf38695 100644 --- a/lact-schema/src/request.rs +++ b/lact-schema/src/request.rs @@ -61,6 +61,7 @@ pub enum Request<'a> { DisableOverdrive, GenerateSnapshot, ConfirmPendingConfig(ConfirmCommand), + RestConfig, } #[derive(Serialize, Deserialize, Debug, PartialEq)]