Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
4bcb37f
Add pci dep
stsdc Apr 14, 2025
c3d652a
Add libpci dep
stsdc Apr 14, 2025
0e473c7
libpci-dev
stsdc Apr 14, 2025
0cded21
missed space
stsdc Apr 14, 2025
4e76d37
Try to use LIB_VERSION
stsdc Apr 14, 2025
de6631f
Add Access and Dev structs
stsdc Apr 14, 2025
2ae3a75
wip
stsdc Apr 15, 2025
d28b3b7
Use struct in cname
stsdc Apr 15, 2025
3ad5375
Merge branch 'main' into stsdc/libpci
stsdc Apr 15, 2025
14ba09b
Add pci_scan_bus
stsdc Apr 16, 2025
db42263
Merge branch 'main' into stsdc/libpci
stsdc Apr 16, 2025
0225d12
Update structs according to ver. 3.10.0
stsdc Apr 18, 2025
709aa5f
Make pci_init a standalone function
stsdc Apr 18, 2025
79b6341
list all pci addresses
stsdc Apr 18, 2025
f04f8b2
Introduce pci_lookup_name
stsdc Apr 22, 2025
e9a2c54
remove ref
stsdc Apr 22, 2025
b9175ce
Merge branch 'main' into stsdc/libpci
stsdc Apr 24, 2025
1d5b3e2
convert Access to class
stsdc Apr 25, 2025
803e0cc
Reintroduce pci_cleanup as destroy_function for Access class
stsdc Apr 26, 2025
866a188
standalone functions are now methods of Access class
stsdc Apr 26, 2025
f40af61
Introduce class Dev; use free_function
stsdc Apr 26, 2025
3c84ebf
Return unowned nullable string in lookup_name
stsdc Apr 26, 2025
7b208dc
Introduce fill_info
stsdc Apr 26, 2025
275330a
Add Version annotations
stsdc Apr 26, 2025
377dc0a
Add subsys_vendor_id and subsys_id; add missing FILL consts
stsdc Apr 27, 2025
aee4527
Drop SessionManager and use libpci to get GPU name
stsdc Apr 30, 2025
0e653a5
fix lint
stsdc Apr 30, 2025
88c4809
Merge branch 'main' into stsdc/libpci
stsdc May 1, 2025
d520256
Reintroduce GPU monitoring; introduce multiple GPU support foundament
stsdc May 1, 2025
a144858
Fix for Intel graphics
stsdc May 2, 2025
3d731c6
A bit better debug messages
stsdc May 2, 2025
a53d166
Consider 3D cotroller as a GPU
stsdc May 2, 2025
b3d94a6
Update Resources.vala
stsdc May 2, 2025
5b63050
Add Intel GPU dummy class
stsdc May 6, 2025
e525adc
Add proper vendor name to the GPU name
stsdc May 6, 2025
2619151
Display not supported label for Intel and Nvidia gpus
stsdc May 6, 2025
b037a45
lint
stsdc May 6, 2025
b556be3
Improve comment styling for hints and docs
stsdc May 6, 2025
1a11d19
Add comment
stsdc May 6, 2025
6d3e51b
Merge branch 'main' into stsdc/libpci
stsdc May 7, 2025
889b100
Remove obsolete code
stsdc May 8, 2025
7b78697
Update src/Views/SystemView/SystemView.vala
stsdc May 8, 2025
f50b8ef
Refactoring: atomize comments; put literals into consts
stsdc May 8, 2025
0718cc9
Remove space at the start of the file
stsdc May 8, 2025
fd47986
Make it clear that Intel GPU needs implementation.
stsdc May 8, 2025
585ba6c
Add libpci-dev to readme
stsdc May 8, 2025
e03f0b5
Use pci consts from Utils
stsdc May 8, 2025
fa2c3c2
Use switch-case for GPU detection
stsdc May 9, 2025
62fbc45
Use for loop for detecting GPU
stsdc May 9, 2025
4478ad7
make sysfs path in nvidia protected
stsdc May 9, 2025
b933672
Explicit setting properties without digging into the method in the in…
ryonakano May 10, 2025
acff8e4
Compare GPU types instead of string properties
stsdc May 10, 2025
fc97d56
Merge branch 'stsdc/libpci' into ryonakano/libpci-proposal
stsdc May 10, 2025
3804207
Update names of IGPU methods
stsdc May 10, 2025
7175da7
Display pretty version of libpci
stsdc May 11, 2025
5bc7216
Use LIBPCI_* consts to display pretty version
stsdc May 12, 2025
e6e746f
Move PCI defines to independant source
ryonakano May 13, 2025
c18f0c0
Add Flags attribute to enum LookupMode
stsdc May 14, 2025
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
apt install -y libgala-dev libgee-0.8-dev libglib2.0-dev libgranite-dev libgtk-3-dev libhandy-1-dev \
libdbus-glib-1-dev libwnck-3-dev libgtop2-dev libwingpanel-3.0-dev libudisks2-dev \
libxnvctrl0 libxnvctrl-dev libcurl4-gnutls-dev libflatpak-dev libjson-glib-dev \
liblivechart-1-dev \
liblivechart-1-dev libpci-dev \
meson valac sassc git
- name: Build
run: |
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ Monitor will be available from the Applications menu.
If you plan to install WITH a wingpanel-indicator

