Merge pull request #1 from UshakovVasilii/master

Sync with upstream
This commit is contained in:
Erdem U. Altinyurt
2020-01-10 03:40:07 +03:00
committed by GitHub
25 changed files with 359 additions and 358 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
*.zip
freon@UshakovVasilii_Github.yahoo.com/schemas/gschemas.compiled

View File

@@ -1,5 +1,6 @@
#!/bin/sh
NAME=freon@UshakovVasilii_Github.yahoo.com
glib-compile-schemas $NAME/schemas
rm -rf ~/.local/share/gnome-shell/extensions/$NAME
cp -r $NAME ~/.local/share/gnome-shell/extensions/.

View File

@@ -1,18 +1,15 @@
const Lang = imports.lang;
const GLib = imports.gi.GLib;
const Me = imports.misc.extensionUtils.getCurrentExtension();
const CommandLineUtil = Me.imports.commandLineUtil;
var AticonfigUtil = new Lang.Class({
Name: 'AticonfigUtil',
Extends: CommandLineUtil.CommandLineUtil,
var AticonfigUtil = class extends CommandLineUtil.CommandLineUtil {
_init: function() {
this.parent();
constructor() {
super();
let path = GLib.find_program_in_path('aticonfig');
this._argv = path ? [path, '--odgt'] : null;
},
}
/*
Default Adapter - AMD Radeon R9 200 Series
@@ -39,4 +36,4 @@ var AticonfigUtil = new Lang.Class({
return [{ label : label.trim(), temp : temp}];
}
});
};

View File

@@ -1,16 +1,13 @@
const Lang = imports.lang;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Me = imports.misc.extensionUtils.getCurrentExtension();
const CommandLineUtil = Me.imports.commandLineUtil;
var BumblebeeNvidiaUtil = new Lang.Class({
Name: 'BumblebeeNvidiaUtil',
Extends: CommandLineUtil.CommandLineUtil,
var BumblebeeNvidiaUtil = class extends CommandLineUtil.CommandLineUtil {
_init: function() {
this.parent();
constructor() {
super();
// optirun nvidia-smi -q -d TEMPERATURE
this._path = GLib.find_program_in_path('optirun');
this._argv = this._path ? [this._path, 'nvidia-smi', '-q', '-d', 'TEMPERATURE'] : null;
@@ -35,7 +32,7 @@ var BumblebeeNvidiaUtil = new Lang.Class({
lockFilePath).monitor_file(Gio.FileMonitorFlags.NONE, null
);
this._lockMonitor.id = this._lockMonitor.connect(
'changed', Lang.bind(this, this._statusChanged)
'changed', this._statusChanged.bind(this)
);
// Check if the lock file already exists
@@ -44,9 +41,9 @@ var BumblebeeNvidiaUtil = new Lang.Class({
this._detectLabel();
this._active = true;
}
},
}
_detectLabel: function() {
_detectLabel() {
// optirun nvidia-smi -L
// GPU 0: GeForce GT 525M (UUID: GPU-...)
for (let line of GLib.spawn_command_line_sync(this._path + " nvidia-smi -L")){
@@ -58,9 +55,9 @@ var BumblebeeNvidiaUtil = new Lang.Class({
break;
}
}
},
}
_statusChanged: function(monitor, a_file, other_file, event_type) {
_statusChanged(monitor, a_file, other_file, event_type) {
if (event_type == Gio.FileMonitorEvent.CREATED) {
if(this._argv && !this._label)
this._detectLabel();
@@ -68,14 +65,14 @@ var BumblebeeNvidiaUtil = new Lang.Class({
} else if (event_type == Gio.FileMonitorEvent.DELETED) {
this._active = false;
}
},
}
execute: function(callback) {
execute(callback) {
if(this._active)
this.parent(callback);
super.execute(callback);
else
this._output = [];
},
}
get temp() {
let key = 'bumblebee-nvidia'
@@ -95,11 +92,11 @@ var BumblebeeNvidiaUtil = new Lang.Class({
}
}
return [{label: key, temp: null, displayName: label}];
},
}
destroy: function(){
this.parent();
destroy(){
super.destroy();
this._lockMonitor.disconnect(this._lockMonitor.id);
}
});
};

View File

@@ -1,17 +1,15 @@
const ByteArray = imports.byteArray;
const Lang = imports.lang;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
var CommandLineUtil = new Lang.Class({
Name: 'CommandLineUtil',
var CommandLineUtil = class {
_init: function(){
constructor(){
this._argv = null;
this._updated = false;
},
}
execute: function(callback) {
execute(callback) {
try{
this._callback = callback;
let [exit, pid, stdinFd, stdoutFd, stderrFd] =
@@ -28,8 +26,9 @@ var CommandLineUtil = new Lang.Class({
GLib.close(stdinFd);
let childWatch = GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, Lang.bind(this, function(pid, status, requestObj) {
let childWatch = GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, (pid, status, requestObj) => {
let output = [];
let error_output = [];
let [line, size] = [null, 0];
while (([line, size] = outReader.read_line(null)) != null && line != null) {
@@ -40,34 +39,35 @@ var CommandLineUtil = new Lang.Class({
while (([line, size] = errReader.read_line(null)) != null && line != null) {
if(line)
output.push(ByteArray.toString(line));
error_output.push(ByteArray.toString(line));
}
stderr.close(null);
GLib.source_remove(childWatch);
this._output = output;
this._error_output = error_output;
this._updated = true;
callback();
}));
});
} catch(e){
global.log(e.toString());
}
},
}
get available(){
return this._argv != null;
},
}
get updated (){
return this._updated;
},
}
set updated (updated){
this._updated = updated;
},
}
destroy: function(){
destroy(){
this._argv = null;
}
});
};

View File

@@ -1,93 +0,0 @@
/* -*- mode: js; js-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
Copyright (c) 2011-2012, Giovanni Campagna <scampa.giovanni@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the GNOME nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
const Gettext = imports.gettext;
const Gio = imports.gi.Gio;
const Config = imports.misc.config;
const ExtensionUtils = imports.misc.extensionUtils;
/**
* initTranslations:
* @domain: (optional): the gettext domain to use
*
* Initialize Gettext to load translations from extensionsdir/locale.
* If @domain is not provided, it will be taken from metadata['gettext-domain']
*/
function initTranslations(domain) {
let extension = ExtensionUtils.getCurrentExtension();
domain = domain || extension.metadata['gettext-domain'];
// check if this extension was built with "make zip-file", and thus
// has the locale files in a subfolder
// otherwise assume that extension has been installed in the
// same prefix as gnome-shell
let localeDir = extension.dir.get_child('locale');
if (localeDir.query_exists(null))
Gettext.bindtextdomain(domain, localeDir.get_path());
else
Gettext.bindtextdomain(domain, Config.LOCALEDIR);
}
/**
* getSettings:
* @schema: (optional): the GSettings schema id
*
* Builds and return a GSettings schema for @schema, using schema files
* in extensionsdir/schemas. If @schema is not provided, it is taken from
* metadata['settings-schema'].
*/
function getSettings(schema) {
let extension = ExtensionUtils.getCurrentExtension();
schema = schema || extension.metadata['settings-schema'];
const GioSSS = Gio.SettingsSchemaSource;
// check if this extension was built with "make zip-file", and thus
// has the schema files in a subfolder
// otherwise assume that extension has been installed in the
// same prefix as gnome-shell (and therefore schemas are available
// in the standard folders)
let schemaDir = extension.dir.get_child('schemas');
let schemaSource;
if (schemaDir.query_exists(null))
schemaSource = GioSSS.new_from_directory(schemaDir.get_path(),
GioSSS.get_default(),
false);
else
schemaSource = GioSSS.get_default();
let schemaObj = schemaSource.lookup(schema, true);
if (!schemaObj)
throw new Error('Schema ' + schema + ' could not be found for extension '
+ extension.metadata.uuid + '. Please check your installation.');
return new Gio.Settings({ settings_schema: schemaObj });
}

View File

@@ -1,5 +1,4 @@
const St = imports.gi.St;
const Lang = imports.lang;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Main = imports.ui.main;
@@ -8,15 +7,17 @@ const Mainloop = imports.mainloop;
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Me = imports.misc.extensionUtils.getCurrentExtension();
const Convenience = Me.imports.convenience;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const UDisks2 = Me.imports.udisks2;
const AticonfigUtil = Me.imports.aticonfigUtil;
const NvidiaUtil = Me.imports.nvidiaUtil;
const HddtempUtil = Me.imports.hddtempUtil;
const SensorsUtil = Me.imports.sensorsUtil;
const smartctlUtil = Me.imports.smartctlUtil;
const nvmecliUtil = Me.imports.nvmecliUtil;
const BumblebeeNvidiaUtil = Me.imports.bumblebeeNvidiaUtil;
const FreonItem = Me.imports.freonItem;
@@ -47,14 +48,11 @@ function _makeLogFunction(prefix) {
}
}
var FreonMenuButton = new Lang.Class({
Name: 'FreonMenuButton',
Extends: PanelMenu.Button,
const FreonMenuButton = GObject.registerClass(class Freon_FreonMenuButton extends PanelMenu.Button {
_init() {
super._init(St.Align.START);
_init: function(){
this.parent(St.Align.START);
this._settings = Convenience.getSettings();
this._settings = ExtensionUtils.getSettings();
var _debugFunc = _makeLogFunction('DEBUG');
this.debug = this._settings.get_boolean('debug') ? _debugFunc : () => {};
@@ -95,36 +93,38 @@ var FreonMenuButton = new Lang.Class({
this._createInitialIcon();
}
this.actor.add_actor(this._menuLayout);
this.add_actor(this._menuLayout);
this._settingChangedSignals = [];
this._addSettingChangedSignal('update-time', Lang.bind(this, this._updateTimeChanged));
this._addSettingChangedSignal('unit', Lang.bind(this, this._querySensors));
this._addSettingChangedSignal('show-icon-on-panel', Lang.bind(this, this._showIconOnPanelChanged));
this._addSettingChangedSignal('hot-sensors', Lang.bind(this, this._querySensors));
this._addSettingChangedSignal('show-decimal-value', Lang.bind(this, this._querySensors));
this._addSettingChangedSignal('show-fan-rpm', Lang.bind(this, this._querySensors));
this._addSettingChangedSignal('show-voltage', Lang.bind(this, this._querySensors));
this._addSettingChangedSignal('drive-utility', Lang.bind(this, this._driveUtilityChanged));
this._addSettingChangedSignal('gpu-utility', Lang.bind(this, this._gpuUtilityChanged));
this._addSettingChangedSignal('position-in-panel', Lang.bind(this, this._positionInPanelChanged));
this._addSettingChangedSignal('group-temperature', Lang.bind(this, this._querySensors))
this._addSettingChangedSignal('group-voltage', Lang.bind(this, this._rerender))
this._addSettingChangedSignal('update-time', this._updateTimeChanged.bind(this));
this._addSettingChangedSignal('unit', this._querySensors.bind(this));
this._addSettingChangedSignal('show-icon-on-panel', this._showIconOnPanelChanged.bind(this));
this._addSettingChangedSignal('hot-sensors', this._querySensors.bind(this));
this._addSettingChangedSignal('show-decimal-value', this._querySensors.bind(this));
this._addSettingChangedSignal('show-fan-rpm', this._querySensors.bind(this));
this._addSettingChangedSignal('show-voltage', this._querySensors.bind(this));
this._addSettingChangedSignal('drive-utility', this._driveUtilityChanged.bind(this));
this._addSettingChangedSignal('gpu-utility', this._gpuUtilityChanged.bind(this));
this._addSettingChangedSignal('position-in-panel', this._positionInPanelChanged.bind(this));
this._addSettingChangedSignal('panel-box-index', this._positionInPanelChanged.bind(this));
this._addSettingChangedSignal('group-temperature', this._querySensors.bind(this))
this._addSettingChangedSignal('group-voltage', this._rerender.bind(this))
this.connect('destroy', Lang.bind(this, this._onDestroy));
this.connect('destroy', this._onDestroy.bind(this));
// don't postprone the first call by update-time.
this._querySensors();
this._addTimer();
this._updateUITimeoutId = Mainloop.timeout_add(250, Lang.bind(this, function (){
this._updateUI(true);
this._updateUITimeoutId = Mainloop.timeout_add(250, () => {
this._updateUI();
// readd to update queue
return true;
}));
},
});
}
_createHotItem: function(s, showIcon, gicon){
_createHotItem(s, showIcon, gicon){
if(showIcon){
let i = new St.Icon({ style_class: 'system-status-icon'});
this._hotIcons[s] = i;
@@ -133,25 +133,25 @@ var FreonMenuButton = new Lang.Class({
this._menuLayout.add(i);
}
let l = new St.Label({
text: '\u2026', /* ... */
text: '\u26a0', // ⚠, warning
y_expand: true,
y_align: Clutter.ActorAlign.CENTER});
this._hotLabels[s] = l;
this._menuLayout.add(l);
},
}
_createInitialIcon: function() {
_createInitialIcon() {
this._initialIcon = new St.Icon({ style_class: 'system-status-icon'});
this._initialIcon.gicon = this._sensorIcons['gpu-temperature'];
this._menuLayout.add(this._initialIcon);
},
}
_rerender : function(){
_rerender(){
this._needRerender = true;
this._querySensors();
},
}
_positionInPanelChanged : function(){
_positionInPanelChanged(){
this.container.get_parent().remove_actor(this.container);
// small HACK with private boxes :)
@@ -162,10 +162,11 @@ var FreonMenuButton = new Lang.Class({
};
let p = this.positionInPanel;
boxes[p].insert_child_at_index(this.container, p == 'right' ? 0 : -1)
},
let i = this._settings.get_int('panel-box-index');
boxes[p].insert_child_at_index(this.container, i);
}
_showIconOnPanelChanged : function(){
_showIconOnPanelChanged(){
if(this._settings.get_boolean('show-icon-on-panel')) {
let index = 0;
for(let k in this._hotLabels){
@@ -180,38 +181,41 @@ var FreonMenuButton = new Lang.Class({
this._hotIcons[k].destroy();
this._hotIcons = {};
}
},
}
_driveUtilityChanged : function(){
_driveUtilityChanged(){
this._destroyDriveUtility();
this._initDriveUtility();
this._querySensors();
},
}
_initDriveUtility : function(){
_initDriveUtility(){
switch(this._settings.get_string('drive-utility')){
case 'hddtemp':
this._utils.disks = new HddtempUtil.HddtempUtil();
break;
case 'udisks2':
this._utils.disks = new UDisks2.UDisks2(Lang.bind(this, function() {
this._utils.disks = new UDisks2.UDisks2(() => {
// this._updateDisplay(); we cannot change actor in background thread #74
}));
});
break;
case 'smartctl':
this._utils.disks = new smartctlUtil.smartctlUtil();
break;
case 'nvmecli':
this._utils.disks = new nvmecliUtil.nvmecliUtil();
break;
}
},
}
_destroyDriveUtility : function(){
_destroyDriveUtility(){
if(this._utils.disks){
this._utils.disks.destroy();
delete this._utils.disks;
}
},
}
_initGpuUtility : function(){
_initGpuUtility(){
switch(this._settings.get_string('gpu-utility')){
case 'nvidia-settings':
this._utils.gpu = new NvidiaUtil.NvidiaUtil();
@@ -223,39 +227,39 @@ var FreonMenuButton = new Lang.Class({
this._utils.gpu = new BumblebeeNvidiaUtil.BumblebeeNvidiaUtil();
break;
}
},
}
_destroyGpuUtility : function(){
_destroyGpuUtility(){
if(this._utils.gpu){
this._utils.gpu.destroy();
delete this._utils.gpu;
}
},
}
_gpuUtilityChanged : function(){
_gpuUtilityChanged(){
this._destroyGpuUtility();
this._initGpuUtility();
this._querySensors();
},
}
_updateTimeChanged : function(){
_updateTimeChanged(){
Mainloop.source_remove(this._timeoutId);
this._addTimer();
},
}
_addTimer : function(){
this._timeoutId = Mainloop.timeout_add_seconds(this._settings.get_int('update-time'), Lang.bind(this, function (){
_addTimer(){
this._timeoutId = Mainloop.timeout_add_seconds(this._settings.get_int('update-time'), () => {
this._querySensors();
// readd to update queue
return true;
}));
},
});
}
_addSettingChangedSignal : function(key, callback){
_addSettingChangedSignal(key, callback){
this._settingChangedSignals.push(this._settings.connect('changed::' + key, callback));
},
}
_onDestroy: function(){
_onDestroy(){
this._destroyDriveUtility();
this._destroyGpuUtility();
Mainloop.source_remove(this._timeoutId);
@@ -264,20 +268,19 @@ var FreonMenuButton = new Lang.Class({
for (let signal of this._settingChangedSignals){
this._settings.disconnect(signal);
};
},
}
_querySensors: function(){
_querySensors(){
for (let sensor of Object.values(this._utils)) {
if (sensor.available) {
sensor.execute(Lang.bind(this,function(){
sensor.execute(() => {
// we cannot change actor in background thread #74
}));
});
}
}
},
}
_updateUI: function(){
let needUpdate = false;
_updateUI(needUpdate = false){
for (let sensor of Object.values(this._utils)) {
if (sensor.available && sensor.updated) {
this.debug(sensor + ' updated');
@@ -289,9 +292,9 @@ var FreonMenuButton = new Lang.Class({
this._updateDisplay(); // #74
this.debug('update display');
}
},
}
_fixNames: function(sensors){
_fixNames(sensors){
let names = [];
for (let s of sensors){
if(s.type == 'separator' ||
@@ -310,9 +313,9 @@ var FreonMenuButton = new Lang.Class({
}
names.push(name);
}
},
}
_updateDisplay: function(){
_updateDisplay(){
let gpuTempInfo = this._utils.sensors.gpu;
if (this._utils.gpu && this._utils.gpu.available)
@@ -416,6 +419,9 @@ var FreonMenuButton = new Lang.Class({
this._fixNames(sensors);
for (let k in this._hotLabels)
this._hotLabels[k].set_text('\u26a0'); // ⚠, warning
for (let s of sensors)
if(s.type != 'separator') {
let l = this._hotLabels[s.key || s.label];
@@ -465,9 +471,9 @@ var FreonMenuButton = new Lang.Class({
this.menu.addMenuItem(item);
this._appendStaticMenuItems();
}
},
}
_appendStaticMenuItems : function(){
_appendStaticMenuItems(){
// separator
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
@@ -484,9 +490,9 @@ var FreonMenuButton = new Lang.Class({
Util.spawn(["gnome-shell-extension-prefs", Me.metadata.uuid]);
});
this.menu.addMenuItem(settings);
},
}
_appendMenuItems : function(sensors){
_appendMenuItems(sensors){
this._lastSensorsCount = sensors.length;
this._sensorMenuItems = {};
let needGroupTemperature = this._settings.get_boolean('group-temperature');
@@ -515,7 +521,7 @@ var FreonMenuButton = new Lang.Class({
} else {
let key = s.key || s.label;
let item = new FreonItem.FreonItem(this._sensorIcons[s.type], key, s.label, s.value, s.displayName || undefined);
item.connect('activate', Lang.bind(this, function (self) {
item.connect('activate', (self) => {
let l = this._hotLabels[self.key];
let hotSensors = this._settings.get_strv('hot-sensors');
if(l){
@@ -560,7 +566,7 @@ var FreonMenuButton = new Lang.Class({
function(item, pos) {
return hotSensors.indexOf(item) == pos;
}));
}));
});
if (this._hotLabels[key]) {
item.main = true;
if(this._hotIcons[key])
@@ -595,14 +601,14 @@ var FreonMenuButton = new Lang.Class({
}
}
this._appendStaticMenuItems();
},
}
_toFahrenheit: function(c){
_toFahrenheit(c){
return ((9/5)*c+32);
},
}
_formatTemp: function(value) {
_formatTemp(value) {
if(value === null)
return 'N/A';
if (this._settings.get_string('unit')=='fahrenheit'){
@@ -610,12 +616,11 @@ var FreonMenuButton = new Lang.Class({
}
let format = '%.1f';
if (!this._settings.get_boolean('show-decimal-value')){
//ret = Math.round(value);
format = '%d';
format = '%.0f';
}
format += '%s';
return format.format(value, (this._settings.get_string('unit')=='fahrenheit') ? "\u00b0F" : "\u00b0C");
},
}
get positionInPanel(){
return this._settings.get_string('position-in-panel');
@@ -625,13 +630,13 @@ var FreonMenuButton = new Lang.Class({
let freonMenu;
function init(extensionMeta) {
Convenience.initTranslations();
ExtensionUtils.initTranslations();
}
function enable() {
freonMenu = new FreonMenuButton();
let positionInPanel = freonMenu.positionInPanel;
Main.panel.addToStatusArea('freonMenu', freonMenu, positionInPanel == 'right' ? 0 : -1, positionInPanel);
Main.panel.addToStatusArea('freonMenu', freonMenu);
freonMenu._positionInPanelChanged();
}
function disable() {

View File

@@ -1,13 +1,11 @@
const Lang = imports.lang;
const St = imports.gi.St;
const GObject = imports.gi.GObject;
const PopupMenu = imports.ui.popupMenu;
const St = imports.gi.St;
var FreonItem = new Lang.Class({
Name: 'FreonItem',
Extends: PopupMenu.PopupBaseMenuItem,
var FreonItem = GObject.registerClass(class FreonItem extends PopupMenu.PopupBaseMenuItem {
_init: function(gIcon, key, label, value, displayName) {
this.parent();
_init(gIcon, key, label, value, displayName) {
super._init();
this._main = false;
this._key = key;
this._gIcon = gIcon;
@@ -17,7 +15,7 @@ var FreonItem = new Lang.Class({
this.actor.add(this._labelActor, {x_fill: true, expand: true});
this._valueLabel = new St.Label({text: value});
this.actor.add(this._valueLabel);
},
}
set main(main) {
if(main)
@@ -25,23 +23,23 @@ var FreonItem = new Lang.Class({
else
this.setOrnament(PopupMenu.Ornament.NONE);
this._main = main;
},
}
get main() {
return this._main;
},
}
get key() {
return this._key;
},
}
set display_name(text) {
return this._labelActor.text = text;
},
}
get gicon() {
return this._gIcon;
},
}
set value(value) {
this._valueLabel.text = value;

View File

@@ -1,15 +1,12 @@
const Lang = imports.lang;
const GLib = imports.gi.GLib;
const Me = imports.misc.extensionUtils.getCurrentExtension();
const CommandLineUtil = Me.imports.commandLineUtil;
var HddtempUtil = new Lang.Class({
Name: 'HddtempUtil',
Extends: CommandLineUtil.CommandLineUtil,
var HddtempUtil = class extends CommandLineUtil.CommandLineUtil {
_init: function() {
this.parent();
constructor() {
super();
let hddtempArgv = GLib.find_program_in_path('hddtemp');
if(hddtempArgv) {
// check if this user can run hddtemp directly.
@@ -52,7 +49,7 @@ var HddtempUtil = new Lang.Class({
// use net cat to get data
this._argv = [nc, 'localhost', port.toString()];
}
},
}
get temp() {
if(!this._output)
@@ -78,4 +75,4 @@ var HddtempUtil = new Lang.Class({
return sensors;
}
});
};

View File

@@ -1,5 +1,5 @@
{
"shell-version": ["3.30"],
"shell-version": ["3.34"],
"uuid": "freon@UshakovVasilii_Github.yahoo.com",
"name": "Freon",
"description": "Shows CPU temperature, disk temperature, video card temperature (NVIDIA/Catalyst/Bumblebee&NVIDIA), voltage and fan RPM (forked from xtranophilist/gnome-shell-extension-sensors)",

View File

@@ -1,17 +1,14 @@
const ByteArray = imports.byteArray;
const Lang = imports.lang;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Me = imports.misc.extensionUtils.getCurrentExtension();
const CommandLineUtil = Me.imports.commandLineUtil;
var NvidiaUtil = new Lang.Class({
Name: 'NvidiaUtil',
Extends: CommandLineUtil.CommandLineUtil,
var NvidiaUtil = class extends CommandLineUtil.CommandLineUtil {
_init: function() {
this.parent();
constructor() {
super();
let path = GLib.find_program_in_path('nvidia-settings');
this._argv = path ? [path, '-q', 'gpucoretemp', '-t'] : null;
this._labels = [];
@@ -29,7 +26,7 @@ var NvidiaUtil = new Lang.Class({
GLib.close(stdinFd);
GLib.close(stderrFd);
let childWatch = GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, Lang.bind(this, function(pid, status, requestObj) {
let childWatch = GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, (pid, status, requestObj) => {
let output = [];
let [line, size] = [null, 0];
@@ -42,12 +39,18 @@ var NvidiaUtil = new Lang.Class({
stdout.close(null);
GLib.source_remove(childWatch);
}));
});
}
},
}
get temp() {
if(!this._output)
let output = [];
if(this._output)
output.push(...this._output)
if(this._error_output)
output.push(...this._error_output)
if(output.length === 0)
return [];
let temps = [];
for (let line of this._output) {
@@ -79,4 +82,4 @@ var NvidiaUtil = new Lang.Class({
return gpus;
}
});
};

View File

@@ -0,0 +1,50 @@
const GLib = imports.gi.GLib;
const Me = imports.misc.extensionUtils.getCurrentExtension();
function getNvmeData (argv){
const nvme = GLib.find_program_in_path('nvme')
return JSON.parse(GLib.spawn_command_line_sync(`${nvme} ${argv} -o json`)[1].toString())
}
var nvmecliUtil = class {
constructor(callback) {
this._nvmeDevices = [];
try {
this._nvmeDevices = getNvmeData("list")["Devices"]
} catch (e) {
global.log('[FREON] Unable to find nvme devices: ' + e);
}
this._updated = true;
}
get available(){
return this._nvmeDevices.length > 0;
}
get updated (){
return this._updated;
}
set updated (updated){
this._updated = updated;
}
get temp() {
return this._nvmeDevices.map(device => {
return {
label: device["ModelNumber"],
temp: parseFloat(getNvmeData(`smart-log ${device["DevicePath"]}`).temperature) - 273.15
}
})
}
destroy(callback) {
this._nvmeDevices = [];
}
execute(callback) {
this._updated = true;
}
};

View File

@@ -134,3 +134,11 @@ msgstr ""
#: prefs.js:49
msgid "Right"
msgstr ""
#: extension.js:479
msgid "Go to the Freon wiki"
msgstr ""
#: extension.js:486
msgid "Sensor Settings"
msgstr ""

View File

@@ -2,16 +2,17 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-02-20 19:23+0200\n"
"PO-Revision-Date: 2016-02-20 19:31+0200\n"
"POT-Creation-Date: 2015-10-06 17:05-0300\n"
"PO-Revision-Date: 2019-09-19 17:58+0300\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.6\n"
"Last-Translator: \n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"Language: ru\n"
"X-Generator: Poedit 2.2.3\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#: bumblebeeNvidiaUtil.js:75 prefs.js:82
msgid "Bumblebee + NVIDIA"
@@ -19,16 +20,16 @@ msgstr "Bumblebee + NVIDIA"
#: extension.js:319
msgid "Average"
msgstr "Средняя температура"
msgstr "Средняя"
#: extension.js:320
msgid "Maximum"
msgstr "Максимальная температура"
msgstr "Максимальная"
#: extension.js:341
#, javascript-format
msgid "%drpm"
msgstr "%d об / мин"
msgstr "%d об/мин"
#: extension.js:350
#, javascript-format
@@ -49,7 +50,7 @@ msgstr ""
#: extension.js:488
msgid "Temperature Sensors"
msgstr "Датчик температуры"
msgstr "Датчики температуры"
#: extension.js:495
msgid "Voltage"
@@ -81,15 +82,15 @@ msgstr "Позиция на панели"
#: prefs.js:55
msgid "Show Icon on Panel"
msgstr "Иконка на панели"
msgstr "Отображать иконку на панели"
#: prefs.js:58
msgid "Show Fan Speed"
msgstr "Скорость вентилятора"
msgstr "Отображать скорость вентилятора"
#: prefs.js:61
msgid "Show Power Supply Voltage"
msgstr "Напряжение питания"
msgstr "Отображать напряжение питания"
#: prefs.js:64
msgid "Group Temperature Items"
@@ -109,7 +110,7 @@ msgstr "Работает если у вас более трёх датчиков
#: prefs.js:74
msgid "HDD/SSD Temperature Utility"
msgstr "HDD/SSD утилита мониторинга"
msgstr "Утилита для определения температуры HDD/SSD"
#: prefs.js:79
msgid "None"
@@ -125,4 +126,26 @@ msgstr "Catalyst"
#: prefs.js:84
msgid "Video Card Temperature Utility"
msgstr "Утилита мониторинга видеокарт"
msgstr "Утилита для определения температуры видеокарты"
#: prefs.js:49
msgid "Left"
msgstr "Слева"
#: prefs.js:49
msgid "Center"
msgstr "По центру"
#: prefs.js:49
msgid "Right"
msgstr "Справа"
#: extension.js:479
msgid "Go to the Freon wiki"
msgstr "Перейти на wiki Freon"
#: extension.js:486
#, fuzzy
#| msgid "Sensors Settings"
msgid "Sensor Settings"
msgstr "Настройки"

View File

@@ -3,14 +3,14 @@ msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-10-06 17:05-0300\n"
"PO-Revision-Date: 2018-01-15 09:36+0200\n"
"PO-Revision-Date: 2019-09-19 17:53+0300\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: uk_UA\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.0.3\n"
"X-Generator: Poedit 2.2.3\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
@@ -74,7 +74,7 @@ msgstr "Показувати одну цифру після десятковог
#: prefs.js:45
msgid "Temperature Unit"
msgstr "Одиниця вимиру температури"
msgstr "Одиниця виміру температури"
#: prefs.js:51
msgid "Position in Panel"
@@ -82,7 +82,7 @@ msgstr "Положення на панелі"
#: prefs.js:55
msgid "Show Icon on Panel"
msgstr "Відображати значок на панелі"
msgstr "Показувати значок на панелі"
#: prefs.js:58
msgid "Show Fan Speed"
@@ -139,3 +139,13 @@ msgstr "В центрі"
#: prefs.js:49
msgid "Right"
msgstr "Праворуч"
#: extension.js:479
msgid "Go to the Freon wiki"
msgstr "Перейти на wiki Freon"
#: extension.js:486
#, fuzzy
#| msgid "Sensors Settings"
msgid "Sensor Settings"
msgstr "Налаштування сенсорів"

View File

@@ -1,10 +1,10 @@
const GObject = imports.gi.GObject;
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Me = imports.misc.extensionUtils.getCurrentExtension();
const Convenience = Me.imports.convenience;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']);
const _ = Gettext.gettext;
@@ -14,19 +14,16 @@ const modelColumn = {
}
function init() {
Convenience.initTranslations();
ExtensionUtils.initTranslations();
}
var FreonPrefsWidget = new GObject.Class({
Name: 'Freon.Prefs.Widget',
GTypeName: 'FreonPrefsWidget',
Extends: Gtk.Grid,
var FreonPrefsWidget = new GObject.registerClass(class Freon_FreonPrefsWidget extends Gtk.Grid {
_init: function(params) {
this.parent(params);
_init() {
super._init();
this.margin = this.row_spacing = this.column_spacing = 20;
this._settings = Convenience.getSettings();
this._settings = ExtensionUtils.getSettings();
let i = 0;
@@ -41,7 +38,7 @@ var FreonPrefsWidget = new GObject.Class({
this._addComboBox({
items : {centigrade : "\u00b0C", fahrenheit : "\u00b0F"},
key: 'unit', y : i++, x : 2,
key: 'unit', y : i++, x : 3,
label: _('Temperature Unit')
});
@@ -51,25 +48,29 @@ var FreonPrefsWidget = new GObject.Class({
label: _('Position in Panel')
});
this._addSwitch({key : 'show-icon-on-panel', y : i++, x : 2,
let panelBoxIndex = Gtk.SpinButton.new_with_range (-1, 20, 1);
this.attach(panelBoxIndex, 2, i, 1, 1);
this._settings.bind('panel-box-index', panelBoxIndex, 'value', Gio.SettingsBindFlags.DEFAULT);
this._addSwitch({key : 'show-icon-on-panel', y : i++, x : 3,
label : _('Show Icon on Panel')});
this._addSwitch({key : 'show-fan-rpm', y : i, x : 0,
label : _('Show Fan Speed')});
this._addSwitch({key : 'show-voltage', y : i++, x : 2,
this._addSwitch({key : 'show-voltage', y : i++, x : 3,
label : _('Show Power Supply Voltage')});
this._addSwitch({key : 'group-temperature', y : i, x : 0,
label : _('Group Temperature Items'),
help : _("Works if you have more than three temperature sensors")});
this._addSwitch({key : 'group-voltage', y : i++, x : 2,
this._addSwitch({key : 'group-voltage', y : i++, x : 3,
label : _('Group Voltage Items'),
help : _("Works if you have more than three voltage sensors")});
this._addComboBox({
items : {none : 'None', hddtemp : 'Hddtemp', udisks2 : 'UDisks2', smartctl : 'smartctl'},
items : {none : 'None', hddtemp : 'Hddtemp', udisks2 : 'UDisks2', smartctl : 'smartctl', nvmecli : 'nvme-cli'},
key: 'drive-utility', y : i, x : 0,
label: _('HDD/SSD Temperature Utility')
});
@@ -80,12 +81,12 @@ var FreonPrefsWidget = new GObject.Class({
'nvidia-settings' : _('NVIDIA'),
'aticonfig' : _('Catalyst'),
'bumblebee-nvidia-smi': _('Bumblebee + NVIDIA') },
key: 'gpu-utility', y : i, x : 2,
key: 'gpu-utility', y : i, x : 3,
label: _('Video Card Temperature Utility')
});
},
}
_addSwitch : function(params){
_addSwitch(params){
let lbl = new Gtk.Label({label: params.label,halign : Gtk.Align.END});
this.attach(lbl, params.x, params.y, 1, 1);
let sw = new Gtk.Switch({halign : Gtk.Align.END, valign : Gtk.Align.CENTER});
@@ -95,9 +96,9 @@ var FreonPrefsWidget = new GObject.Class({
sw.set_tooltip_text(params.help);
}
this._settings.bind(params.key, sw, 'active', Gio.SettingsBindFlags.DEFAULT);
},
}
_addComboBox : function(params){
_addComboBox(params){
let model = new Gtk.ListStore();
model.set_column_types([GObject.TYPE_STRING, GObject.TYPE_STRING]);
@@ -112,12 +113,12 @@ var FreonPrefsWidget = new GObject.Class({
combobox.set_active(Object.keys(params.items).indexOf(this._settings.get_string(params.key)));
combobox.connect('changed', Lang.bind(this, function(entry) {
combobox.connect('changed', (entry) => {
let [success, iter] = combobox.get_active_iter();
if (!success)
return;
this._settings.set_string(params.key, model.get_value(iter, 0))
}));
});
this.attach(new Gtk.Label({ label: params.label, halign : Gtk.Align.END}), params.x, params.y, 1, 1);
this.attach(combobox, params.x + 1, params.y, 1, 1);

View File

@@ -63,6 +63,12 @@
<description>Position in Panel ('left', 'center', 'right')</description>
</key>
<key name="panel-box-index" type="i">
<default>0</default>
<summary>Index in panel box</summary>
<description>Index within the selected panel box (0: first, 1: second, ..., -1: last)</description>
</key>
<key type="b" name="group-temperature">
<default>true</default>
<summary>Group temperature menu items</summary>

View File

@@ -1,63 +1,66 @@
const Lang = imports.lang;
const GLib = imports.gi.GLib;
const Me = imports.misc.extensionUtils.getCurrentExtension();
const CommandLineUtil = Me.imports.commandLineUtil;
var SensorsUtil = new Lang.Class({
Name: 'SensorsUtil',
Extends: CommandLineUtil.CommandLineUtil,
var SensorsUtil = class extends CommandLineUtil.CommandLineUtil {
_init: function() {
this.parent();
constructor() {
super();
let path = GLib.find_program_in_path('sensors');
// -A: Do not show adapter -j: JSON output
this._argv = path ? [path, '-A', '-j'] : null;
},
}
get temp() {
return this._parseGenericSensorsOutput(/^temp\d_input/, 'temp');
},
return this._parseGenericSensorsOutput(/^temp\d+_input/, 'temp');
}
get gpu() {
return this._parseGpuSensorsOutput(/^temp\d_input/, 'temp');
},
return this._parseGpuSensorsOutput(/^temp\d+_input/, 'temp');
}
get rpm() {
return this._parseGenericSensorsOutput(/^fan\d_input/, 'rpm');
},
return this._parseGenericSensorsOutput(/^fan\d+_input/, 'rpm');
}
get volt() {
return this._parseGenericSensorsOutput(/^in\d_input/, 'volt');
},
return this._parseGenericSensorsOutput(/^in\d+_input/, 'volt');
}
_parseGenericSensorsOutput: function(sensorFilter, sensorType) {
_parseGenericSensorsOutput(sensorFilter, sensorType) {
return this._parseSensorsOutput(sensorFilter, sensorType, false);
},
}
_parseGpuSensorsOutput: function(sensorFilter, sensorType) {
_parseGpuSensorsOutput(sensorFilter, sensorType) {
return this._parseSensorsOutput(sensorFilter, sensorType, true);
},
}
_parseSensorsOutput: function(sensorFilter, sensorType, gpuFlag) {
_parseSensorsOutput(sensorFilter, sensorType, gpuFlag) {
if(!this._output)
return [];
// Prep output as one big string for JSON parser
let output = this._output.join('');
let data = []
try {
data = JSON.parse(output);
data = JSON.parse(this._output.join(''));
} catch (e) {
try {
// fix for wrong lm_sensors output
// https://github.com/UshakovVasilii/gnome-shell-extension-freon/issues/114#issuecomment-491613545
let lineRemoved = this._output.filter(l => l.trim() !== ',').join('\n');
let errorRemoved = lineRemoved.replace(/ERROR.*Can't read/, "");
errorRemoved = errorRemoved.replace(/ERROR.*I\/O error/, "");
data = JSON.parse(errorRemoved);
} catch (e) {
global.log(e.toString());
return [];
}
}
let sensors = [];
for (var chipset in data) {
let gpuFilter = /(radeon|amdgpu|nouveau)/;
if (!data.hasOwnProperty(chipset) || gpuFlag != gpuFilter.test(chipset))
if (!data.hasOwnProperty(chipset) || (gpuFlag != gpuFilter.test(chipset) && sensorType === 'temp'))
continue;
let chipsetSensors = data[chipset]
@@ -80,4 +83,4 @@ var SensorsUtil = new Lang.Class({
}
return sensors;
}
});
};

View File

@@ -1,18 +1,15 @@
const Lang = imports.lang;
const GLib = imports.gi.GLib;
const Me = imports.misc.extensionUtils.getCurrentExtension();
const CommandLineUtil = Me.imports.commandLineUtil;
var smartctlUtil = new Lang.Class({
Name: 'smartctlUtil',
Extends: CommandLineUtil.CommandLineUtil,
var smartctlUtil = class extends CommandLineUtil.CommandLineUtil {
_init: function() {
this.parent();
constructor() {
super();
let path = GLib.find_program_in_path('smartctl');
this._argv = path ? [path, '-x', '/dev/nvme0'] : null;
},
}
get temp() {
if(!this._output)
@@ -42,11 +39,10 @@ var smartctlUtil = new Lang.Class({
}
return sensors;
},
}
get available(){
return true;
},
});
}
};

View File

@@ -1,4 +1,3 @@
const Lang = imports.lang;
const Gio = imports.gi.Gio;
const UDisksDriveProxy = Gio.DBusProxy.makeProxyWrapper(
@@ -18,7 +17,7 @@ const UDisksDriveAtaProxy = Gio.DBusProxy.makeProxyWrapper(
// Poor man's async.js
const Async = {
// mapping will be done in parallel
map: function(arr, mapClb /* function(in, successClb)) */, resClb /* function(result) */) {
map(arr, mapClb /* function(in, successClb)) */, resClb /* function(result) */) {
let counter = arr.length;
let result = [];
for (let i = 0; i < arr.length; ++i) {
@@ -31,30 +30,28 @@ const Async = {
}
// routines for handling of udisks2
var UDisks2 = new Lang.Class({
Name: 'UDisks2',
var UDisks2 = class {
_init: function(callback) {
this.parent();
constructor(callback) {
this._udisksProxies = [];
this._get_drive_ata_proxies(Lang.bind(this, function(proxies) {
this._get_drive_ata_proxies((proxies) => {
this._udisksProxies = proxies;
callback();
}));
});
this._updated = true;
},
}
get available(){
return this._udisksProxies.length > 0;
},
}
get updated (){
return this._updated;
},
}
set updated (updated){
this._updated = updated;
},
}
// creates a list of sensor objects from the list of proxies given
get temp() {
@@ -67,10 +64,10 @@ var UDisks2 = new Lang.Class({
temp: proxy.ata.SmartTemperature - 273.15
};
});
},
}
// calls callback with [{ drive: UDisksDriveProxy, ata: UDisksDriveAtaProxy }, ... ] for every drive that implements both interfaces
_get_drive_ata_proxies: function(callback) {
_get_drive_ata_proxies(callback) {
Gio.DBusObjectManagerClient.new(Gio.DBus.system, 0, "org.freedesktop.UDisks2", "/org/freedesktop/UDisks2", null, null, function(src, res) {
try {
let objMgr = Gio.DBusObjectManagerClient.new_finish(res); //might throw
@@ -107,9 +104,9 @@ var UDisks2 = new Lang.Class({
global.log('[FREON] Could not find UDisks2 objects: ' + e);
}
});
},
}
destroy: function(callback) {
destroy(callback) {
for (let proxy of this._udisksProxies){
if(proxy.drive){
proxy.drive.run_dispose();
@@ -119,10 +116,10 @@ var UDisks2 = new Lang.Class({
}
}
this._udisksProxies = [];
},
}
execute: function(callback) {
execute(callback) {
this._updated = true;
},
}
});
};

View File

@@ -1,5 +1,6 @@
#!/bin/sh
NAME=freon@UshakovVasilii_Github.yahoo.com
glib-compile-schemas $NAME/schemas
cd $NAME
zip -r $NAME.zip *
cd ..