Skip to content
Open
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
68 changes: 67 additions & 1 deletion prefs.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,70 @@ const Settings = new GObject.Class({
this._bind_settings();
},

_setup_storage_list: function() {
let entryWidget = this.builder.get_object('storage-path');
let parentBox = entryWidget.get_parent();
parentBox.remove(entryWidget);

let listContainer = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL, spacing: 6 });
parentBox.append(listContainer);

let paths = this._settings.get_strv('storage-path');

let renderRows = () => {
let child = listContainer.get_first_child();
while (child) {
listContainer.remove(child);
child = listContainer.get_first_child();
}

let currentPaths = this._settings.get_strv('storage-path') || [];
currentPaths.forEach((path, index) => {
let row = new Gtk.Box({ spacing: 6 });
let entry = new Gtk.Entry({ text: path, hexpand: true });

entry.connect('activate', (w) => {
let p = this._settings.get_strv('storage-path');
p[index] = w.get_text();
this._settings.set_strv('storage-path', p);
});
let focusController = new Gtk.EventControllerFocus();
focusController.connect('leave', () => {
let p = this._settings.get_strv('storage-path');
let text = entry.get_text();
if (p[index] !== text) {
p[index] = text;
this._settings.set_strv('storage-path', p);
}
});
entry.add_controller(focusController);

let delBtn = new Gtk.Button({ icon_name: 'list-remove-symbolic' });
delBtn.connect('clicked', () => {
let p = this._settings.get_strv('storage-path') || [];
p.splice(index, 1);
this._settings.set_strv('storage-path', p);
renderRows();
});

row.append(entry);
row.append(delBtn);
listContainer.append(row);
});

let addBtn = new Gtk.Button({ label: _('Add Path'), icon_name: 'list-add-symbolic' });
addBtn.connect('clicked', () => {
let p = this._settings.get_strv('storage-path');
p.push('/');
this._settings.set_strv('storage-path', p);
renderRows();
});
listContainer.append(addBtn);
};

renderRows();
},