```bash
sudo apt install build-essential cmake sassc valac libgtk-3-dev libgee-0.8-dev libgranite-dev libgtop2-dev libwnck-3-dev libhandy-1-dev libudisks2-dev libjson-glib-dev libflatpak-dev libxnvctrl-dev liblivechart-1-dev libwingpanel-dev
sudo apt install build-essential cmake sassc valac libgtk-3-dev libgee-0.8-dev libgranite-dev libgtop2-dev libwnck-3-dev libhandy-1-dev libudisks2-dev libjson-glib-dev libflatpak-dev libxnvctrl-dev liblivechart-1-dev libpci-dev libwingpanel-dev
```

Alternatively, if you plan to install WITHOUT a wingpanel-indicator

```bash
sudo apt install build-essential cmake sassc valac libgtk-3-dev libgee-0.8-dev libgranite-dev libgtop2-dev libwnck-3-dev libhandy-1-dev libudisks2-dev libjson-glib-dev libflatpak-dev libxnvctrl-dev liblivechart-1-dev
sudo apt install build-essential cmake sassc valac libgtk-3-dev libgee-0.8-dev libgranite-dev libgtop2-dev libwnck-3-dev libhandy-1-dev libudisks2-dev libjson-glib-dev libflatpak-dev libxnvctrl-dev liblivechart-1-dev libpci-dev
```


Expand Down
33 changes: 20 additions & 13 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ libdir = join_paths(prefix, get_option('libdir'))
icondir = join_paths(datadir, 'icons', 'hicolor')
vapidir = meson.current_source_dir() / 'vapi/'

add_global_arguments('-DGETTEXT_PACKAGE="@0@"'.format(meson.project_name()), language:'c')
add_global_arguments('-DGETTEXT_PACKAGE="@0@"'.format(meson.project_name()), language: 'c')

add_project_arguments(['--vapidir', vapidir], language: 'vala')
add_project_arguments(['-DWNCK_I_KNOW_THIS_IS_UNSTABLE', '-w'], language: 'c')
Expand All @@ -38,35 +38,42 @@ app_dependencies = [
dependency('flatpak'),

# FIXME Bump required version to >= 1.10.0 when GTK 4 porting
dependency('livechart', version: '< 1.10.0', fallback: ['live-chart', 'livechart_dep']),
dependency(
'livechart',
version: '< 1.10.0',
fallback: ['live-chart', 'livechart_dep'],
),

meson.get_compiler('c').find_library('m', required : false),
meson.get_compiler('c').find_library('m', required: false),
meson.get_compiler('vala').find_library('posix'),
meson.get_compiler('c').find_library('XNVCtrl'),
meson.get_compiler('c').find_library('X11'),

# PCI needs lower version limit '>= 3.8.0'
meson.get_compiler('c').find_library('pci'),
meson.get_compiler('vala').find_library('pci', dirs: vapidir),

meson.get_compiler('c').find_library('XNVCtrl'),
meson.get_compiler('vala').find_library('libxnvctrl', dirs: vapidir),
]


