feat(about): improve GPU names by getting info from wgpu

This commit is contained in:
Fred 2025-12-12 16:57:58 +01:00 committed by GitHub
parent fffee57149
commit 29f1386e58
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 488 additions and 573 deletions

View file

@ -1,19 +0,0 @@
[package]
name = "cosmic-settings-system"
version = "1.0.0-beta6"
edition = "2024"
license = "GPL-3.0-only"
rust-version.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
byte-unit = "5.1.6"
const_format = "0.2.35"
concat-in-place = "1.1.0"
sysinfo = "0.36.1"
memchr = "2.7.6"
[dependencies.bumpalo]
version = "3.19.0"
features = ["collections"]

View file

@ -1,244 +0,0 @@
// Copyright 2023 System76 <info@system76.com>
// SPDX-License-Identifier: GPL-3.0-only
use bumpalo::Bump;
use std::{collections::HashSet, ffi::OsStr, io::Read};
use concat_in_place::strcat;
use const_format::concatcp;
const DMI_DIR: &str = "/sys/devices/virtual/dmi/id/";
const BOARD_NAME: &str = concatcp!(DMI_DIR, "board_name");
const BOARD_VERSION: &str = concatcp!(DMI_DIR, "board_version");
const SYS_VENDOR: &str = concatcp!(DMI_DIR, "sys_vendor");
const VERSION_IGNORING_PRODUCTS: &[&str] = &["Dev One"];
#[must_use]
#[derive(Clone, Debug, Default)]
pub struct Info {
pub desktop_environment: String,
pub device_name: String,
pub disk_capacity: String,
pub graphics: Vec<String>,
pub hardware_model: String,
pub memory: String,
pub operating_system: String,
pub os_architecture: String,
pub kernel_version: String,
pub processor: String,
pub windowing_system: String,
}
impl Info {
pub fn load() -> Info {
let mut info = Info::default();
let mut bump = Bump::with_capacity(8 * 1024);
architecture(&bump, &mut info.os_architecture);
bump.reset();
kernel_version(&bump, &mut info.kernel_version);
bump.reset();
hardware_model(&bump, &mut info.hardware_model);
bump.reset();
operating_system(&bump, &mut info.operating_system);
bump.reset();
processor_name(&bump, &mut info.processor);
bump.reset();
let mut sys = sysinfo::System::new();
let disks = sysinfo::Disks::new_with_refreshed_list();
sys.refresh_memory();
let mut total_capacity = 0;
let mut disk_set = HashSet::new();
for disk in disks.list() {
if disk_set.contains(disk.name()) {
continue;
}
disk_set.insert(disk.name());
total_capacity += disk.total_space();
}
info.disk_capacity = format_size(total_capacity);
if let Some(name) = sysinfo::System::host_name() {
info.device_name = name;
}
info.memory = format_size(sys.total_memory());
if let Ok(mut session) = std::env::var("XDG_SESSION_TYPE") {
if let Some(first) = session.get_mut(0..1) {
first.make_ascii_uppercase();
}
info.windowing_system = session;
}
// prefer XDG_SESSION_DESKTOP because the value is singular: https://www.freedesktop.org/software/systemd/man/latest/pam_systemd.html
if let Ok(mut session) = std::env::var("XDG_SESSION_DESKTOP")
// otherwise, XDG_CURRENT_DESKTOP (could be plural): https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html
.or_else(|_| std::env::var("XDG_CURRENT_DESKTOP"))
// fallback to legacy environment variable
.or_else(|_| std::env::var("DESKTOP_SESSION"))
{
if let Some(first) = session.get_mut(0..1) {
first.make_ascii_uppercase();
}
info.desktop_environment = session;
}
if let Ok(output) = std::process::Command::new("lspci").output() {
if let Ok(stdout) = std::str::from_utf8(&output.stdout) {
for line in stdout.lines() {
if let Some(pos) = memchr::memmem::find(line.as_bytes(), b"VGA") {
let line = &line[pos + 3..];
if let Some(pos) = memchr::memmem::find(line.as_bytes(), b": ") {
info.graphics.push(String::from(&line[pos + 2..]));
}
}
}
}
}
info
}
}
pub fn architecture(bump: &Bump, arch: &mut String) {
let buffer = &mut bumpalo::collections::Vec::new_in(bump);
if let Some(value) = read_to_string("/proc/sys/kernel/arch", buffer) {
arch.push_str(value.trim());
}
}
pub fn kernel_version(bump: &Bump, kernel: &mut String) {
let buffer = &mut bumpalo::collections::Vec::new_in(bump);
if let Some(value) = read_to_string("/proc/version", buffer) {
if let Some(version) = value.split_whitespace().nth(2) {
kernel.push_str(version.trim());
}
}
}
pub fn hardware_model(bump: &Bump, hardware_model: &mut String) {
let buffer = &mut bumpalo::collections::Vec::new_in(bump);
if let Some(mut sys_vendor) = read_to_string(SYS_VENDOR, buffer) {
sys_vendor = sys_vendor.trim();
hardware_model.push_str(sys_vendor);
let buffer = &mut bumpalo::collections::Vec::new_in(bump);
if let Some(mut name) = read_to_string(BOARD_NAME, buffer) {
name = name.trim();
if !name.is_empty() && name != sys_vendor {
// Ensure that the name does not contain the vendor.
name = match name.strip_prefix(sys_vendor) {
Some(stripped) => stripped.trim(),
None => name,
};
let _str = strcat!(&mut *hardware_model, " " name);
}
let buffer = &mut bumpalo::collections::Vec::new_in(bump);
if let Some(mut version) = read_to_string(BOARD_VERSION, buffer) {
version = version.trim();
if !version.is_empty() && !VERSION_IGNORING_PRODUCTS.contains(&name) {
let _str = strcat!(hardware_model, " (" version.trim() ")");
}
}
}
} else {
// simple fallback to sysinfo if DMI information is not available
hardware_model.push_str(&sysinfo::Product::name().unwrap_or("".to_string()));
}
}
pub fn operating_system(bump: &Bump, operating_system: &mut String) {
let mut buffer = bumpalo::collections::Vec::new_in(bump);
let Some(os_release) = read_to_string("/etc/os-release", &mut buffer) else {
return;
};
for line in os_release.lines() {
if let Some(mut value) = line.strip_prefix("PRETTY_NAME=") {
if let Some(v) = value.strip_prefix('"') {
value = v;
}
if let Some(v) = value.strip_suffix('"') {
value = v;
}
operating_system.push_str(value.trim());
break;
}
}
}
pub fn processor_name(bump: &Bump, name: &mut String) {
if let Some(cpuinfo) = read_to_string(
"/proc/cpuinfo",
&mut bumpalo::collections::Vec::new_in(bump),
) {
for line in cpuinfo.lines() {
if let Some(info) = line.strip_prefix("model name") {
if let Some(info) = info.trim_start().strip_prefix(':') {
name.push_str(info.trim());
return;
}
break;
}
}
}
// fallback to sysinfo if /proc/cpuinfo is not present
let s = sysinfo::System::new_with_specifics(
sysinfo::RefreshKind::nothing().with_cpu(sysinfo::CpuRefreshKind::everything()),
);
name.push_str(s.cpus().iter().next().unwrap().brand());
}
pub fn read_to_string<'a, P: AsRef<OsStr>>(
path: P,
buffer: &'a mut bumpalo::collections::Vec<u8>,
) -> Option<&'a str> {
let mut file = std::fs::File::open(path.as_ref()).ok()?;
if let Ok(metadata) = file.metadata() {
if let Ok(len) = usize::try_from(metadata.len()) {
buffer.reserve_exact(len);
}
}
let mut buf = [0; 16 * 1024];
loop {
match file.read(&mut buf) {
Ok(0) => break,
Ok(read) => buffer.extend_from_slice(&buf[..read]),
Err(_) => return None,
}
}
std::str::from_utf8(buffer.as_slice()).ok()
}
fn format_size(size: u64) -> String {
format!(
"{:.2}",
byte_unit::Byte::from_u64(size).get_appropriate_unit(byte_unit::UnitType::Binary)
)
}

View file

@ -1,4 +0,0 @@
// Copyright 2023 System76 <info@system76.com>
// SPDX-License-Identifier: GPL-3.0-only
pub mod about;