feat(about): improve GPU names by getting info from wgpu
This commit is contained in:
parent
fffee57149
commit
29f1386e58
8 changed files with 488 additions and 573 deletions
|
|
@ -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"]
|
||||
|
|
@ -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)
|
||||
)
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
// Copyright 2023 System76 <info@system76.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
pub mod about;
|
||||
Loading…
Add table
Add a link
Reference in a new issue