// Bind the gtk window to the schema settings
_bind_settings: function() {
let widget;
Expand Down Expand Up @@ -77,7 +141,9 @@ const Settings = new GObject.Class({
this._settings.bind('update-time', this.builder.get_object('update-time'), 'value', Gio.SettingsBindFlags.DEFAULT);

// process individual text entry sensor preferences
sensors = [ 'storage-path', 'monitor-cmd' ];
this._setup_storage_list();
sensors = [ 'monitor-cmd' ];

for (let key in sensors) {
let sensor = sensors[key];

Expand Down
Binary file modified schemas/gschemas.compiled
Binary file not shown.
4 changes: 2 additions & 2 deletions schemas/org.gnome.shell.extensions.vitals.gschema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@
<summary>Network speed format</summary>
<description>Should speed display in bits or bytes?</description>
</key>
<key type="s" name="storage-path">
<default>"/"</default>
<key type="as" name="storage-path">
<default>["/"]</default>
<summary>Storage path</summary>
<description>Storage path for monitoring</description>
</key>
Expand Down
96 changes: 58 additions & 38 deletions sensors.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ export const Sensors = GObject.registerClass({
this._storageDevice = '';
this._findStorageDevice();

this._lastRead = 0;
this._lastWrite = 0;
this._storageHistory = {};
}
}

Expand Down Expand Up @@ -349,48 +348,69 @@ export const Sensors = GObject.registerClass({
this._returnValue(callback, 'ARC Current', current, 'storage', 'storage');
}).catch(err => { });

// skip rest of stats if gtop not available
if (!hasGTop) return;

let paths = this._settings.get_strv('storage-path') || [];
if (paths.length === 0) return;

// check disk performance stats
new FileModule.File('/proc/diskstats').read("\n").then(lines => {
for (let line of lines) {
let loadArray = line.trim().split(/\s+/);
if ('/dev/' + loadArray[2] == this._storageDevice) {
var read = (loadArray[5] * 512);
var write = (loadArray[9] * 512);
this._returnValue(callback, 'Read total', read, 'storage', 'storage');
this._returnValue(callback, 'Write total', write, 'storage', 'storage');
this._returnValue(callback, 'Read rate', (read - this._lastRead) / dwell, 'storage', 'storage');
this._returnValue(callback, 'Write rate', (write - this._lastWrite) / dwell, 'storage', 'storage');
this._lastRead = read;
this._lastWrite = write;
break;
Promise.all([
new FileModule.File('/proc/mounts').read("\n"),
new FileModule.File('/proc/diskstats').read("\n")
]).then(([mounts, stats]) => {
let pathDeviceMap = {};
for (let line of mounts) {
let parts = line.trim().split(/\s+/);
if (parts.length >= 2) pathDeviceMap[parts[1]] = parts[0].replace('/dev/', '');
}

let deviceData = {};
for (let line of stats) {
let parts = line.trim().split(/\s+/);
if (parts.length > 10) {
deviceData[parts[2]] = {
read: parseInt(parts[5]) * 512,
write: parseInt(parts[9]) * 512
};
}
}
}).catch(err => { });

// skip rest of stats if gtop not available
if (!hasGTop) return;
paths.forEach(path => {
if (!path) return;

GTop.glibtop_get_fsusage(this.storage, path);
let total = this.storage.blocks * this.storage.block_size;
let avail = this.storage.bavail * this.storage.block_size;
let free = this.storage.bfree * this.storage.block_size;
let used = total - free;
let usedPct = Math.round((used / (used + avail)) * 100);

let suffix = ` (${path})`;
this._returnValue(callback, _('Used %') + suffix, usedPct + '%', 'storage', 'string');
this._returnValue(callback, _('Free') + suffix, avail, 'storage', 'storage');

let dev = pathDeviceMap[path];
if (dev && deviceData[dev]) {
let currentRead = deviceData[dev].read;
let currentWrite = deviceData[dev].write;

this._returnValue(callback, _('Read total') + suffix, currentRead, 'storage', 'storage');
this._returnValue(callback, _('Write total') + suffix, currentWrite, 'storage', 'storage');
if (this._storageHistory[dev]) {
let rRate = (currentRead - this._storageHistory[dev].read) / dwell;
let wRate = (currentWrite - this._storageHistory[dev].write) / dwell;
this._returnValue(callback, _('Read rate') + suffix, rRate, 'storage', 'storage');
this._returnValue(callback, _('Write rate') + suffix, wRate, 'storage', 'storage');
}

GTop.glibtop_get_fsusage(this.storage, this._settings.get_string('storage-path'));

let total = this.storage.blocks * this.storage.block_size;
let avail = this.storage.bavail * this.storage.block_size;
let free = this.storage.bfree * this.storage.block_size;
let used = total - free;
let reserved = (total - avail) - used;
let freePercent = 0;
let usedPercent = 0;
if (total > 0) {
freePercent = Math.round((free / total) * 100);
usedPercent = Math.round((used / total) * 100);
}
this._storageHistory[dev] = { read: currentRead, write: currentWrite };
}

this._returnValue(callback, 'Total', total, 'storage', 'storage');
this._returnValue(callback, 'Used', used, 'storage', 'storage');
this._returnValue(callback, 'Reserved', reserved, 'storage', 'storage');
this._returnValue(callback, 'Free', avail, 'storage', 'storage');
this._returnValue(callback, 'Used %', usedPercent + '%', 'storage', 'string');
this._returnValue(callback, 'Free %', freePercent + '%', 'storage', 'string');
this._returnValue(callback, 'storage', avail, 'storage-group', 'storage');
if (path == paths[0])
this._returnValue(callback, 'storage', avail, 'storage-group', 'storage');
});
}).catch(err => { });
}

_queryBattery(callback) {
Expand Down