From 5693c1faa2185e8be2b5c6d1acb2bc984229af2e Mon Sep 17 00:00:00 2001 From: Vishal Rao Date: Tue, 15 Sep 2026 20:18:40 +0530 Subject: [PATCH 1/4] Add util format function for memory size Set the IEC_UNITS flag separately for the value but refrain using it for the unit string. Memory sizes unit strings are always shown without the lowercase letter I eg. "MB" or "GB" instead of "MiB" or "GiB". Rationale for this commit is to not have your average user wonder what that lowercase letter I depicts. --- src/Utils.vala | 9 +++++++++ .../ProcessTreeView/ProcessTreeView.vala | 2 +- src/Views/SystemView/SystemMemoryView.vala | 16 ++++++++-------- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/Utils.vala b/src/Utils.vala index 379fa66e6..16a3878f3 100644 --- a/src/Utils.vala +++ b/src/Utils.vala @@ -59,6 +59,15 @@ public class Monitor.Utils.Strings { format_size (speed * Utils.BITS_IN_BYTES, BITS | ONLY_UNIT) ); } + + public static string format_memory_size (uint64 size_in_bytes) { + ///TRANSLATORS: The first param is the numeric value (as string) of memory size. + ///The second param is the memory size such as "MB" or "GB" for megabytes or gigabytes. + return _("%s %s").printf ( + format_size (size_in_bytes, IEC_UNITS | ONLY_VALUE), + format_size (size_in_bytes, ONLY_UNIT) + ); + } } public class Monitor.Utils.Colors : Object { diff --git a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala index dc790d1d8..71e7eb0ab 100644 --- a/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala +++ b/src/Views/ProcessView/ProcessTreeView/ProcessTreeView.vala @@ -130,7 +130,7 @@ public class Monitor.ProcessTreeView : Granite.Bin { var label = (Gtk.Label) cell.child; var item = (ProcessRowData) cell.item; var binding_memory = item.bind_property ("memory", label, "label", SYNC_CREATE, (_, from_val, ref to_val) => { - to_val.set_string (format_size (from_val.get_uint64 () * 1024, IEC_UNITS)); + to_val.set_string (Utils.Strings.format_memory_size (from_val.get_uint64 () * 1024)); return true; }); item.bindings.set ("memory", binding_memory); diff --git a/src/Views/SystemView/SystemMemoryView.vala b/src/Views/SystemView/SystemMemoryView.vala index d2ba9a1a1..bc45ac631 100644 --- a/src/Views/SystemView/SystemMemoryView.vala +++ b/src/Views/SystemView/SystemMemoryView.vala @@ -71,16 +71,16 @@ public class Monitor.SystemMemoryView : Monitor.WidgetResource { // memory_chart.update (3, memory.shared_percentage + memory.buffer_percentage + memory.cached_percentage); // memory_chart.update (3, memory.shared_percentage + memory.buffer_percentage + memory.cached_percentage + memory.locked_percentage); - memory_total_label.text = format_size ((uint64) memory.total, IEC_UNITS); - memory_used_label.text = format_size ((uint64) memory.used, IEC_UNITS); - memory_buffered_label.text = format_size ((uint64) memory.buffer, IEC_UNITS); - memory_cached_label.text = format_size ((uint64) memory.cached, IEC_UNITS); - memory_locked_label.text = format_size ((uint64) memory.locked, IEC_UNITS); + memory_total_label.text = Utils.Strings.format_memory_size ((uint64) memory.total); + memory_used_label.text = Utils.Strings.format_memory_size ((uint64) memory.used); + memory_buffered_label.text = Utils.Strings.format_memory_size ((uint64) memory.buffer); + memory_cached_label.text = Utils.Strings.format_memory_size ((uint64) memory.cached); + memory_locked_label.text = Utils.Strings.format_memory_size ((uint64) memory.locked); - memory_shared_label.text = format_size ((uint64) memory.shared, IEC_UNITS); + memory_shared_label.text = Utils.Strings.format_memory_size ((uint64) memory.shared); - swap_total_label.text = format_size ((uint64) swap.total, IEC_UNITS); - swap_used_label.text = format_size ((uint64) swap.used, IEC_UNITS); + swap_total_label.text = Utils.Strings.format_memory_size ((uint64) swap.total); + swap_used_label.text = Utils.Strings.format_memory_size ((uint64) swap.used); } } From 76ea8982f337ad11b121053fe9fe6cca3631f0f4 Mon Sep 17 00:00:00 2001 From: Vishal Rao Date: Tue, 15 Sep 2026 21:26:08 +0530 Subject: [PATCH 2/4] Get physical memory size using udev Also update util memory size format function to: - show the full format with single decimal place eg. "3.1 MB" unless, - the size is an exact factor/power of 2 then show eg. "32 GB". This is to show accurate total physical memory available eg. "32 GB" instead of previously showing "31.2 GiB" which libgtop would report. --- .github/workflows/ci.yml | 2 +- .github/workflows/test.yml | 2 +- README.md | 2 +- meson.build | 1 + src/Resources/Memory.vala | 18 +++++++++++++++++- src/Utils.vala | 15 +++++++++++++++ 6 files changed, 36 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2ab4c6756..7b34381d2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: run: | apt update apt install -y libgala-dev libgee-0.8-dev libglib2.0-dev libgranite-7-dev libgtk-4-dev libadwaita-1-dev \ - libdbus-glib-1-dev libgtop2-dev libwingpanel-9-dev libudisks2-dev \ + libdbus-glib-1-dev libgtop2-dev libgudev-1.0-dev libwingpanel-9-dev libudisks2-dev \ libxnvctrl0 libxnvctrl-dev libcurl4-gnutls-dev libflatpak-dev libjson-glib-dev \ liblivechart-2-dev libpci-dev \ meson valac sassc git diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2323f76c3..24d717480 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -24,7 +24,7 @@ jobs: run: | apt update apt install -y libgala-dev libgee-0.8-dev libglib2.0-dev libgranite-7-dev libgtk-4-dev libadwaita-1-dev \ - libdbus-glib-1-dev libgtop2-dev libwingpanel-9-dev libudisks2-dev \ + libdbus-glib-1-dev libgtop2-dev libgudev-1.0-dev libwingpanel-9-dev libudisks2-dev \ libxnvctrl0 libxnvctrl-dev libcurl4-gnutls-dev libflatpak-dev libjson-glib-dev \ liblivechart-2-dev libpci-dev \ meson valac sassc git \ diff --git a/README.md b/README.md index 035654cb9..0080f034e 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ sudo apt install sassc valac libgtk-4-dev libgee-0.8-dev libgranite-7-dev libgto Alternatively, if you plan to install WITHOUT a wingpanel-indicator ```bash -sudo apt install sassc valac libgtk-4-dev libgee-0.8-dev libgranite-7-dev libgtop2-dev libadwaita-1-dev libudisks2-dev libjson-glib-dev libflatpak-dev libxnvctrl-dev liblivechart-2-dev libpci-dev meson +sudo apt install sassc valac libgtk-4-dev libgee-0.8-dev libgranite-7-dev libgtop2-dev libgudev-1.0-dev libadwaita-1-dev libudisks2-dev libjson-glib-dev libflatpak-dev libxnvctrl-dev liblivechart-2-dev libpci-dev meson ``` diff --git a/meson.build b/meson.build index 9e29ed18f..34b0d0445 100644 --- a/meson.build +++ b/meson.build @@ -34,6 +34,7 @@ app_dependencies = [ dependency('gio-2.0'), dependency('gobject-2.0'), dependency('libgtop-2.0'), + dependency('gudev-1.0'), dependency('libadwaita-1', version: '>=1.0.0'), dependency('gtk4-x11'), dependency('udisks2'), diff --git a/src/Resources/Memory.vala b/src/Resources/Memory.vala index bbe4ecb95..ad6906762 100644 --- a/src/Resources/Memory.vala +++ b/src/Resources/Memory.vala @@ -46,7 +46,8 @@ namespace Monitor { public void update () { GTop.get_mem (out mem); - total = (double) (mem.total); + var total_physical_memory = get_total_physical_memory (); + total = (double) (total_physical_memory > 0 ? total_physical_memory : mem.total); used = (double) mem.user; shared = (double) (mem.shared); buffer = (double) (mem.buffer); @@ -54,5 +55,20 @@ namespace Monitor { locked = (double) (mem.locked); } + private uint64 get_total_physical_memory () { + uint64 mem_total = 0; + + GUdev.Client client = new GUdev.Client ({"dmi"}); + GUdev.Device? device = client.query_by_sysfs_path ("/sys/devices/virtual/dmi/id"); + + if (device != null) { + uint64 devices = device.get_property_as_uint64 ("MEMORY_ARRAY_NUM_DEVICES"); + for (int item = 0; item < devices; item++) { + mem_total += device.get_property_as_uint64 ("MEMORY_DEVICE_%d_SIZE".printf (item)); + } + } + + return mem_total; + } } } diff --git a/src/Utils.vala b/src/Utils.vala index 16a3878f3..c8deb862c 100644 --- a/src/Utils.vala +++ b/src/Utils.vala @@ -5,6 +5,7 @@ namespace Monitor.Utils { const int BITS_IN_BYTES = 8; + const int IEC_UNIT_BASE = 1024; const string NOT_AVAILABLE = (_("N/A")); const string NO_DATA = "\u2014"; @@ -61,6 +62,20 @@ public class Monitor.Utils.Strings { } public static string format_memory_size (uint64 size_in_bytes) { + uint64 unit = 1; + while (size_in_bytes >= unit * IEC_UNIT_BASE) { + unit *= IEC_UNIT_BASE; + } + + if (size_in_bytes % unit == 0) { + ///TRANSLATORS: The first param is the numeric value of memory size. + ///The second param is the memory size such as "MB" or "GB" for megabytes or gigabytes. + return _("%llu %s").printf ( + size_in_bytes / unit, + format_size (size_in_bytes, ONLY_UNIT) + ); + } + ///TRANSLATORS: The first param is the numeric value (as string) of memory size. ///The second param is the memory size such as "MB" or "GB" for megabytes or gigabytes. return _("%s %s").printf ( From 99ba1e2b58bb85f16027177dd92dedd536f9836f Mon Sep 17 00:00:00 2001 From: Vishal Rao Date: Wed, 16 Sep 2026 18:47:32 +0530 Subject: [PATCH 3/4] Update README.md to add missed content --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0080f034e..12abfa30a 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ If you plan to install WITH a wingpanel-indicator ```bash -sudo apt install sassc valac libgtk-4-dev libgee-0.8-dev libgranite-7-dev libgtop2-dev libadwaita-1-dev libudisks2-dev libjson-glib-dev libflatpak-dev libxnvctrl-dev liblivechart-2-dev libpci-dev libwingpanel-9-dev meson +sudo apt install sassc valac libgtk-4-dev libgee-0.8-dev libgranite-7-dev libgtop2-dev libgudev-1.0-dev libadwaita-1-dev libudisks2-dev libjson-glib-dev libflatpak-dev libxnvctrl-dev liblivechart-2-dev libpci-dev libwingpanel-9-dev meson ``` Alternatively, if you plan to install WITHOUT a wingpanel-indicator From 81392c925ae6f12787f226d87283f902a62eeb22 Mon Sep 17 00:00:00 2001 From: Vishal Rao Date: Thu, 17 Sep 2026 00:05:12 +0530 Subject: [PATCH 4/4] Fix format_memory_size util function unit calculation --- src/Utils.vala | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Utils.vala b/src/Utils.vala index 84080723f..c3e012430 100644 --- a/src/Utils.vala +++ b/src/Utils.vala @@ -7,6 +7,7 @@ namespace Monitor.Utils { const int BITS_IN_BYTES = 8; const int MHZ_IN_GHZ = 1000; const int IEC_UNIT_BASE = 1024; + const int NON_IEC_UNIT_BASE = 1000; const string NOT_AVAILABLE = (_("N/A")); const string NO_DATA = "\u2014"; @@ -82,12 +83,14 @@ public class Monitor.Utils.Strings { unit *= IEC_UNIT_BASE; } + var size_adjusted_for_non_iec_units = size_in_bytes * NON_IEC_UNIT_BASE / IEC_UNIT_BASE; + if (size_in_bytes % unit == 0) { ///TRANSLATORS: The first param is the numeric value of memory size. ///The second param is the memory size such as "MB" or "GB" for megabytes or gigabytes. return _("%llu %s").printf ( size_in_bytes / unit, - format_size (size_in_bytes, ONLY_UNIT) + format_size (size_adjusted_for_non_iec_units, ONLY_UNIT) ); } @@ -95,7 +98,7 @@ public class Monitor.Utils.Strings { ///The second param is the memory size such as "MB" or "GB" for megabytes or gigabytes. return _("%s %s").printf ( format_size (size_in_bytes, IEC_UNITS | ONLY_VALUE), - format_size (size_in_bytes, ONLY_UNIT) + format_size (size_adjusted_for_non_iec_units, ONLY_UNIT) ); } }