config_data = configuration_data()
config_data.set('GETTEXT_PACKAGE', meson.project_name())

subdir('data')

config_data.set('VCS_TAG', '@VCS_TAG@')
project_config = vcs_tag(
input: configure_file(
input: 'src/Conf.vala.in',
output: 'Conf.vala.in',
configuration: config_data
),
output: 'Conf.vala',
command: ['git', 'describe', '--tags', '--dirty']
input: configure_file(
input: 'src/Conf.vala.in',
output: 'Conf.vala.in',
configuration: config_data,
),
output: 'Conf.vala',
command: ['git', 'describe', '--tags', '--dirty'],
)

subdir('src')


# Add in a post install script
meson.add_install_script('meson/post_install.py')

Expand Down
39 changes: 23 additions & 16 deletions src/Monitor.vala
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace Monitor {
Object (
application_id: "io.elementary.monitor",
flags : ApplicationFlags.FLAGS_NONE
);
);
status_background = status_indicator;
}

Expand Down Expand Up @@ -70,21 +70,21 @@ namespace Monitor {
if (!MonitorApp.settings.get_boolean ("indicator-state")) {
MonitorApp.settings.set_boolean ("indicator-state", true);
}
// if (!MonitorApp.settings.get_boolean ("indicator-cpu-state")) {
// MonitorApp.settings.set_boolean ("indicator-cpu-state", true);
// }
// if (!MonitorApp.settings.get_boolean ("indicator-memory-state")) {
// MonitorApp.settings.set_boolean ("indicator-memory-state", true);
// }
// if (!MonitorApp.settings.get_boolean ("indicator-temperature-state")) {
// MonitorApp.settings.set_boolean ("indicator-temperature-state", true);
// }
// if (!MonitorApp.settings.get_boolean ("indicator-network-upload-state")) {
// MonitorApp.settings.set_boolean ("indicator-network-upload-state", false);
// }
// if (!MonitorApp.settings.get_boolean ("indicator-network-download-state")) {
// MonitorApp.settings.set_boolean ("indicator-network-download-state", false);
// }
// if (!MonitorApp.settings.get_boolean ("indicator-cpu-state")) {
// MonitorApp.settings.set_boolean ("indicator-cpu-state", true);
// }
// if (!MonitorApp.settings.get_boolean ("indicator-memory-state")) {
// MonitorApp.settings.set_boolean ("indicator-memory-state", true);
// }
// if (!MonitorApp.settings.get_boolean ("indicator-temperature-state")) {
// MonitorApp.settings.set_boolean ("indicator-temperature-state", true);
// }
// if (!MonitorApp.settings.get_boolean ("indicator-network-upload-state")) {
// MonitorApp.settings.set_boolean ("indicator-network-upload-state", false);
// }
// if (!MonitorApp.settings.get_boolean ("indicator-network-download-state")) {
// MonitorApp.settings.set_boolean ("indicator-network-download-state", false);
// }

window.hide ();
MonitorApp.settings.set_boolean ("background-state", true);
Expand All @@ -101,6 +101,13 @@ namespace Monitor {
print (" Monitor %s \n", VCS_TAG);
print ("\n");

print (
"LibPCI ver: %d.%d.%d \n",
PCIUtils.LIBPCI_MAJOR_VER,
PCIUtils.LIBPCI_MINOR_VER,
PCIUtils.LIBPCI_PATCH_VER
);

// add command line options
try {
var opt_context = new OptionContext ("");
Expand Down
10 changes: 10 additions & 0 deletions src/PCIUtils.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* SPDX-License-Identifier: GPL-3.0-or-later
* SPDX-FileCopyrightText: 2025 elementary, Inc. (https://elementary.io)
*/

namespace Monitor.PCIUtils {
const int LIBPCI_MAJOR_VER = (Pci.LIB_VERSION & 0xFF0000) >> 16;
const int LIBPCI_MINOR_VER = (Pci.LIB_VERSION & 0x00FF00) >> 8;
const int LIBPCI_PATCH_VER = (Pci.LIB_VERSION & 0x0000FF) >> 0;
}
43 changes: 12 additions & 31 deletions src/Resources/GPU/GPUAmd.vala
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
*/

public class Monitor.GPUAmd : IGPU, Object {
public SessionManager ? session_manager { get; protected set; }

public Gee.HashMap<string, HwmonTemperature> hwmon_temperatures { get; set; }

public string hwmon_module_name { get; set; }

public string name { get; set; }

public int percentage { get; protected set; }

public int memory_percentage { get; protected set; }
Expand All @@ -20,53 +21,33 @@ public class Monitor.GPUAmd : IGPU, Object {

public double temperature { get; protected set; }

private string path { get; set; }

construct {
// session_manager = get_sessman ();
// When path for GPU is created it can be assigned to card0 or card1
// this a bit random. This should be removed when multiple GPU
// support will be added.
try {
var dir = Dir.open ("/sys/class/drm/");
string ? name;
while ((name = dir.read_name ()) != null) {
if (name == "card0") {
path = "/sys/class/drm/card0/";
debug ("GPU path: %s", path);

} else if (name == "card1") {
path = "/sys/class/drm/card1/";
debug ("GPU path: %s", path);

}
}
if (path == null) {
debug ("Can't detect right path for AMD GPU");
}
} catch (Error e) {
print ("Error: %s\n", e.message);
}
protected string sysfs_path { get; set; }

public GPUAmd (Pci.Access pci_access, Pci.Dev pci_device) {
name = pci_parse_name (pci_access, pci_device);
name = "AMD® " + name;

sysfs_path = pci_parse_sysfs_path (pci_access, pci_device);
}

private void update_temperature () {
temperature = double.parse (hwmon_temperatures.get ("edge").input) / 1000;
}

private void update_memory_vram_used () {
memory_vram_used = double.parse (get_sysfs_value (path + "device/mem_info_vram_used"));
memory_vram_used = double.parse (get_sysfs_value (sysfs_path + "/mem_info_vram_used"));
}

private void update_memory_vram_total () {
memory_vram_total = double.parse (get_sysfs_value (path + "device/mem_info_vram_total"));
memory_vram_total = double.parse (get_sysfs_value (sysfs_path + "/mem_info_vram_total"));
}

private void update_memory_percentage () {
memory_percentage = (int) (Math.round ((memory_vram_used / memory_vram_total) * 100));
}

private void update_percentage () {
percentage = int.parse (get_sysfs_value (path + "device/gpu_busy_percent"));
percentage = int.parse (get_sysfs_value (sysfs_path + "/gpu_busy_percent"));
}

public void update () {
Expand Down
66 changes: 66 additions & 0 deletions src/Resources/GPU/GPUIntel.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* SPDX-License-Identifier: GPL-3.0-or-later
* SPDX-FileCopyrightText: 2025 elementary, Inc. (https://elementary.io)
*/

public class Monitor.GPUIntel : IGPU, Object {

public Gee.HashMap<string, HwmonTemperature> hwmon_temperatures { get; set; }

public string hwmon_module_name { get; set; }

public string name { get; set; }

public int percentage { get; protected set; }

public int memory_percentage { get; protected set; }

public double memory_vram_used { get; protected set; }

public double memory_vram_total { get; set; }

public double temperature { get; protected set; }

protected string sysfs_path { get; set; }

public GPUIntel (Pci.Access pci_access, Pci.Dev pci_device) {
name = pci_parse_name (pci_access, pci_device);
name = "Intel® " + name;

sysfs_path = pci_parse_sysfs_path (pci_access, pci_device);
}

private void update_temperature () {
// @TODO: Intel GPU temperature retrieval needs implementation.
temperature = 0;
}

private void update_memory_vram_used () {
// @TODO: Intel GPU used VRAM retrieval needs implementation.
memory_vram_used = 0;
}

private void update_memory_vram_total () {
// @TODO: Intel GPU total VRAM retrieval needs implementation.
memory_vram_total = 0;
}

private void update_memory_percentage () {
// @TODO: Intel GPU memory percentage needs implementation.
memory_percentage = 0;
}

private void update_percentage () {
// @TODO: Intel GPU usage percentage needs implementation.
percentage = 0;
}

public void update () {
update_temperature ();
update_memory_vram_used ();
update_memory_vram_total ();
update_memory_percentage ();
update_percentage ();
}

}
13 changes: 11 additions & 2 deletions src/Resources/GPU/GPUNvidia.vala
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
*/

public class Monitor.GPUNvidia : IGPU, Object {
public SessionManager ? session_manager { get; protected set; }

public Gee.HashMap<string, HwmonTemperature> hwmon_temperatures { get; set; }

public string hwmon_module_name { get; set; }

public string name { get; set; }

public int percentage { get; protected set; }

public int memory_percentage { get; protected set; }
Expand All @@ -22,6 +23,8 @@ public class Monitor.GPUNvidia : IGPU, Object {

public double temperature { get; protected set; }

protected string sysfs_path { get; set; }

public int nvidia_temperature = 0;

public int nvidia_memory_vram_used = 0;
Expand All @@ -46,8 +49,14 @@ public class Monitor.GPUNvidia : IGPU, Object {

public X.Display nvidia_display;

public GPUNvidia (Pci.Access pci_access, Pci.Dev pci_device) {
name = pci_parse_name (pci_access, pci_device);
name = "nVidia® " + name;

sysfs_path = pci_parse_sysfs_path (pci_access, pci_device);
}

construct {
// session_manager = get_sessman ();
nvidia_display = new X.Display ();
}

Expand Down
22 changes: 16 additions & 6 deletions src/Resources/GPU/IGPU.vala
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,12 @@
*/

public interface Monitor.IGPU : Object {
public abstract SessionManager ? session_manager { get; public set; }

public abstract Gee.HashMap<string, HwmonTemperature> hwmon_temperatures { get; set; }

public abstract string hwmon_module_name { get; protected set; }

public string name {
owned get {
return session_manager.renderer.split ("(", 2)[0];
}
}
public abstract string name { get; protected set; }

public abstract int percentage { get; protected set; }

Expand All @@ -26,6 +21,8 @@ public interface Monitor.IGPU : Object {

public abstract double temperature { get; protected set; }

protected abstract string sysfs_path { get; protected set; }

public abstract void update_temperature ();

public abstract void update_memory_vram_used ();
Expand All @@ -38,6 +35,19 @@ public interface Monitor.IGPU : Object {

public abstract void update ();

protected virtual string pci_parse_name (Pci.Access pci_access, Pci.Dev pci_device) {
char namebuf[256];
return pci_access.lookup_name (namebuf, Pci.LookupMode.DEVICE, pci_device.vendor_id, pci_device.device_id);
}

protected virtual string pci_parse_sysfs_path (Pci.Access pci_access, Pci.Dev pci_device) {
string pci_path_domain_bus = "%04x:%02x".printf (pci_device.domain_16, pci_device.bus);
string pci_path_dev_func = "%02x.%d".printf (pci_device.dev, pci_device.func);
string path = "/sys/class/pci_bus/%s/device/%s:%s".printf (pci_path_domain_bus, pci_path_domain_bus, pci_path_dev_func);
debug ("GPU path: %s", path);

return path;
}

public virtual string get_sysfs_value (string path) {
string content;
Expand Down
Loading