mirror of
https://github.com/ilya-zlobintsev/LACT.git
synced 2026-11-03 12:50:31 -06:00
feat: oc page QoL (#1193)
* feat: move warning to sidebar and make it more specific (cherry picked from commitac745e669d) * phrasing (cherry picked from commit44d87a13d9) * remove wrapper (cherry picked from commit3bcad769e3) * shorten description a bit (cherry picked from commitf37485c34f) * use info-dialog to guard manual p-lvl for p-states conf (cherry picked from commit563dfac8f4) * p-level/powermizer: use more compact description (cherry picked from commite8c858d7a0) * p-level fix formatting * less agressive wording for warning * fix typo * remove oc-warning
This commit is contained in:
1 parent
4d326a46f7
commit
b81a3771ed
9 files changed
+138
-66
No files matched your search
@@ -151,9 +151,9 @@ performance-level-high-description = Always use the highest clockspeeds for GPU
|
||||
performance-level-low-description = Always use the lowest clockspeeds for GPU and VRAM
|
||||
performance-level-manual-description = Manual performance control
|
||||
performance-level-profile-standard-description = Fixed profiling mode
|
||||
performance-level-profile-min-sclk-description = Profiling mode that forces the GPU clock to lowest level
|
||||
performance-level-profile-min-mclk-description = Profiling mode that forces the VRAM clock to lowest level
|
||||
performance-level-profile-peak-description = Profiling mode that forces GPU and VRAM clocks to highest levels
|
||||
performance-level-profile-min-sclk-description = Forces the GPU clock to lowest level
|
||||
performance-level-profile-min-mclk-description = Forces the VRAM clock to lowest level
|
||||
performance-level-profile-peak-description = Forces GPU and VRAM clocks to highest levels
|
||||
|
||||
performance-level = Performance Level
|
||||
power-profile-mode = Power Profile Mode:
|
||||
@@ -180,7 +180,6 @@ nvidia-oc-description =
|
||||
It is possible to achieve a pseudo-undervolt by combining the locked clocks option with a positive clockspeed offset.
|
||||
This will force the GPU to run at a voltage that's constrained by the locked clocks, while achieving a higher clockspeed due to the offset.
|
||||
This can cause system instability if pushed too high.
|
||||
oc-warning = Changing these values may lead to system instability and can potentially damage your hardware!
|
||||
show-all-pstates = Show all P-States
|
||||
enable-gpu-locked-clocks = Enable GPU Locked Clocks
|
||||
enable-vram-locked-clocks = Enable VRAM Locked Clocks
|
||||
@@ -221,8 +220,8 @@ mem-pstate-clock-voltage = VRAM P-State {$pstate} Voltage (mV)
|
||||
pstates = Power States
|
||||
gpu-pstates = GPU Power States
|
||||
vram-pstates = VRAM Power States
|
||||
pstates-manual-needed = Performance level must be set to 'manual' to toggle power states
|
||||
enable-pstate-config = Enable power state configuration
|
||||
pstates-manual-needed = To enable P-State configuration, the performance level must be set to Manual.
|
||||
enable-pstate-config = P-State Configuration
|
||||
|
||||
menu = Menu
|
||||
show-historical-charts = Show Graphs
|
||||
|
||||
@@ -13,3 +13,12 @@
|
||||
.main-sidebar-container .sidebar-section {
|
||||
margin: 4px 8px 8px 8px;
|
||||
}
|
||||
|
||||
.oc-warning-button > button {
|
||||
color: @warning_color;
|
||||
background: alpha(@warning_color, 0.15);
|
||||
}
|
||||
|
||||
.oc-warning-button > button:hover {
|
||||
background: alpha(@warning_color, 0.25);
|
||||
}
|
||||
@@ -850,6 +850,24 @@ impl AppModel {
|
||||
self.overdrive_dialog.emit(OverdriveDialogMsg::Loaded);
|
||||
result?;
|
||||
}
|
||||
AppMsg::EnablePstateConfig => {
|
||||
self.info_dialog
|
||||
.emit(InfoDialogMsg::Show(Box::new(InfoDialogData {
|
||||
id: InfoDialogId::EnablePstateConfigConfirmation,
|
||||
heading: fl!(I18N, "enable-pstate-config"),
|
||||
body: fl!(I18N, "pstates-manual-needed"),
|
||||
confirmation: Some(InfoDialogConfirmation {
|
||||
confirm_label: fl!(I18N, "confirm"),
|
||||
cancel_label: fl!(I18N, "cancel"),
|
||||
appearance: adw::ResponseAppearance::Suggested,
|
||||
confirm_msg: AppMsg::EnablePstateConfigConfirmed,
|
||||
}),
|
||||
..Default::default()
|
||||
})));
|
||||
}
|
||||
AppMsg::EnablePstateConfigConfirmed => {
|
||||
self.oc_page.emit(OcPageMsg::EnablePstateConfig);
|
||||
}
|
||||
AppMsg::ResetConfig => {
|
||||
self.info_dialog
|
||||
.emit(InfoDialogMsg::Show(Box::new(InfoDialogData {
|
||||
|
||||
@@ -17,6 +17,7 @@ pub enum InfoDialogId {
|
||||
Unknown,
|
||||
Error,
|
||||
ResetConfigConfirmation,
|
||||
EnablePstateConfigConfirmation,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
|
||||
@@ -35,6 +35,8 @@ pub enum AppMsg {
|
||||
DisableOverdrive,
|
||||
ResetConfig,
|
||||
ResetConfigConfirmed,
|
||||
EnablePstateConfig,
|
||||
EnablePstateConfigConfirmed,
|
||||
FetchProcessList,
|
||||
ReloadProfiles {
|
||||
state_sender: Option<relm4::Sender<ProfileRuleRowMsg>>,
|
||||
|
||||
@@ -4,6 +4,7 @@ mod power_cap_section;
|
||||
mod power_states;
|
||||
mod vf_curve;
|
||||
|
||||
use crate::APP_BROKER;
|
||||
use crate::app::components::gpu_stats_section::{
|
||||
GpuStat, GpuStatsSection, GpuStatsSectionConfig, GpuStatsSectionMsg,
|
||||
};
|
||||
@@ -57,6 +58,8 @@ pub enum OcPageMsg {
|
||||
configured: bool,
|
||||
},
|
||||
PerformanceLevelChanged,
|
||||
SetPerformanceLevel(PerformanceLevel),
|
||||
EnablePstateConfig,
|
||||
ShowVfCurveEditor,
|
||||
VfCurveEditingToggled(bool),
|
||||
}
|
||||
@@ -110,7 +113,8 @@ impl relm4::Component for OcPage {
|
||||
vf_curve_editing: vf_curve_editing.clone(),
|
||||
})
|
||||
.forward(sender.input_sender(), |msg| msg);
|
||||
let power_states_frame = PowerStatesFrame::detach_default();
|
||||
let power_states_frame =
|
||||
PowerStatesFrame::launch_default().forward(sender.input_sender(), |msg| msg);
|
||||
let performance_frame =
|
||||
PerformanceFrame::launch_default().forward(sender.input_sender(), |msg| msg);
|
||||
|
||||
@@ -230,6 +234,15 @@ impl relm4::Component for OcPage {
|
||||
self.get_performance_level(),
|
||||
));
|
||||
}
|
||||
OcPageMsg::SetPerformanceLevel(level) => {
|
||||
self.performance_frame
|
||||
.emit(PerformanceFrameMsg::PerformanceLevel(Some(level)));
|
||||
APP_BROKER.send(AppMsg::SettingsChanged);
|
||||
}
|
||||
OcPageMsg::EnablePstateConfig => {
|
||||
self.power_states_frame
|
||||
.emit(PowerStatesFrameMsg::EnableWithManualPerformanceLevel);
|
||||
}
|
||||
OcPageMsg::ShowVfCurveEditor => {
|
||||
self.vf_curve_editor.emit(VfCurveEditorMsg::Show);
|
||||
}
|
||||
|
||||
@@ -112,14 +112,6 @@ impl relm4::Component for ClocksFrame {
|
||||
},
|
||||
},
|
||||
|
||||
append_child = >k::Label {
|
||||
set_label: &fl!(I18N, "oc-warning"),
|
||||
set_wrap_mode: pango::WrapMode::Word,
|
||||
set_halign: gtk::Align::Start,
|
||||
add_css_class: css::WARNING,
|
||||
add_css_class: css::DIM_LABEL,
|
||||
},
|
||||
|
||||
append_child = >k::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 5,
|
||||
|
||||
@@ -14,7 +14,7 @@ use gtk::{
|
||||
use heuristics_list::PowerProfileHeuristicsList;
|
||||
use i18n_embed_fl::fl;
|
||||
use nvml_wrapper::enums::device::PowerMizerMode;
|
||||
use relm4::{Component, ComponentController, ComponentParts, ComponentSender, RelmWidgetExt};
|
||||
use relm4::{Component, ComponentController, ComponentParts, ComponentSender, RelmWidgetExt, css};
|
||||
|
||||
const PERFORMANCE_LEVELS: [PerformanceLevel; 8] = [
|
||||
PerformanceLevel::Auto,
|
||||
@@ -67,28 +67,39 @@ impl relm4::Component for PerformanceFrame {
|
||||
#[watch]
|
||||
set_visible: model.performance_level.is_some(),
|
||||
|
||||
gtk::Label {
|
||||
set_label: &fl!(I18N, "performance-level"),
|
||||
},
|
||||
|
||||
gtk::Label {
|
||||
#[watch]
|
||||
set_label: &match model.performance_level {
|
||||
Some(PerformanceLevel::Auto) => fl!(I18N, "performance-level-auto-description"),
|
||||
Some(PerformanceLevel::High) => fl!(I18N, "performance-level-high-description"),
|
||||
Some(PerformanceLevel::Low) => fl!(I18N, "performance-level-low-description"),
|
||||
Some(PerformanceLevel::Manual) => fl!(I18N, "performance-level-manual-description"),
|
||||
Some(PerformanceLevel::ProfileStandard) => fl!(I18N, "performance-level-profile-standard-description"),
|
||||
Some(PerformanceLevel::ProfileMinSclk) => fl!(I18N, "performance-level-profile-min-sclk-description"),
|
||||
Some(PerformanceLevel::ProfileMinMclk) => fl!(I18N, "performance-level-profile-min-mclk-description"),
|
||||
Some(PerformanceLevel::ProfilePeak) => fl!(I18N, "performance-level-profile-peak-description"),
|
||||
_ => String::new(),
|
||||
},
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_hexpand: true,
|
||||
set_halign: gtk::Align::End,
|
||||
set_valign: gtk::Align::Center,
|
||||
|
||||
gtk::Label {
|
||||
set_label: &fl!(I18N, "performance-level"),
|
||||
set_halign: gtk::Align::Start,
|
||||
},
|
||||
|
||||
gtk::Label {
|
||||
#[watch]
|
||||
set_label: &match model.performance_level {
|
||||
Some(PerformanceLevel::Auto) => fl!(I18N, "performance-level-auto-description"),
|
||||
Some(PerformanceLevel::High) => fl!(I18N, "performance-level-high-description"),
|
||||
Some(PerformanceLevel::Low) => fl!(I18N, "performance-level-low-description"),
|
||||
Some(PerformanceLevel::Manual) => fl!(I18N, "performance-level-manual-description"),
|
||||
Some(PerformanceLevel::ProfileStandard) => fl!(I18N, "performance-level-profile-standard-description"),
|
||||
Some(PerformanceLevel::ProfileMinSclk) => fl!(I18N, "performance-level-profile-min-sclk-description"),
|
||||
Some(PerformanceLevel::ProfileMinMclk) => fl!(I18N, "performance-level-profile-min-mclk-description"),
|
||||
Some(PerformanceLevel::ProfilePeak) => fl!(I18N, "performance-level-profile-peak-description"),
|
||||
_ => String::new(),
|
||||
},
|
||||
set_halign: gtk::Align::Start,
|
||||
set_xalign: 0.0,
|
||||
set_wrap: true,
|
||||
add_css_class: css::DIM_LABEL,
|
||||
add_css_class: css::CAPTION,
|
||||
},
|
||||
},
|
||||
|
||||
gtk::DropDown::from_strings(&level_names_ref) {
|
||||
set_valign: gtk::Align::Center,
|
||||
#[watch]
|
||||
#[block_signal(level_select_handler)]
|
||||
set_selected: PERFORMANCE_LEVELS.iter().position(|level| model.performance_level == Some(*level)).unwrap_or(0) as u32,
|
||||
@@ -97,7 +108,6 @@ impl relm4::Component for PerformanceFrame {
|
||||
let idx = dropdown.selected();
|
||||
if let Some(level) = PERFORMANCE_LEVELS.get(idx as usize) {
|
||||
sender.input(PerformanceFrameMsg::PerformanceLevel(Some(*level)));
|
||||
sender.output(OcPageMsg::PerformanceLevelChanged).unwrap();
|
||||
APP_BROKER.send(AppMsg::SettingsChanged);
|
||||
}
|
||||
} @ level_select_handler,
|
||||
@@ -179,25 +189,36 @@ impl relm4::Component for PerformanceFrame {
|
||||
#[watch]
|
||||
set_visible: model.active_power_mizer_mode.is_some(),
|
||||
|
||||
gtk::Label {
|
||||
set_label: &fl!(I18N, "power-mizer-mode"),
|
||||
},
|
||||
|
||||
gtk::Label {
|
||||
#[watch]
|
||||
set_label: &match model.active_power_mizer_mode {
|
||||
Some(PowerMizerMode::Auto) => fl!(I18N, "power-mizer-mode-auto-description"),
|
||||
Some(PowerMizerMode::Adaptive) => fl!(I18N, "power-mizer-mode-adaptive-description"),
|
||||
Some(PowerMizerMode::PreferMaximumPerformance) => fl!(I18N, "power-mizer-mode-prefer-maximum-performance-description"),
|
||||
Some(PowerMizerMode::PreferConsistentPerformance) => fl!(I18N, "power-mizer-mode-prefer-consistent-performance-description"),
|
||||
None => String::new(),
|
||||
},
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_hexpand: true,
|
||||
set_halign: gtk::Align::End,
|
||||
set_valign: gtk::Align::Center,
|
||||
|
||||
gtk::Label {
|
||||
set_label: &fl!(I18N, "power-mizer-mode"),
|
||||
set_halign: gtk::Align::Start,
|
||||
},
|
||||
|
||||
gtk::Label {
|
||||
#[watch]
|
||||
set_label: &match model.active_power_mizer_mode {
|
||||
Some(PowerMizerMode::Auto) => fl!(I18N, "power-mizer-mode-auto-description"),
|
||||
Some(PowerMizerMode::Adaptive) => fl!(I18N, "power-mizer-mode-adaptive-description"),
|
||||
Some(PowerMizerMode::PreferMaximumPerformance) => fl!(I18N, "power-mizer-mode-prefer-maximum-performance-description"),
|
||||
Some(PowerMizerMode::PreferConsistentPerformance) => fl!(I18N, "power-mizer-mode-prefer-consistent-performance-description"),
|
||||
None => String::new(),
|
||||
},
|
||||
set_halign: gtk::Align::Start,
|
||||
set_xalign: 0.0,
|
||||
set_wrap: true,
|
||||
add_css_class: css::DIM_LABEL,
|
||||
add_css_class: css::CAPTION,
|
||||
},
|
||||
},
|
||||
|
||||
#[name = "power_mizer_dropdown"]
|
||||
gtk::DropDown {
|
||||
set_valign: gtk::Align::Center,
|
||||
#[watch]
|
||||
#[block_signal(power_mizer_select_handler)]
|
||||
set_model: Some(&model.power_mizer_modes),
|
||||
@@ -251,6 +272,7 @@ impl relm4::Component for PerformanceFrame {
|
||||
match msg {
|
||||
PerformanceFrameMsg::PerformanceLevel(level) => {
|
||||
self.performance_level = level;
|
||||
sender.output(OcPageMsg::PerformanceLevelChanged).unwrap();
|
||||
}
|
||||
PerformanceFrameMsg::PowerProfileModes(table) => {
|
||||
while self.power_profile_modes.n_items() != 0 {
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::{
|
||||
APP_BROKER, I18N,
|
||||
app::{
|
||||
components::page_section_expander::PageSectionExpander, msg::AppMsg,
|
||||
utils::ext::RelmLaunchable as _,
|
||||
pages::oc_page::OcPageMsg, utils::ext::RelmLaunchable as _,
|
||||
},
|
||||
};
|
||||
use amdgpu_sysfs::gpu_handle::{PerformanceLevel, PowerLevelKind};
|
||||
@@ -16,9 +16,8 @@ use i18n_embed_fl::fl;
|
||||
use indexmap::IndexMap;
|
||||
use lact_schema::{DeviceStats, PowerStates};
|
||||
use relm4::{
|
||||
ComponentController, ComponentParts, ComponentSender, RelmObjectExt,
|
||||
ComponentController, ComponentParts, ComponentSender,
|
||||
binding::{Binding, BoolBinding},
|
||||
css,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -42,6 +41,10 @@ pub enum PowerStatesFrameMsg {
|
||||
PerformanceLevel(Option<PerformanceLevel>),
|
||||
VramClockRatio(f64),
|
||||
Configurable(bool),
|
||||
ConfiguredToggled {
|
||||
configured: bool,
|
||||
},
|
||||
EnableWithManualPerformanceLevel,
|
||||
InternalConfigurableChanged(bool),
|
||||
}
|
||||
|
||||
@@ -49,7 +52,7 @@ pub enum PowerStatesFrameMsg {
|
||||
impl relm4::SimpleComponent for PowerStatesFrame {
|
||||
type Init = ();
|
||||
type Input = PowerStatesFrameMsg;
|
||||
type Output = ();
|
||||
type Output = OcPageMsg;
|
||||
|
||||
view! {
|
||||
PageSectionExpander::new(&fl!(I18N, "pstates")) {
|
||||
@@ -57,21 +60,20 @@ impl relm4::SimpleComponent for PowerStatesFrame {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 5,
|
||||
|
||||
gtk::Label {
|
||||
set_label: &fl!(I18N, "pstates-manual-needed"),
|
||||
add_css_class: css::DIM_LABEL,
|
||||
set_halign: gtk::Align::Start,
|
||||
#[watch]
|
||||
set_visible: model.performance_level.is_some_and(|level| level != PerformanceLevel::Manual),
|
||||
},
|
||||
|
||||
gtk::CheckButton {
|
||||
set_label: Some(&fl!(I18N, "enable-pstate-config")),
|
||||
add_binding: (&model.states_configured, "active"),
|
||||
#[watch]
|
||||
#[block_signal(configured_toggled_handler)]
|
||||
set_active: model.states_configured.value(),
|
||||
|
||||
connect_toggled[sender] => move |button| {
|
||||
sender.input(PowerStatesFrameMsg::ConfiguredToggled {
|
||||
configured: button.is_active(),
|
||||
});
|
||||
} @ configured_toggled_handler,
|
||||
|
||||
#[watch]
|
||||
set_visible: model.performance_level.is_some(),
|
||||
#[watch]
|
||||
set_sensitive: model.performance_level.is_some_and(|level| level == PerformanceLevel::Manual),
|
||||
},
|
||||
|
||||
gtk::Box {
|
||||
@@ -110,8 +112,9 @@ impl relm4::SimpleComponent for PowerStatesFrame {
|
||||
|
||||
let states_configured = BoolBinding::new(false);
|
||||
|
||||
let configured_sender = sender.clone();
|
||||
let configured_signal = states_configured.connect_value_notify(move |states_configured| {
|
||||
sender.input(PowerStatesFrameMsg::InternalConfigurableChanged(
|
||||
configured_sender.input(PowerStatesFrameMsg::InternalConfigurableChanged(
|
||||
states_configured.get(),
|
||||
));
|
||||
APP_BROKER.send(AppMsg::SettingsChanged);
|
||||
@@ -132,7 +135,7 @@ impl relm4::SimpleComponent for PowerStatesFrame {
|
||||
ComponentParts { model, widgets }
|
||||
}
|
||||
|
||||
fn update(&mut self, msg: Self::Input, _sender: ComponentSender<Self>) {
|
||||
fn update(&mut self, msg: Self::Input, sender: ComponentSender<Self>) {
|
||||
match msg {
|
||||
PowerStatesFrameMsg::PowerStates {
|
||||
pstates,
|
||||
@@ -182,6 +185,19 @@ impl relm4::SimpleComponent for PowerStatesFrame {
|
||||
PowerStatesFrameMsg::PerformanceLevel(level) => {
|
||||
self.performance_level = level;
|
||||
}
|
||||
PowerStatesFrameMsg::ConfiguredToggled { configured } => {
|
||||
if !configured || self.performance_level == Some(PerformanceLevel::Manual) {
|
||||
self.states_configured.set_value(configured);
|
||||
} else {
|
||||
APP_BROKER.send(AppMsg::EnablePstateConfig);
|
||||
}
|
||||
}
|
||||
PowerStatesFrameMsg::EnableWithManualPerformanceLevel => {
|
||||
sender
|
||||
.output(OcPageMsg::SetPerformanceLevel(PerformanceLevel::Manual))
|
||||
.unwrap();
|
||||
self.states_configured.set_value(true);
|
||||
}
|
||||
PowerStatesFrameMsg::InternalConfigurableChanged(configurable) => {
|
||||
self.core_states_list
|
||||
.emit(PowerStatesListMsg::Configurable(configurable));
|
||||
|
||||
Reference in new issue
Block a user