mirror of
https://github.com/morgan9e/gnome-shell-extension-freon
synced 2026-04-15 00:44:22 +09:00
add utility for Bumblebee & NVIDIA, #5
This commit is contained in:
@@ -0,0 +1,95 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
const BumblebeeNvidiaUtil = new Lang.Class({
|
||||||
|
Name: 'BumblebeeNvidiaUtil',
|
||||||
|
Extends: CommandLineUtil.CommandLineUtil,
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this.parent();
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// original source here:
|
||||||
|
// https://github.com/meden/gse-bumblebee-indicator
|
||||||
|
// thank meden!
|
||||||
|
let virtualDisplay = ':8';
|
||||||
|
let configFile = Gio.File.new_for_path('/etc/bumblebee/bumblebee.conf');
|
||||||
|
let contents = configFile.load_contents(null);
|
||||||
|
if (contents[0]) {
|
||||||
|
let pattern = /^VirtualDisplay=.*$/m
|
||||||
|
let match = new String(pattern.exec(new String(contents)));
|
||||||
|
virtualDisplay = match.substr(16);
|
||||||
|
}
|
||||||
|
let lockFile = '/tmp/.X' + virtualDisplay + '-lock';
|
||||||
|
this._lockMonitor = Gio.File.new_for_path(
|
||||||
|
lockFile).monitor_file(Gio.FileMonitorFlags.NONE, null
|
||||||
|
);
|
||||||
|
this._lockMonitor.id = this._lockMonitor.connect(
|
||||||
|
'changed', Lang.bind(this, this._statusChanged)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
_detectLabel: function() {
|
||||||
|
// optirun nvidia-smi -L
|
||||||
|
// GPU 0: GeForce GT 525M (UUID: GPU-...)
|
||||||
|
for each(let line in GLib.spawn_command_line_sync(this._path + " nvidia-smi -L")){
|
||||||
|
let match = /.*GPU [\d]:([\w\d\ ]+).*/.exec(line);
|
||||||
|
if(match){
|
||||||
|
this._label = match[1];
|
||||||
|
if(this._label)
|
||||||
|
this._label = this._label.trim();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_statusChanged: function(monitor, a_file, other_file, event_type) {
|
||||||
|
if (event_type == Gio.FileMonitorEvent.CREATED) {
|
||||||
|
if(this._argv && !this._label)
|
||||||
|
this._detectLabel();
|
||||||
|
this._active = true;
|
||||||
|
} else if (event_type == Gio.FileMonitorEvent.DELETED) {
|
||||||
|
this._active = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
execute: function(callback) {
|
||||||
|
if(this._active)
|
||||||
|
this.parent(callback);
|
||||||
|
else
|
||||||
|
this._output = [];
|
||||||
|
},
|
||||||
|
|
||||||
|
get temp() {
|
||||||
|
let key = 'bumblebee-nvidia'
|
||||||
|
let label = this._label ? this._label : _('Bumblebee + NVIDIA');
|
||||||
|
if(!this._active || !this._output)
|
||||||
|
return [{label: key, temp: null, displayName: label}];
|
||||||
|
// GPU Current Temp : 37 C
|
||||||
|
for each(let line in this._output) {
|
||||||
|
if(!line)
|
||||||
|
continue;
|
||||||
|
let r;
|
||||||
|
if(line.indexOf('GPU Current Temp') > 0)
|
||||||
|
return [{
|
||||||
|
label: key,
|
||||||
|
temp: (r = /[\s]*GPU Current Temp[\s]*:[\s]*(\d{1,3}).*/.exec(line)) ? parseFloat(r[1]) : null,
|
||||||
|
displayName: label
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy: function(){
|
||||||
|
this.parent();
|
||||||
|
this._lockMonitor.disconnect(this._lockMonitor.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ const AticonfigUtil = Me.imports.aticonfigUtil;
|
|||||||
const NvidiaUtil = Me.imports.nvidiaUtil;
|
const NvidiaUtil = Me.imports.nvidiaUtil;
|
||||||
const HddtempUtil = Me.imports.hddtempUtil;
|
const HddtempUtil = Me.imports.hddtempUtil;
|
||||||
const SensorsUtil = Me.imports.sensorsUtil;
|
const SensorsUtil = Me.imports.sensorsUtil;
|
||||||
|
const BumblebeeNvidiaUtil = Me.imports.bumblebeeNvidiaUtil;
|
||||||
const FreonItem = Me.imports.freonItem;
|
const FreonItem = Me.imports.freonItem;
|
||||||
|
|
||||||
const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']);
|
const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']);
|
||||||
@@ -177,6 +178,9 @@ const FreonMenuButton = new Lang.Class({
|
|||||||
case 'aticonfig':
|
case 'aticonfig':
|
||||||
this._utils.gpu = new AticonfigUtil.AticonfigUtil();
|
this._utils.gpu = new AticonfigUtil.AticonfigUtil();
|
||||||
break;
|
break;
|
||||||
|
case 'bumblebee-nvidia-smi':
|
||||||
|
this._utils.gpu = new BumblebeeNvidiaUtil.BumblebeeNvidiaUtil();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -212,6 +216,7 @@ const FreonMenuButton = new Lang.Class({
|
|||||||
|
|
||||||
_onDestroy: function(){
|
_onDestroy: function(){
|
||||||
this._destroyDriveUtility();
|
this._destroyDriveUtility();
|
||||||
|
this._destroyGpuUtility();
|
||||||
Mainloop.source_remove(this._timeoutId);
|
Mainloop.source_remove(this._timeoutId);
|
||||||
|
|
||||||
for each (let signal in this._settingChangedSignals){
|
for each (let signal in this._settingChangedSignals){
|
||||||
@@ -257,18 +262,26 @@ const FreonMenuButton = new Lang.Class({
|
|||||||
let tempInfo = gpuTempInfo.concat(sensorsTempInfo).concat(driveTempInfo);
|
let tempInfo = gpuTempInfo.concat(sensorsTempInfo).concat(driveTempInfo);
|
||||||
|
|
||||||
if (tempInfo.length > 0){
|
if (tempInfo.length > 0){
|
||||||
|
let total = 0;
|
||||||
let sum = 0;
|
let sum = 0;
|
||||||
let max = 0;
|
let max = 0;
|
||||||
for each (let i in tempInfo){
|
for each (let i in tempInfo){
|
||||||
sum += i.temp;
|
if(i.temp !== 'N/A'){
|
||||||
if (i.temp > max)
|
total++;
|
||||||
max = i.temp;
|
sum += i.temp;
|
||||||
|
if (i.temp > max)
|
||||||
|
max = i.temp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let sensors = [];
|
let sensors = [];
|
||||||
|
|
||||||
for each (let i in gpuTempInfo){
|
for each (let i in gpuTempInfo){
|
||||||
sensors.push({type:'gpu-temperature', label: i.label, value:this._formatTemp(i.temp)});
|
sensors.push({
|
||||||
|
type: 'gpu-temperature',
|
||||||
|
label: i.label,
|
||||||
|
value: this._formatTemp(i.temp),
|
||||||
|
displayName: i.displayName});
|
||||||
}
|
}
|
||||||
for each (let i in sensorsTempInfo){
|
for each (let i in sensorsTempInfo){
|
||||||
sensors.push({type:'temperature', label: i.label, value:this._formatTemp(i.temp)});
|
sensors.push({type:'temperature', label: i.label, value:this._formatTemp(i.temp)});
|
||||||
@@ -281,7 +294,7 @@ const FreonMenuButton = new Lang.Class({
|
|||||||
sensors.push({type : 'separator'});
|
sensors.push({type : 'separator'});
|
||||||
|
|
||||||
// Add average and maximum entries
|
// Add average and maximum entries
|
||||||
sensors.push({type:'temperature-average', label:_("Average"), value:this._formatTemp(sum/tempInfo.length)});
|
sensors.push({type:'temperature-average', label:_("Average"), value:this._formatTemp(sum/total)});
|
||||||
sensors.push({type:'temperature-maximum', label:_("Maximum"), value:this._formatTemp(max)});
|
sensors.push({type:'temperature-maximum', label:_("Maximum"), value:this._formatTemp(max)});
|
||||||
|
|
||||||
if(fanInfo.length > 0 || voltageInfo.length > 0)
|
if(fanInfo.length > 0 || voltageInfo.length > 0)
|
||||||
@@ -330,8 +343,11 @@ const FreonMenuButton = new Lang.Class({
|
|||||||
if(item) {
|
if(item) {
|
||||||
if(s.type == 'temperature-group')
|
if(s.type == 'temperature-group')
|
||||||
item.status.text = s.value;
|
item.status.text = s.value;
|
||||||
else
|
else {
|
||||||
item.value = s.value;
|
item.value = s.value;
|
||||||
|
if(s.displayName)
|
||||||
|
item.display_name = s.displayName;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this._needRerender = true;
|
this._needRerender = true;
|
||||||
}
|
}
|
||||||
@@ -399,7 +415,7 @@ const FreonMenuButton = new Lang.Class({
|
|||||||
this._sensorMenuItems['temperature-group'] = temperatureGroup;
|
this._sensorMenuItems['temperature-group'] = temperatureGroup;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let item = new FreonItem.FreonItem(this._sensorIcons[s.type], s.label, s.value);
|
let item = new FreonItem.FreonItem(this._sensorIcons[s.type], s.label, s.value, s.displayName);
|
||||||
item.connect('activate', Lang.bind(this, function (self) {
|
item.connect('activate', Lang.bind(this, function (self) {
|
||||||
let l = this._hotLabels[self.label];
|
let l = this._hotLabels[self.label];
|
||||||
let hotSensors = this._settings.get_strv('hot-sensors');
|
let hotSensors = this._settings.get_strv('hot-sensors');
|
||||||
@@ -489,6 +505,8 @@ const FreonMenuButton = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_formatTemp: function(value) {
|
_formatTemp: function(value) {
|
||||||
|
if(value === null)
|
||||||
|
return 'N/A';
|
||||||
if (this._settings.get_string('unit')=='fahrenheit'){
|
if (this._settings.get_string('unit')=='fahrenheit'){
|
||||||
value = this._toFahrenheit(value);
|
value = this._toFahrenheit(value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,14 +6,15 @@ const FreonItem = new Lang.Class({
|
|||||||
Name: 'FreonItem',
|
Name: 'FreonItem',
|
||||||
Extends: PopupMenu.PopupBaseMenuItem,
|
Extends: PopupMenu.PopupBaseMenuItem,
|
||||||
|
|
||||||
_init: function(gIcon, label, value) {
|
_init: function(gIcon, label, value, displayName) {
|
||||||
this.parent();
|
this.parent();
|
||||||
this._main = false;
|
this._main = false;
|
||||||
this._label = label;
|
this._label = label;
|
||||||
this._gIcon = gIcon;
|
this._gIcon = gIcon;
|
||||||
|
|
||||||
|
this._labelActor = new St.Label({text: displayName ? displayName : label});
|
||||||
this.actor.add(new St.Icon({ style_class: 'popup-menu-icon', gicon : gIcon}));
|
this.actor.add(new St.Icon({ style_class: 'popup-menu-icon', gicon : gIcon}));
|
||||||
this.actor.add(new St.Label({text: label}), {x_fill: true, expand: true});
|
this.actor.add(this._labelActor, {x_fill: true, expand: true});
|
||||||
this._valueLabel = new St.Label({text: value});
|
this._valueLabel = new St.Label({text: value});
|
||||||
this.actor.add(this._valueLabel);
|
this.actor.add(this._valueLabel);
|
||||||
},
|
},
|
||||||
@@ -34,6 +35,10 @@ const FreonItem = new Lang.Class({
|
|||||||
return this._label;
|
return this._label;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
set display_name(text) {
|
||||||
|
return this._labelActor.text = text;
|
||||||
|
},
|
||||||
|
|
||||||
get gicon() {
|
get gicon() {
|
||||||
return this._gIcon;
|
return this._gIcon;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -75,7 +75,11 @@ const FreonPrefsWidget = new GObject.Class({
|
|||||||
});
|
});
|
||||||
|
|
||||||
this._addComboBox({
|
this._addComboBox({
|
||||||
items : {none : 'None', 'nvidia-settings' : 'Nvidia', aticonfig : 'Catalyst'},
|
items : {
|
||||||
|
'none' : _('None'),
|
||||||
|
'nvidia-settings' : _('NVIDIA'),
|
||||||
|
'aticonfig' : _('Catalyst'),
|
||||||
|
'bumblebee-nvidia-smi': _('Bumblebee + NVIDIA') },
|
||||||
key: 'gpu-utility', y : i, x : 2,
|
key: 'gpu-utility', y : i, x : 2,
|
||||||
label: _('Video Card Temperature Utility')
|
label: _('Video Card Temperature Utility')
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user