VolumeMenu: show headphone icon when headphones are plugged in
This will show the user where sound will come out, and should help if he forgets them plugged, or forgets to plug them before playing music. https://bugzilla.gnome.org/show_bug.cgi?id=675902
This commit is contained in:
parent
3af9f636af
commit
784b04b191
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
const Gvc = imports.gi.Gvc;
|
const Gvc = imports.gi.Gvc;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
|
||||||
@ -32,6 +33,8 @@ const VolumeMenu = new Lang.Class({
|
|||||||
_init: function(control) {
|
_init: function(control) {
|
||||||
this.parent();
|
this.parent();
|
||||||
|
|
||||||
|
this.hasHeadphones = false;
|
||||||
|
|
||||||
this._control = control;
|
this._control = control;
|
||||||
this._control.connect('state-changed', Lang.bind(this, this._onControlStateChanged));
|
this._control.connect('state-changed', Lang.bind(this, this._onControlStateChanged));
|
||||||
this._control.connect('default-sink-changed', Lang.bind(this, this._readOutput));
|
this._control.connect('default-sink-changed', Lang.bind(this, this._readOutput));
|
||||||
@ -98,20 +101,47 @@ const VolumeMenu = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_findHeadphones: function(sink) {
|
||||||
|
// This only works for external headphones (e.g. bluetooth)
|
||||||
|
if (sink.get_form_factor() == 'headset' ||
|
||||||
|
sink.get_form_factor() == 'headphone')
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// a bit hackish, but ALSA/PulseAudio have a number
|
||||||
|
// of different identifiers for headphones, and I could
|
||||||
|
// not find the complete list
|
||||||
|
let port = sink.get_port();
|
||||||
|
if (port)
|
||||||
|
return port.port.indexOf('headphone') >= 0;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_portChanged: function() {
|
||||||
|
this.hasHeadphones = this._findHeadphones(this._output);
|
||||||
|
this.emit('headphones-changed');
|
||||||
|
},
|
||||||
|
|
||||||
_readOutput: function() {
|
_readOutput: function() {
|
||||||
if (this._outputVolumeId) {
|
if (this._outputVolumeId) {
|
||||||
this._output.disconnect(this._outputVolumeId);
|
this._output.disconnect(this._outputVolumeId);
|
||||||
this._output.disconnect(this._outputMutedId);
|
this._output.disconnect(this._outputMutedId);
|
||||||
|
this._output.disconnect(this._outputPortId);
|
||||||
this._outputVolumeId = 0;
|
this._outputVolumeId = 0;
|
||||||
this._outputMutedId = 0;
|
this._outputMutedId = 0;
|
||||||
|
this._outputPortId = 0;
|
||||||
}
|
}
|
||||||
this._output = this._control.get_default_sink();
|
this._output = this._control.get_default_sink();
|
||||||
if (this._output) {
|
if (this._output) {
|
||||||
this._outputMutedId = this._output.connect('notify::is-muted', Lang.bind(this, this._mutedChanged, '_output'));
|
this._outputMutedId = this._output.connect('notify::is-muted', Lang.bind(this, this._mutedChanged, '_output'));
|
||||||
this._outputVolumeId = this._output.connect('notify::volume', Lang.bind(this, this._volumeChanged, '_output'));
|
this._outputVolumeId = this._output.connect('notify::volume', Lang.bind(this, this._volumeChanged, '_output'));
|
||||||
|
this._outputPortId = this._output.connect('notify::port', Lang.bind(this, this._portChanged));
|
||||||
|
|
||||||
this._mutedChanged(null, null, '_output');
|
this._mutedChanged(null, null, '_output');
|
||||||
this._volumeChanged(null, null, '_output');
|
this._volumeChanged(null, null, '_output');
|
||||||
|
this._portChanged();
|
||||||
} else {
|
} else {
|
||||||
|
this.hasHeadphones = false;
|
||||||
this._outputSlider.setValue(0);
|
this._outputSlider.setValue(0);
|
||||||
this.emit('icon-changed', 'audio-volume-muted-symbolic');
|
this.emit('icon-changed', 'audio-volume-muted-symbolic');
|
||||||
}
|
}
|
||||||
@ -227,6 +257,12 @@ const Indicator = new Lang.Class({
|
|||||||
this.setIcon(icon);
|
this.setIcon(icon);
|
||||||
this._syncVisibility();
|
this._syncVisibility();
|
||||||
}));
|
}));
|
||||||
|
this._volumeMenu.connect('headphones-changed', Lang.bind(this, function() {
|
||||||
|
this._syncVisibility();
|
||||||
|
}));
|
||||||
|
|
||||||
|
this._headphoneIcon = this.addIcon(new Gio.ThemedIcon({ name: 'headphones-symbolic' }));
|
||||||
|
this._headphoneIcon.visible = false;
|
||||||
|
|
||||||
this.menu.addMenuItem(this._volumeMenu);
|
this.menu.addMenuItem(this._volumeMenu);
|
||||||
|
|
||||||
@ -239,6 +275,7 @@ const Indicator = new Lang.Class({
|
|||||||
_syncVisibility: function() {
|
_syncVisibility: function() {
|
||||||
this.actor.visible = this._hasPulseAudio;
|
this.actor.visible = this._hasPulseAudio;
|
||||||
this.mainIcon.visible = this._hasPulseAudio;
|
this.mainIcon.visible = this._hasPulseAudio;
|
||||||
|
this._headphoneIcon.visible = this._hasPulseAudio && this._volumeMenu.hasHeadphones;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onScrollEvent: function(actor, event) {
|
_onScrollEvent: function(actor, event) {
|
||||||
|
Loading…
Reference in New Issue
Block a user