From 8320b540740117502424dceed76496949f75f243 Mon Sep 17 00:00:00 2001 From: Fred <27208977+FreddyFunk@users.noreply.github.com> Date: Fri, 14 Nov 2025 00:34:42 +0100 Subject: [PATCH] fix wired speed detection and layout (#1156) * fix wired speed detection and layout * show 2.5 Gbps and 2.5 Tbps interface with decimal values --- .../i18n/en/cosmic_applet_network.ftl | 2 ++ cosmic-applet-network/src/app.rs | 34 +++++++++++++++---- .../src/network_manager/current_networks.rs | 23 ++++++++++++- 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/cosmic-applet-network/i18n/en/cosmic_applet_network.ftl b/cosmic-applet-network/i18n/en/cosmic_applet_network.ftl index 3b05600f..639c8384 100644 --- a/cosmic-applet-network/i18n/en/cosmic_applet_network.ftl +++ b/cosmic-applet-network/i18n/en/cosmic_applet_network.ftl @@ -8,6 +8,8 @@ ipv4 = IPv4 address ipv6 = IPv6 address mac = MAC megabits-per-second = Mbps +gigabits-per-second = Gbps +terabits-per-second = Tbps connected = Connected connecting = Connecting connect = Connect diff --git a/cosmic-applet-network/src/app.rs b/cosmic-applet-network/src/app.rs index 891e0a21..b28b6ffd 100644 --- a/cosmic-applet-network/src/app.rs +++ b/cosmic-applet-network/src/app.rs @@ -754,6 +754,30 @@ impl cosmic::Application for CosmicNetworkApplet { ipv4.push(text(format!("{}: {}", fl!("ipv4"), addr)).size(12).into()); } + let mut right_column = vec![text::body(fl!("connected")).into()]; + + // Only show speed if it's greater than 0 + if *speed > 0 { + let speed_text = if *speed >= 1_000_000 { + let tbps = *speed as f64 / 1_000_000.0; + if tbps.fract() == 0.0 { + format!("{} {}", tbps as u32, fl!("terabits-per-second")) + } else { + format!("{:.1} {}", tbps, fl!("terabits-per-second")) + } + } else if *speed >= 1_000 { + let gbps = *speed as f64 / 1_000.0; + if gbps.fract() == 0.0 { + format!("{} {}", gbps as u32, fl!("gigabits-per-second")) + } else { + format!("{:.1} {}", gbps, fl!("gigabits-per-second")) + } + } else { + format!("{speed} {}", fl!("megabits-per-second")) + }; + right_column.push(text(speed_text).size(12).into()); + } + vpn_ethernet_col = vpn_ethernet_col.push(column![ row![ icon::icon( @@ -763,13 +787,9 @@ impl cosmic::Application for CosmicNetworkApplet { ) .size(40), Column::with_children(ipv4), - text::body(format!( - "{} - {speed} {}", - fl!("connected"), - fl!("megabits-per-second") - )) - .width(Length::Fill) - .align_x(Alignment::End), + Column::with_children(right_column) + .width(Length::Fill) + .align_x(Alignment::End), ] .align_y(Alignment::Center) .spacing(8) diff --git a/cosmic-applet-network/src/network_manager/current_networks.rs b/cosmic-applet-network/src/network_manager/current_networks.rs index aec61763..d063a54e 100644 --- a/cosmic-applet-network/src/network_manager/current_networks.rs +++ b/cosmic-applet-network/src/network_manager/current_networks.rs @@ -8,6 +8,16 @@ use std::net::Ipv4Addr; use super::hw_address::HwAddress; +/// Read network interface speed from sysfs +/// Returns speed in Mbps, or None if unable to read +fn read_speed_from_sysfs(interface: &str) -> Option { + let path = format!("/sys/class/net/{}/speed", interface); + std::fs::read_to_string(path) + .ok() + .and_then(|content| content.trim().parse::().ok()) + .and_then(|speed| if speed > 0 { Some(speed as u32) } else { None }) +} + pub async fn active_connections( active_connections: Vec>, ) -> zbus::Result> { @@ -33,6 +43,8 @@ pub async fn active_connections( continue; } for device in connection.devices().await.unwrap_or_default() { + let interface_name = device.interface().await.ok(); + match device .downcast_to_device() .await @@ -40,11 +52,20 @@ pub async fn active_connections( .and_then(|inner| inner) { Some(SpecificDevice::Wired(wired_device)) => { + let mut speed = wired_device.speed().await?; + + // If NetworkManager returns 0, try to read from sysfs + if speed == 0 { + if let Some(interface) = interface_name.as_ref() { + speed = read_speed_from_sysfs(interface).unwrap_or(0); + } + } + info.push(ActiveConnectionInfo::Wired { name: connection.id().await?, hw_address: HwAddress::from_str(&wired_device.hw_address().await?) .unwrap_or_default(), - speed: wired_device.speed().await?, + speed, ip_addresses: addresses.clone(), }); }