feat: show additional clock domains in UI (#1172)

* feat: show additional clock domains in UI

* fix: tests
This commit is contained in:
Ilya Zlobintsev authored and GitHub committed 2026-08-23 18:14:33 +03:00
1 parent 6f02740b2f
commit df20b606de
9 files changed
+61 -8

No files matched your search

+1 -1
View File
@@ -516,7 +516,7 @@ impl AmdGpuController {
.map(u64::from)
.or_else(|| self.hw_mon_and_then(HwMon::get_vram_clockspeed));
let mut sensors = HashMap::new();
let mut sensors = IndexMap::new();
let mut target_gpu_clockspeed = None;
@@ -942,7 +942,7 @@ impl GpuController for IntelGpuController {
gpu_clockspeed,
target_gpu_clockspeed,
vram_clockspeed: None,
sensors: HashMap::new(),
sensors: IndexMap::new(),
};
let power = PowerStats {
@@ -899,7 +899,7 @@ impl GpuController for NvidiaGpuController {
]
.into_iter()
.filter_map(|(name, value)| Some((name.to_owned(), u64::from(value.ok()?))))
.collect::<HashMap<String, u64>>();
.collect::<IndexMap<String, u64>>();
let mut voltage = None;
+1
View File
@@ -131,6 +131,7 @@ gpu-temp = Temperature
gpu-usage = GPU Usage
vram-clock = VRAM Clock
power-usage = Power Usage
extra-clocks = Extra Clocks
no-throttling = No
unknown-throttling = Unknown
missing-stat = N/A
@@ -49,7 +49,7 @@ impl relm4::SimpleComponent for GpuStatsSection {
set_orientation: gtk::Orientation::Vertical,
set_spacing: 10,
PageSection::new("") {
PageSection {
#[watch]
set_visible: model.visible_count(GpuStatDisplay::Digits) > 0,
@@ -144,10 +144,39 @@ impl relm4::SimpleComponent for GpuStatsSection {
#[watch]
set_visible: model.shows(GpuStat::Temperature) && !secondary_temperatures.is_empty(),
},
append_child = &InfoRow {
set_name: fl!(I18N, "extra-clocks"),
set_max_value_width_chars: 40,
#[watch]
set_value: extra_clocks.join(", "),
set_icon: "go-down-symbolic".to_string(),
#[name = "secondary_clocks_popover"]
set_popover = &gtk::Popover {
gtk::Label {
set_margin_all: 10,
set_selectable: false,
set_use_markup: true,
set_attributes: Some(&AttrList::from_str("0 -1 weight bold").unwrap()),
#[watch]
set_label: &extra_clocks.join("\n"),
},
},
connect_clicked[secondary_clocks_popover] => move |_| {
secondary_clocks_popover.popup();
},
} -> extra_clocks_item: gtk::FlowBoxChild {
#[watch]
set_visible: model.shows(GpuStat::ExtraClocks),
},
},
},
PageSection::new("") {
PageSection {
#[watch]
set_visible: model.visible_count(GpuStatDisplay::LevelBar) > 0,
@@ -338,6 +367,7 @@ impl relm4::SimpleComponent for GpuStatsSection {
let (primary_temperatures, secondary_temperatures): (Vec<String>, Vec<String>) =
(Vec::new(), Vec::new());
let extra_clocks: Vec<String> = Vec::new();
let model = Self {
stats_to_show: config.stats,
@@ -385,6 +415,8 @@ impl relm4::SimpleComponent for GpuStatsSection {
fn pre_view(&self) {
let (primary_temperatures, secondary_temperatures) =
formatting::fmt_temperature_text(&model.stats);
let extra_clocks = extra_clocks(&model.stats);
}
}
@@ -402,6 +434,7 @@ pub enum GpuStat {
Temperature,
GpuClock,
VramClock,
ExtraClocks,
GpuUsage,
VramUsage,
GttUsage,
@@ -424,7 +457,8 @@ impl GpuStat {
| Self::Throttling
| Self::GpuClockTarget
| Self::GpuVoltage
| Self::Temperature => GpuStatDisplay::Digits,
| Self::Temperature
| Self::ExtraClocks => GpuStatDisplay::Digits,
Self::GpuClock
| Self::VramClock
| Self::GpuUsage
@@ -459,6 +493,7 @@ impl GpuStatsSection {
GpuStat::PowerUsage => {
self.stats.power.average.is_some() || self.stats.power.current.is_some()
}
GpuStat::ExtraClocks => !self.stats.clockspeed.sensors.is_empty(),
}
}
@@ -487,3 +522,12 @@ fn format_current_gfxclk(value: Option<u64>) -> String {
fl!(I18N, "missing-stat")
}
}
fn extra_clocks(stats: &DeviceStats) -> Vec<String> {
stats
.clockspeed
.sensors
.iter()
.map(|(name, value)| format!("{name}: {}", formatting::fmt_clockspeed(Some(*value), 1.0)))
.collect::<Vec<_>>()
}
+7
View File
@@ -147,6 +147,8 @@ mod imp {
info_text: RefCell<String>,
#[property(get, set)]
icon: RefCell<String>,
#[property(get, set)]
max_value_width_chars: RefCell<i32>,
pub(super) info_menubutton: gtk::MenuButton,
pub(super) value_box: gtk::Box,
@@ -255,6 +257,11 @@ mod imp {
.sync_create()
.build();
obj.bind_property("max-value-width-chars", value_label, "max-width-chars")
.transform_to(|_, value: i32| if value == 0 { None } else { Some(value) })
.sync_create()
.build();
obj.bind_property("icon", &icon_image, "icon-name")
.sync_create()
.build();
+1 -1
View File
@@ -159,7 +159,7 @@ mod benches {
gpu_clockspeed: Some(500),
vram_clockspeed: Some(1000),
target_gpu_clockspeed: None,
sensors: HashMap::new(),
sensors: IndexMap::new(),
},
active_power_states: Some(ActivePowerStates {
core: Some(PowerLevelId::Index(0)),
+1
View File
@@ -102,6 +102,7 @@ impl relm4::Component for OcPage {
GpuStat::GttUsage,
GpuStat::PowerUsage,
GpuStat::FanSpeed,
GpuStat::ExtraClocks,
]),
});
let power_cap_section = PowerCapSection::detach_default();
+1 -1
View File
@@ -719,7 +719,7 @@ pub struct ClockspeedStats {
pub target_gpu_clockspeed: Option<u64>,
pub vram_clockspeed: Option<u64>,
#[serde(default)]
pub sensors: HashMap<String, u64>,
pub sensors: IndexMap<String, u64>,
}
#[skip_serializing_none]