From a368df61ac77d5e223e6e8c3a9e8fca50fe7ac01 Mon Sep 17 00:00:00 2001 From: fludixx Date: Sun, 21 Jun 2020 02:51:01 +0200 Subject: [PATCH] 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 --- js/ui/status/volume.js | 57 ++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/js/ui/status/volume.js b/js/ui/status/volume.js index 64767b848..7b5065871 100644 --- a/js/ui/status/volume.js +++ b/js/ui/status/volume.js @@ -62,6 +62,7 @@ var StreamSlider = class { this._stream = null; this._volumeCancellable = null; + this._icons = []; } get stream() { @@ -182,24 +183,15 @@ var StreamSlider = class { if (!this._stream) 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 n; if (this._stream.is_muted || volume <= 0) { n = 0; } else { n = Math.ceil(3 * volume / this._control.get_vol_max_norm()); - if (n < 1) - n = 1; - else if (n > 3) - n = 4; + n = Math.clamp(n, 1, this._icons.length - 1); } - return icons[n]; + return this._icons[n]; } getLevel() { @@ -223,6 +215,13 @@ var OutputStreamSlider = class extends StreamSlider { constructor(control) { super(control); 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) { @@ -274,6 +273,12 @@ var InputStreamSlider = class extends StreamSlider { this._control.connect('stream-added', this._maybeShowInput.bind(this)); this._control.connect('stream-removed', this._maybeShowInput.bind(this)); 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) { @@ -319,7 +324,7 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection { this._output = new OutputStreamSlider(this._control); this._output.connect('stream-updated', () => { - this.emit('icon-changed'); + this.emit('output-icon-changed'); }); this.addMenuItem(this._output.item); @@ -327,6 +332,9 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection { this._input.item.connect('notify::visible', () => { this.emit('input-visible-changed'); }); + this._input.connect('stream-updated', () => { + this.emit('input-icon-changed'); + }); this.addMenuItem(this._input.item); this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); @@ -343,7 +351,7 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection { this._readInput(); this._readOutput(); } 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(); } - getIcon() { + getOutputIcon() { return this._output.getIcon(); } + getInputIcon() { + return this._input.getIcon(); + } + getLevel() { return this._output.getLevel(); } @@ -382,21 +394,24 @@ class Indicator extends PanelMenu.SystemIndicator { this._control = getMixerControl(); this._volumeMenu = new VolumeMenu(this._control); - this._volumeMenu.connect('icon-changed', () => { - let icon = this._volumeMenu.getIcon(); + this._volumeMenu.connect('output-icon-changed', () => { + let icon = this._volumeMenu.getOutputIcon(); if (icon != null) this._primaryIndicator.icon_name = icon; this._primaryIndicator.visible = icon !== null; }); - this._inputIndicator.set({ - icon_name: 'audio-input-microphone-symbolic', - visible: this._volumeMenu.getInputVisible(), - }); + this._inputIndicator.visible = this._volumeMenu.getInputVisible(); this._volumeMenu.connect('input-visible-changed', () => { 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); } @@ -406,7 +421,7 @@ class Indicator extends PanelMenu.SystemIndicator { if (result == Clutter.EVENT_PROPAGATE || this.menu.actor.mapped) 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 maxLevel = this._volumeMenu.getMaxLevel(); Main.osdWindowManager.show(-1, gicon, null, level, maxLevel);