Skip to content
This repository was archived by the owner on May 12, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 73 additions & 82 deletions Cargo.lock

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,21 @@ opt-level = 3
adw = { version = "0.8.1", features = ["v1_8"], package = "libadwaita" }
anyhow = { version = "1.0.102", features = ["backtrace"] }
async-channel = "2.5.0"
clap = { version = "4.5.60", features = ["derive"] }
clap = { version = "4.6.1", features = ["derive"] }
gettext-rs = { version = "0.7.7", features = ["gettext-system"] }
glob = "0.3.3"
gtk = { version = "0.10.3", features = ["v4_12"], package = "gtk4" }
lazy-regex = "3.6.0"
libc = { version = "0.2.182", features = ["extra_traits"] }
libc = { version = "0.2.186", features = ["extra_traits"] }
log = "0.4.29"
neli-wifi = { version = "0.6.1", features = ["default"] }
nix = { version = "0.31.2", default-features = false, features = [
"signal",
"sched",
] }
num_cpus = "1.17.0"
nvml-wrapper = "0.12.0"
pastey = "0.2.1"
nvml-wrapper = "0.12.1"
pastey = "0.2.2"
path-dedot = "3.1.1"
plotters = { version = "0.3.7", default-features = false, features = [
"area_series",
Expand All @@ -43,7 +43,7 @@ plotters-cairo = "0.8.0"
pretty_env_logger = "0.5"
process-data = { path = "lib/process_data" }
rmp-serde = "1.3.1"
ron = "0.12.0"
ron = "0.12.1"
rust-ini = "0.21.3"
futures = { version = "0.3", default-features = false, features = ["alloc"] }
serde_json = "1.0.149"
Expand Down
2 changes: 1 addition & 1 deletion build-aux/net.nokyan.Resources.Devel.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "net.nokyan.Resources.Devel",
"runtime": "org.gnome.Platform",
"runtime-version": "49",
"runtime-version": "50",
"sdk": "org.gnome.Sdk",
"sdk-extensions": [
"org.freedesktop.Sdk.Extension.rust-stable",
Expand Down
10 changes: 5 additions & 5 deletions src/ui/dialogs/app_dialog.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::config::PROFILE;
use crate::i18n::i18n;
use crate::ui::pages::applications::application_entry::ApplicationEntry;
use crate::utils::units::{convert_speed, convert_storage};
use crate::utils::units::{convert_fraction, convert_speed, convert_storage};
use adw::{prelude::*, subclass::prelude::*};
use gtk::gio::ThemedIcon;
use gtk::glib;
Expand Down Expand Up @@ -165,7 +165,7 @@ impl ResAppDialog {
let imp = self.imp();

imp.cpu_usage
.set_subtitle(&format!("{:.1} %", app.cpu_usage() * 100.0));
.set_subtitle(&convert_fraction(app.cpu_usage() as f64, false));

imp.memory_usage
.set_subtitle(&convert_storage(app.memory_usage() as f64, false));
Expand All @@ -186,16 +186,16 @@ impl ResAppDialog {
.set_subtitle(&convert_storage(app.write_total() as f64, false));

imp.gpu_usage
.set_subtitle(&format!("{:.1} %", app.gpu_usage() * 100.0));
.set_subtitle(&convert_fraction(app.gpu_usage() as f64, false));

imp.vram_usage
.set_subtitle(&convert_storage(app.gpu_mem_usage() as f64, false));

imp.encoder_usage
.set_subtitle(&format!("{:.1} %", app.enc_usage() * 100.0));
.set_subtitle(&convert_fraction(app.enc_usage() as f64, false));

imp.decoder_usage
.set_subtitle(&format!("{:.1} %", app.dec_usage() * 100.0));
.set_subtitle(&convert_fraction(app.dec_usage() as f64, false));

imp.processes_amount
.set_subtitle(&app.running_processes().to_string());
Expand Down
10 changes: 5 additions & 5 deletions src/ui/dialogs/process_dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use log::trace;
use crate::config::PROFILE;
use crate::i18n::i18n;
use crate::ui::pages::processes::process_entry::ProcessEntry;
use crate::utils::units::{convert_speed, convert_storage, format_time};
use crate::utils::units::{convert_fraction, convert_speed, convert_storage, format_time};

mod imp {

Expand Down Expand Up @@ -159,7 +159,7 @@ impl ResProcessDialog {
let imp = self.imp();

imp.cpu_usage
.set_subtitle(&format!("{:.1} %", process.cpu_usage() * 100.0));
.set_subtitle(&convert_fraction(process.cpu_usage() as f64, false));

imp.memory_usage
.set_subtitle(&convert_storage(process.memory_usage() as f64, false));
Expand Down Expand Up @@ -196,16 +196,16 @@ impl ResProcessDialog {
}

imp.gpu_usage
.set_subtitle(&format!("{:.1} %", process.gpu_usage() * 100.0));
.set_subtitle(&convert_fraction(process.gpu_usage() as f64, false));

imp.vram_usage
.set_subtitle(&convert_storage(process.gpu_mem_usage() as f64, false));

imp.encoder_usage
.set_subtitle(&format!("{:.1} %", process.enc_usage() * 100.0));
.set_subtitle(&convert_fraction(process.enc_usage() as f64, false));

imp.decoder_usage
.set_subtitle(&format!("{:.1} %", process.dec_usage() * 100.0));
.set_subtitle(&convert_fraction(process.dec_usage() as f64, false));

imp.total_cpu_time
.set_subtitle(&format_time(process.total_cpu_time()));
Expand Down
78 changes: 78 additions & 0 deletions src/ui/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
use adw::{ActionRow, prelude::ActionRowExt};

use crate::{
i18n::{i18n, i18n_f},
utils::units::{convert_fraction, convert_storage, convert_temperature},
};

extern crate pastey;

#[macro_export]
Expand Down Expand Up @@ -38,6 +45,77 @@ macro_rules! gstring_option_getter_setter {
};
}

fn set_subtitle_maybe<S: AsRef<str>>(subtitle: Option<S>, action_row: &ActionRow) {
if let Some(subtitle) = subtitle {
action_row.set_subtitle(subtitle.as_ref());
} else {
action_row.set_subtitle(&i18n("N/A"));
}
}

fn set_subtitle_converted_maybe<T, S: AsRef<str>, F: Fn(T) -> S>(
value: Option<T>,
stringify_fn: F,
action_row: &ActionRow,
) {
set_subtitle_maybe(value.map(stringify_fn), action_row);
}

fn set_subtitle_boolean(boolean: bool, action_row: &ActionRow) -> String {
let subtitle = if boolean { i18n("Yes") } else { i18n("No") };

action_row.set_subtitle(&subtitle);

subtitle
}

fn set_subtitle_boolean_maybe(boolean: Option<bool>, action_row: &ActionRow) -> String {
if let Some(boolean) = boolean {
set_subtitle_boolean(boolean, action_row)
} else {
action_row.set_subtitle(&i18n("N/A"));
i18n("N/A")
}
}

fn gpu_npu_usage_string(
usage_fraction: Option<f64>,
used_memory: Option<u64>,
total_memory: Option<u64>,
temperature: Option<f64>,
) -> String {
let mut elements = Vec::with_capacity(3);

if let Some(usage_fraction) = usage_fraction {
elements.push(convert_fraction(usage_fraction, true));
}

if let (Some(used_memory), Some(total_memory)) = (used_memory, total_memory) {
elements.push(i18n_f(
// Translators: This will be displayed in the sidebar, please try to keep your translation as short as (or even
// shorter than) 'Memory'
"Memory: {}",
&[&convert_fraction(
used_memory as f64 / total_memory as f64,
true,
)],
));
} else if let Some(used_memory) = used_memory {
elements.push(i18n_f(
// Translators: This will be displayed in the sidebar, please try to keep your translation as short as (or even
// shorter than) 'Memory'
"Memory: {}",
&[&convert_storage(used_memory as f64, true)],
));
}

if let Some(temperature) = temperature {
elements.push(convert_temperature(temperature));
}

elements.join(" · ").to_string()
}

pub mod dialogs;
pub mod pages;
pub mod widgets;
Expand Down
14 changes: 7 additions & 7 deletions src/ui/pages/applications/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::utils::NUM_CPUS;
use crate::utils::app::AppsContext;
use crate::utils::process::ProcessAction;
use crate::utils::settings::SETTINGS;
use crate::utils::units::{convert_speed, convert_storage};
use crate::utils::units::{convert_fraction, convert_speed, convert_storage};

use self::application_entry::ApplicationEntry;
use self::application_name_cell::ResApplicationNameCell;
Expand Down Expand Up @@ -897,12 +897,12 @@ impl ResApplications {
item.property_expression("item")
.chain_property::<ApplicationEntry>("cpu_usage")
.chain_closure::<String>(closure!(|_: Option<Object>, cpu_usage: f32| {
let mut percentage = cpu_usage * 100.0;
let mut fraction = cpu_usage;
if !SETTINGS.normalize_cpu_usage() {
percentage *= *NUM_CPUS as f32;
fraction *= *NUM_CPUS as f32;
}

format!("{percentage:.1} %")
convert_fraction(fraction as f64, false)
}))
.bind(&row, "text", Widget::NONE);

Expand Down Expand Up @@ -1256,7 +1256,7 @@ impl ResApplications {
item.property_expression("item")
.chain_property::<ApplicationEntry>("gpu_usage")
.chain_closure::<String>(closure!(|_: Option<Object>, gpu_usage: f32| {
format!("{:.1} %", gpu_usage * 100.0)
convert_fraction(gpu_usage as f64, false)
}))
.bind(&row, "text", Widget::NONE);

Expand Down Expand Up @@ -1325,7 +1325,7 @@ impl ResApplications {
item.property_expression("item")
.chain_property::<ApplicationEntry>("enc_usage")
.chain_closure::<String>(closure!(|_: Option<Object>, enc_usage: f32| {
format!("{:.1} %", enc_usage * 100.0)
convert_fraction(enc_usage as f64, false)
}))
.bind(&row, "text", Widget::NONE);

Expand Down Expand Up @@ -1394,7 +1394,7 @@ impl ResApplications {
item.property_expression("item")
.chain_property::<ApplicationEntry>("dec_usage")
.chain_closure::<String>(closure!(|_: Option<Object>, dec_usage: f32| {
format!("{:.1} %", dec_usage * 100.0)
convert_fraction(dec_usage as f64, false)
}))
.bind(&row, "text", Widget::NONE);

Expand Down
39 changes: 12 additions & 27 deletions src/ui/pages/battery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ use std::fmt::Write;

use crate::config::PROFILE;
use crate::i18n::i18n;
use crate::ui::set_subtitle_converted_maybe;
use crate::utils::battery::BatteryData;
use crate::utils::units::{convert_energy, convert_power};
use crate::utils::units::{convert_energy, convert_fraction, convert_power};

pub const TAB_ID_PREFIX: &str = "battery";

Expand Down Expand Up @@ -251,7 +252,7 @@ impl ResBattery {
let mut usage_string = String::new();

if let Ok(charge) = battery_data.charge {
let mut percentage_string = format!("{} %", (charge * 100.0).round());
let mut percentage_string = convert_fraction(charge, true);
usage_string.push_str(&percentage_string);

if let Ok(state) = battery_data.state {
Expand All @@ -268,38 +269,22 @@ impl ResBattery {
self.set_property("usage", battery_data.charge.unwrap_or_default());

if let Ok(power_usage) = battery_data.power_usage {
imp.power_usage.graph().push_data_point(power_usage);

let formatted_power = convert_power(power_usage);
let formatted_highest_power =
convert_power(imp.power_usage.graph().get_highest_value());

imp.power_usage.graph().set_visible(true);
imp.power_usage.set_subtitle(&format!(
"{formatted_power} · {} {formatted_highest_power}",
i18n("Highest:")
));

if !usage_string.is_empty() {
usage_string.push_str(" · ");
}

usage_string.push_str(&formatted_power);
} else {
imp.power_usage.graph().set_visible(false);
imp.power_usage.set_subtitle(&i18n("N/A"));
if usage_string.is_empty() {
usage_string.push_str(&i18n("N/A"));
}
usage_string.push_str(&convert_power(power_usage));
}

imp.power_usage
.add_power_point(battery_data.power_usage.ok(), None);

self.set_tab_usage_string(usage_string);

if let Ok(health) = battery_data.health {
imp.health
.set_subtitle(&format!("{} %", (health * 100.0).round()));
} else {
imp.health.set_subtitle(&i18n("N/A"));
}
set_subtitle_converted_maybe(
battery_data.health.ok(),
|fraction| convert_fraction(fraction, true),
&imp.health,
);
}
}
Loading
Loading