volume: Update indicator when microphone volume changes

The current microphone indicator only indicates if the microphone is in
use. Users might be also interested if their microphone is recording
or is muted, this commit enables that without opening the pop-up
menu. The microphone icon changes itself, depending on the sensitivity
of the microphone. It behaves similar to the already existing volume
indicator.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2902
This commit is contained in:
fludixx 2020-06-21 02:51:01 +02:00 committed by Florian Müllner
parent 5e66b104dc
commit a368df61ac

View File

@ -62,6 +62,7 @@ var StreamSlider = class {
this._stream = null; this._stream = null;
this._volumeCancellable = null; this._volumeCancellable = null;
this._icons = [];
} }
get stream() { get stream() {
@ -182,24 +183,15 @@ var StreamSlider = class {
if (!this._stream) if (!this._stream)
return null; return null;
let icons = ["audio-volume-muted-symbolic",
"audio-volume-low-symbolic",
"audio-volume-medium-symbolic",
"audio-volume-high-symbolic",
"audio-volume-overamplified-symbolic"];
let volume = this._stream.volume; let volume = this._stream.volume;
let n; let n;
if (this._stream.is_muted || volume <= 0) { if (this._stream.is_muted || volume <= 0) {
n = 0; n = 0;
} else { } else {
n = Math.ceil(3 * volume / this._control.get_vol_max_norm()); n = Math.ceil(3 * volume / this._control.get_vol_max_norm());
if (n < 1) n = Math.clamp(n, 1, this._icons.length - 1);
n = 1;
else if (n > 3)
n = 4;
} }
return icons[n]; return this._icons[n];
} }
getLevel() { getLevel() {
@ -223,6 +215,13 @@ var OutputStreamSlider = class extends StreamSlider {
constructor(control) { constructor(control) {
super(control); super(control);
this._slider.accessible_name = _("Volume"); this._slider.accessible_name = _("Volume");
this._icons = [
'audio-volume-muted-symbolic',
'audio-volume-low-symbolic',
'audio-volume-medium-symbolic',
'audio-volume-high-symbolic',
'audio-volume-overamplified-symbolic',
];
} }
_connectStream(stream) { _connectStream(stream) {
@ -274,6 +273,12 @@ var InputStreamSlider = class extends StreamSlider {
this._control.connect('stream-added', this._maybeShowInput.bind(this)); this._control.connect('stream-added', this._maybeShowInput.bind(this));
this._control.connect('stream-removed', this._maybeShowInput.bind(this)); this._control.connect('stream-removed', this._maybeShowInput.bind(this));
this._icon.icon_name = 'audio-input-microphone-symbolic'; this._icon.icon_name = 'audio-input-microphone-symbolic';
this._icons = [
'microphone-sensitivity-muted-symbolic',
'microphone-sensitivity-low-symbolic',
'microphone-sensitivity-medium-symbolic',
'microphone-sensitivity-high-symbolic',
];
} }
_connectStream(stream) { _connectStream(stream) {
@ -319,7 +324,7 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection {
this._output = new OutputStreamSlider(this._control); this._output = new OutputStreamSlider(this._control);
this._output.connect('stream-updated', () => { this._output.connect('stream-updated', () => {
this.emit('icon-changed'); this.emit('output-icon-changed');
}); });
this.addMenuItem(this._output.item); this.addMenuItem(this._output.item);
@ -327,6 +332,9 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection {
this._input.item.connect('notify::visible', () => { this._input.item.connect('notify::visible', () => {
this.emit('input-visible-changed'); this.emit('input-visible-changed');
}); });
this._input.connect('stream-updated', () => {
this.emit('input-icon-changed');
});
this.addMenuItem(this._input.item); this.addMenuItem(this._input.item);
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
@ -343,7 +351,7 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection {
this._readInput(); this._readInput();
this._readOutput(); this._readOutput();
} else { } else {
this.emit('icon-changed'); this.emit('output-icon-changed');
} }
} }
@ -355,10 +363,14 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection {
this._input.stream = this._control.get_default_source(); this._input.stream = this._control.get_default_source();
} }
getIcon() { getOutputIcon() {
return this._output.getIcon(); return this._output.getIcon();
} }
getInputIcon() {
return this._input.getIcon();
}
getLevel() { getLevel() {
return this._output.getLevel(); return this._output.getLevel();
} }
@ -382,21 +394,24 @@ class Indicator extends PanelMenu.SystemIndicator {
this._control = getMixerControl(); this._control = getMixerControl();
this._volumeMenu = new VolumeMenu(this._control); this._volumeMenu = new VolumeMenu(this._control);
this._volumeMenu.connect('icon-changed', () => { this._volumeMenu.connect('output-icon-changed', () => {
let icon = this._volumeMenu.getIcon(); let icon = this._volumeMenu.getOutputIcon();
if (icon != null) if (icon != null)
this._primaryIndicator.icon_name = icon; this._primaryIndicator.icon_name = icon;
this._primaryIndicator.visible = icon !== null; this._primaryIndicator.visible = icon !== null;
}); });
this._inputIndicator.set({ this._inputIndicator.visible = this._volumeMenu.getInputVisible();
icon_name: 'audio-input-microphone-symbolic',
visible: this._volumeMenu.getInputVisible(),
});
this._volumeMenu.connect('input-visible-changed', () => { this._volumeMenu.connect('input-visible-changed', () => {
this._inputIndicator.visible = this._volumeMenu.getInputVisible(); this._inputIndicator.visible = this._volumeMenu.getInputVisible();
}); });
this._volumeMenu.connect('input-icon-changed', () => {
let icon = this._volumeMenu.getInputIcon();
if (icon !== null)
this._inputIndicator.icon_name = icon;
});
this.menu.addMenuItem(this._volumeMenu); this.menu.addMenuItem(this._volumeMenu);
} }
@ -406,7 +421,7 @@ class Indicator extends PanelMenu.SystemIndicator {
if (result == Clutter.EVENT_PROPAGATE || this.menu.actor.mapped) if (result == Clutter.EVENT_PROPAGATE || this.menu.actor.mapped)
return result; return result;
let gicon = new Gio.ThemedIcon({ name: this._volumeMenu.getIcon() }); let gicon = new Gio.ThemedIcon({ name: this._volumeMenu.getOutputIcon() });
let level = this._volumeMenu.getLevel(); let level = this._volumeMenu.getLevel();
let maxLevel = this._volumeMenu.getMaxLevel(); let maxLevel = this._volumeMenu.getMaxLevel();
Main.osdWindowManager.show(-1, gicon, null, level, maxLevel); Main.osdWindowManager.show(-1, gicon, null, level, maxLevel);