2011-09-28 09:16:26 -04:00
|
|
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
2019-01-31 09:07:06 -05:00
|
|
|
/* exported Indicator */
|
2010-07-22 20:39:44 -04:00
|
|
|
|
2018-02-23 17:58:22 -05:00
|
|
|
const { Clutter, Gio, GLib, GObject, Gvc, St } = imports.gi;
|
2022-07-04 18:30:44 -04:00
|
|
|
const Signals = imports.misc.signals;
|
2010-07-22 20:39:44 -04:00
|
|
|
|
2017-06-09 10:06:39 -04:00
|
|
|
const Main = imports.ui.main;
|
2010-07-22 20:39:44 -04:00
|
|
|
const PanelMenu = imports.ui.panelMenu;
|
|
|
|
const PopupMenu = imports.ui.popupMenu;
|
2013-04-23 16:57:43 -04:00
|
|
|
const Slider = imports.ui.slider;
|
2010-07-22 20:39:44 -04:00
|
|
|
|
2018-07-31 02:02:04 -04:00
|
|
|
const ALLOW_AMPLIFIED_VOLUME_KEY = 'allow-volume-above-100-percent';
|
|
|
|
|
2021-01-13 16:56:04 -05:00
|
|
|
const VolumeType = {
|
|
|
|
OUTPUT: 0,
|
|
|
|
INPUT: 1,
|
|
|
|
};
|
|
|
|
|
2012-08-26 10:05:46 -04:00
|
|
|
// Each Gvc.MixerControl is a connection to PulseAudio,
|
|
|
|
// so it's better to make it a singleton
|
|
|
|
let _mixerControl;
|
2022-07-15 08:23:23 -04:00
|
|
|
/**
|
|
|
|
* @returns {Gvc.MixerControl} - the mixer control singleton
|
|
|
|
*/
|
2012-08-26 10:05:46 -04:00
|
|
|
function getMixerControl() {
|
|
|
|
if (_mixerControl)
|
|
|
|
return _mixerControl;
|
2010-07-22 20:39:44 -04:00
|
|
|
|
2012-08-26 10:05:46 -04:00
|
|
|
_mixerControl = new Gvc.MixerControl({ name: 'GNOME Shell Volume Control' });
|
|
|
|
_mixerControl.open();
|
|
|
|
|
|
|
|
return _mixerControl;
|
|
|
|
}
|
2010-07-22 20:39:44 -04:00
|
|
|
|
2022-07-04 18:30:44 -04:00
|
|
|
var StreamSlider = class extends Signals.EventEmitter {
|
2017-10-30 21:19:44 -04:00
|
|
|
constructor(control) {
|
2022-07-04 18:30:44 -04:00
|
|
|
super();
|
|
|
|
|
2012-12-19 21:57:26 -05:00
|
|
|
this._control = control;
|
2012-08-26 10:05:46 -04:00
|
|
|
|
2013-04-23 16:57:43 -04:00
|
|
|
this.item = new PopupMenu.PopupBaseMenuItem({ activate: false });
|
2022-05-10 20:34:21 -04:00
|
|
|
this.item.hide();
|
2012-10-18 13:42:17 -04:00
|
|
|
|
2018-02-23 17:58:22 -05:00
|
|
|
this._inDrag = false;
|
|
|
|
this._notifyVolumeChangeId = 0;
|
|
|
|
|
2013-04-23 16:57:43 -04:00
|
|
|
this._slider = new Slider.Slider(0);
|
2018-07-31 02:02:04 -04:00
|
|
|
|
2022-07-15 08:20:28 -04:00
|
|
|
this._soundSettings = new Gio.Settings({
|
|
|
|
schema_id: 'org.gnome.desktop.sound',
|
|
|
|
});
|
|
|
|
this._soundSettings.connect(`changed::${ALLOW_AMPLIFIED_VOLUME_KEY}`,
|
|
|
|
() => this._amplifySettingsChanged());
|
2018-07-31 02:02:04 -04:00
|
|
|
this._amplifySettingsChanged();
|
|
|
|
|
2019-09-05 05:45:37 -04:00
|
|
|
this._sliderChangedId = this._slider.connect('notify::value',
|
2022-07-15 08:20:28 -04:00
|
|
|
() => this._sliderChanged());
|
2018-02-23 17:58:22 -05:00
|
|
|
this._slider.connect('drag-begin', () => (this._inDrag = true));
|
|
|
|
this._slider.connect('drag-end', () => {
|
|
|
|
this._inDrag = false;
|
|
|
|
this._notifyVolumeChange();
|
|
|
|
});
|
2010-07-22 20:39:44 -04:00
|
|
|
|
2013-04-23 16:57:43 -04:00
|
|
|
this._icon = new St.Icon({ style_class: 'popup-menu-icon' });
|
2019-04-12 17:00:49 -04:00
|
|
|
this.item.add(this._icon);
|
2019-10-21 14:44:00 -04:00
|
|
|
this.item.add_child(this._slider);
|
2022-07-15 08:20:28 -04:00
|
|
|
this.item.connect('button-press-event',
|
|
|
|
(actor, event) => this._slider.startDragging(event));
|
|
|
|
this.item.connect('key-press-event',
|
|
|
|
(actor, event) => this._slider.emit('key-press-event', event));
|
|
|
|
this.item.connect('scroll-event',
|
|
|
|
(actor, event) => this._slider.emit('scroll-event', event));
|
2013-06-11 23:39:56 -04:00
|
|
|
|
2012-12-19 21:57:26 -05:00
|
|
|
this._stream = null;
|
2018-12-13 14:33:45 -05:00
|
|
|
this._volumeCancellable = null;
|
2020-06-20 20:51:01 -04:00
|
|
|
this._icons = [];
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2010-07-22 20:39:44 -04:00
|
|
|
|
2012-12-19 21:57:26 -05:00
|
|
|
get stream() {
|
|
|
|
return this._stream;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-09-04 11:55:26 -04:00
|
|
|
|
2012-12-19 21:57:26 -05:00
|
|
|
set stream(stream) {
|
2019-08-19 20:51:42 -04:00
|
|
|
if (this._stream)
|
2012-12-19 21:57:26 -05:00
|
|
|
this._disconnectStream(this._stream);
|
|
|
|
|
|
|
|
this._stream = stream;
|
|
|
|
|
|
|
|
if (this._stream) {
|
|
|
|
this._connectStream(this._stream);
|
|
|
|
this._updateVolume();
|
|
|
|
} else {
|
|
|
|
this.emit('stream-updated');
|
|
|
|
}
|
|
|
|
|
|
|
|
this._updateVisibility();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-19 21:57:26 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_disconnectStream(stream) {
|
2021-08-15 18:36:59 -04:00
|
|
|
stream.disconnectObject(this);
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-19 21:57:26 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_connectStream(stream) {
|
2021-08-15 18:36:59 -04:00
|
|
|
stream.connectObject(
|
|
|
|
'notify::is-muted', this._updateVolume.bind(this),
|
|
|
|
'notify::volume', this._updateVolume.bind(this), this);
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-19 21:57:26 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_shouldBeVisible() {
|
2012-12-19 21:57:26 -05:00
|
|
|
return this._stream != null;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-19 21:57:26 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_updateVisibility() {
|
2012-12-19 21:57:26 -05:00
|
|
|
let visible = this._shouldBeVisible();
|
2019-04-12 17:00:49 -04:00
|
|
|
this.item.visible = visible;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-05-22 18:27:06 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
scroll(event) {
|
2013-11-29 13:17:34 -05:00
|
|
|
return this._slider.scroll(event);
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2010-10-20 15:53:23 -04:00
|
|
|
|
2019-07-25 12:53:00 -04:00
|
|
|
_sliderChanged() {
|
2012-12-19 21:57:26 -05:00
|
|
|
if (!this._stream)
|
|
|
|
return;
|
|
|
|
|
2019-07-25 12:53:00 -04:00
|
|
|
let value = this._slider.value;
|
2012-12-19 21:57:26 -05:00
|
|
|
let volume = value * this._control.get_vol_max_norm();
|
|
|
|
let prevMuted = this._stream.is_muted;
|
2018-02-23 17:58:22 -05:00
|
|
|
let prevVolume = this._stream.volume;
|
2012-12-19 21:57:26 -05:00
|
|
|
if (volume < 1) {
|
|
|
|
this._stream.volume = 0;
|
|
|
|
if (!prevMuted)
|
|
|
|
this._stream.change_is_muted(true);
|
2011-03-28 10:10:11 -04:00
|
|
|
} else {
|
2012-12-19 21:57:26 -05:00
|
|
|
this._stream.volume = volume;
|
|
|
|
if (prevMuted)
|
|
|
|
this._stream.change_is_muted(false);
|
|
|
|
}
|
|
|
|
this._stream.push_volume();
|
2018-02-23 17:58:22 -05:00
|
|
|
|
2018-02-23 17:58:22 -05:00
|
|
|
let volumeChanged = this._stream.volume !== prevVolume;
|
|
|
|
if (volumeChanged && !this._notifyVolumeChangeId && !this._inDrag) {
|
2018-02-23 17:58:22 -05:00
|
|
|
this._notifyVolumeChangeId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 30, () => {
|
|
|
|
this._notifyVolumeChange();
|
|
|
|
this._notifyVolumeChangeId = 0;
|
|
|
|
return GLib.SOURCE_REMOVE;
|
|
|
|
});
|
|
|
|
GLib.Source.set_name_by_id(this._notifyVolumeChangeId,
|
|
|
|
'[gnome-shell] this._notifyVolumeChangeId');
|
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-19 21:57:26 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_notifyVolumeChange() {
|
2018-12-13 14:33:45 -05:00
|
|
|
if (this._volumeCancellable)
|
|
|
|
this._volumeCancellable.cancel();
|
2020-03-27 22:37:50 -04:00
|
|
|
this._volumeCancellable = null;
|
|
|
|
|
|
|
|
if (this._stream.state === Gvc.MixerStreamState.RUNNING)
|
|
|
|
return; // feedback not necessary while playing
|
2018-12-13 14:33:45 -05:00
|
|
|
|
|
|
|
this._volumeCancellable = new Gio.Cancellable();
|
|
|
|
let player = global.display.get_sound_player();
|
|
|
|
player.play_from_theme('audio-volume-change',
|
2022-07-15 08:20:28 -04:00
|
|
|
_('Volume changed'), this._volumeCancellable);
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-21 13:28:40 -05:00
|
|
|
|
2019-09-05 05:45:37 -04:00
|
|
|
_changeSlider(value) {
|
2019-10-30 13:11:56 -04:00
|
|
|
this._slider.block_signal_handler(this._sliderChangedId);
|
2019-09-05 05:45:37 -04:00
|
|
|
this._slider.value = value;
|
2019-10-30 13:11:56 -04:00
|
|
|
this._slider.unblock_signal_handler(this._sliderChangedId);
|
2019-09-05 05:45:37 -04:00
|
|
|
}
|
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_updateVolume() {
|
2012-12-19 21:57:26 -05:00
|
|
|
let muted = this._stream.is_muted;
|
2019-09-05 05:45:37 -04:00
|
|
|
this._changeSlider(muted
|
2019-08-19 15:38:51 -04:00
|
|
|
? 0 : this._stream.volume / this._control.get_vol_max_norm());
|
2012-12-19 21:57:26 -05:00
|
|
|
this.emit('stream-updated');
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-19 21:57:26 -05:00
|
|
|
|
2018-07-31 02:02:04 -04:00
|
|
|
_amplifySettingsChanged() {
|
|
|
|
this._allowAmplified = this._soundSettings.get_boolean(ALLOW_AMPLIFIED_VOLUME_KEY);
|
|
|
|
|
2019-08-07 08:55:49 -04:00
|
|
|
this._slider.maximum_value = this._allowAmplified
|
2019-02-02 11:50:04 -05:00
|
|
|
? this.getMaxLevel() : 1;
|
2018-07-31 02:02:04 -04:00
|
|
|
|
|
|
|
if (this._stream)
|
|
|
|
this._updateVolume();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2018-07-31 02:02:04 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
getIcon() {
|
2012-12-19 21:57:26 -05:00
|
|
|
if (!this._stream)
|
|
|
|
return null;
|
|
|
|
|
|
|
|
let volume = this._stream.volume;
|
2018-02-09 09:10:16 -05:00
|
|
|
let n;
|
2012-12-19 21:57:26 -05:00
|
|
|
if (this._stream.is_muted || volume <= 0) {
|
2018-02-09 09:10:16 -05:00
|
|
|
n = 0;
|
2012-12-19 21:57:26 -05:00
|
|
|
} else {
|
2018-02-09 09:10:16 -05:00
|
|
|
n = Math.ceil(3 * volume / this._control.get_vol_max_norm());
|
2020-06-20 20:51:01 -04:00
|
|
|
n = Math.clamp(n, 1, this._icons.length - 1);
|
2011-03-28 10:10:11 -04:00
|
|
|
}
|
2020-06-20 20:51:01 -04:00
|
|
|
return this._icons[n];
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2017-06-09 10:06:39 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
getLevel() {
|
2017-06-09 10:06:39 -04:00
|
|
|
if (!this._stream)
|
|
|
|
return null;
|
|
|
|
|
2019-02-02 11:50:04 -05:00
|
|
|
return this._stream.volume / this._control.get_vol_max_norm();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2018-07-31 02:02:04 -04:00
|
|
|
|
|
|
|
getMaxLevel() {
|
|
|
|
let maxVolume = this._control.get_vol_max_norm();
|
|
|
|
if (this._allowAmplified)
|
|
|
|
maxVolume = this._control.get_vol_max_amplified();
|
|
|
|
|
2019-02-02 11:50:04 -05:00
|
|
|
return maxVolume / this._control.get_vol_max_norm();
|
2012-12-19 21:57:26 -05:00
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
};
|
2012-12-19 21:57:26 -05:00
|
|
|
|
2017-10-30 21:19:44 -04:00
|
|
|
var OutputStreamSlider = class extends StreamSlider {
|
|
|
|
constructor(control) {
|
|
|
|
super(control);
|
2019-07-25 12:53:00 -04:00
|
|
|
this._slider.accessible_name = _("Volume");
|
2020-06-20 20:51:01 -04:00
|
|
|
this._icons = [
|
|
|
|
'audio-volume-muted-symbolic',
|
|
|
|
'audio-volume-low-symbolic',
|
|
|
|
'audio-volume-medium-symbolic',
|
|
|
|
'audio-volume-high-symbolic',
|
|
|
|
'audio-volume-overamplified-symbolic',
|
|
|
|
];
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2013-08-21 12:24:30 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_connectStream(stream) {
|
2017-10-30 21:19:44 -04:00
|
|
|
super._connectStream(stream);
|
2021-08-15 18:36:59 -04:00
|
|
|
stream.connectObject('notify::port',
|
|
|
|
this._portChanged.bind(this), this);
|
2012-12-19 21:57:26 -05:00
|
|
|
this._portChanged();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2010-07-22 20:39:44 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_findHeadphones(sink) {
|
2012-10-18 13:42:17 -04:00
|
|
|
// 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
|
2013-02-01 14:19:02 -05:00
|
|
|
if (sink.get_ports().length > 0)
|
2018-07-14 16:56:22 -04:00
|
|
|
return sink.get_port().port.includes('headphone');
|
2012-10-18 13:42:17 -04:00
|
|
|
|
|
|
|
return false;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-10-18 13:42:17 -04:00
|
|
|
|
2022-07-15 12:15:13 -04:00
|
|
|
_portChanged() {
|
|
|
|
const hasHeadphones = this._findHeadphones(this._stream);
|
|
|
|
if (hasHeadphones === this._hasHeadphones)
|
|
|
|
return;
|
|
|
|
|
|
|
|
this._hasHeadphones = hasHeadphones;
|
2019-08-19 15:38:51 -04:00
|
|
|
this._icon.icon_name = this._hasHeadphones
|
2019-08-19 15:33:15 -04:00
|
|
|
? 'audio-headphones-symbolic'
|
2019-08-19 15:38:51 -04:00
|
|
|
: 'audio-speakers-symbolic';
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
|
|
|
};
|
2012-12-19 21:57:26 -05:00
|
|
|
|
2017-10-30 21:19:44 -04:00
|
|
|
var InputStreamSlider = class extends StreamSlider {
|
|
|
|
constructor(control) {
|
|
|
|
super(control);
|
2019-07-25 12:53:00 -04:00
|
|
|
this._slider.accessible_name = _("Microphone");
|
2017-12-01 19:27:35 -05:00
|
|
|
this._control.connect('stream-added', this._maybeShowInput.bind(this));
|
|
|
|
this._control.connect('stream-removed', this._maybeShowInput.bind(this));
|
2013-04-23 16:57:43 -04:00
|
|
|
this._icon.icon_name = 'audio-input-microphone-symbolic';
|
2020-06-20 20:51:01 -04:00
|
|
|
this._icons = [
|
|
|
|
'microphone-sensitivity-muted-symbolic',
|
|
|
|
'microphone-sensitivity-low-symbolic',
|
|
|
|
'microphone-sensitivity-medium-symbolic',
|
|
|
|
'microphone-sensitivity-high-symbolic',
|
|
|
|
];
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2010-07-22 20:39:44 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_connectStream(stream) {
|
2017-10-30 21:19:44 -04:00
|
|
|
super._connectStream(stream);
|
2012-12-19 21:57:26 -05:00
|
|
|
this._maybeShowInput();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2010-07-22 20:39:44 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_maybeShowInput() {
|
2010-07-22 20:39:44 -04:00
|
|
|
// only show input widgets if any application is recording audio
|
|
|
|
let showInput = false;
|
2019-09-14 08:33:09 -04:00
|
|
|
if (this._stream) {
|
|
|
|
// skip gnome-volume-control and pavucontrol which appear
|
|
|
|
// as recording because they show the input level
|
|
|
|
let skippedApps = [
|
|
|
|
'org.gnome.VolumeControl',
|
2019-08-20 17:43:54 -04:00
|
|
|
'org.PulseAudio.pavucontrol',
|
2019-09-14 08:33:09 -04:00
|
|
|
];
|
|
|
|
|
2022-07-15 08:20:28 -04:00
|
|
|
showInput = this._control.get_source_outputs().some(
|
|
|
|
output => !skippedApps.includes(output.get_application_id()));
|
2010-07-22 20:39:44 -04:00
|
|
|
}
|
2012-03-16 18:53:14 -04:00
|
|
|
|
2012-12-19 21:57:26 -05:00
|
|
|
this._showInput = showInput;
|
|
|
|
this._updateVisibility();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2010-07-22 20:39:44 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_shouldBeVisible() {
|
2017-10-30 21:19:44 -04:00
|
|
|
return super._shouldBeVisible() && this._showInput;
|
2012-12-19 21:57:26 -05:00
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
};
|
2012-12-19 21:57:26 -05:00
|
|
|
|
2017-10-30 21:19:44 -04:00
|
|
|
var VolumeMenu = class extends PopupMenu.PopupMenuSection {
|
|
|
|
constructor(control) {
|
|
|
|
super();
|
2012-12-19 21:57:26 -05:00
|
|
|
|
|
|
|
this.hasHeadphones = false;
|
|
|
|
|
|
|
|
this._control = control;
|
2017-12-01 19:27:35 -05:00
|
|
|
this._control.connect('state-changed', this._onControlStateChanged.bind(this));
|
|
|
|
this._control.connect('default-sink-changed', this._readOutput.bind(this));
|
|
|
|
this._control.connect('default-source-changed', this._readInput.bind(this));
|
2012-12-19 21:57:26 -05:00
|
|
|
|
2013-04-23 16:57:43 -04:00
|
|
|
this._output = new OutputStreamSlider(this._control);
|
2022-07-15 08:20:28 -04:00
|
|
|
this._output.connect('stream-updated',
|
|
|
|
() => this.emit('output-icon-changed'));
|
2012-12-19 21:57:26 -05:00
|
|
|
this.addMenuItem(this._output.item);
|
|
|
|
|
2013-04-23 16:57:43 -04:00
|
|
|
this._input = new InputStreamSlider(this._control);
|
2022-07-15 08:20:28 -04:00
|
|
|
this._input.item.connect('notify::visible',
|
|
|
|
() => this.emit('input-visible-changed'));
|
|
|
|
this._input.connect('stream-updated',
|
|
|
|
() => this.emit('input-icon-changed'));
|
2012-12-19 21:57:26 -05:00
|
|
|
this.addMenuItem(this._input.item);
|
|
|
|
|
|
|
|
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
|
|
|
|
|
|
|
this._onControlStateChanged();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2010-07-22 20:39:44 -04:00
|
|
|
|
2021-01-13 16:56:04 -05:00
|
|
|
scroll(type, event) {
|
|
|
|
return type === VolumeType.INPUT
|
|
|
|
? this._input.scroll(event)
|
|
|
|
: this._output.scroll(event);
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-19 22:02:04 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_onControlStateChanged() {
|
2012-12-19 21:57:26 -05:00
|
|
|
if (this._control.get_state() == Gvc.MixerControlState.READY) {
|
|
|
|
this._readInput();
|
|
|
|
this._readOutput();
|
2012-12-19 22:02:04 -05:00
|
|
|
} else {
|
2020-06-20 20:51:01 -04:00
|
|
|
this.emit('output-icon-changed');
|
2012-12-19 22:02:04 -05:00
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-19 22:02:04 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_readOutput() {
|
2012-12-19 21:57:26 -05:00
|
|
|
this._output.stream = this._control.get_default_sink();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-19 21:57:26 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_readInput() {
|
2012-12-19 21:57:26 -05:00
|
|
|
this._input.stream = this._control.get_default_source();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-19 21:57:26 -05:00
|
|
|
|
2021-01-13 16:56:04 -05:00
|
|
|
getIcon(type) {
|
|
|
|
return type === VolumeType.INPUT
|
|
|
|
? this._input.getIcon()
|
|
|
|
: this._output.getIcon();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2017-06-09 10:06:39 -04:00
|
|
|
|
2021-01-13 16:56:04 -05:00
|
|
|
getLevel(type) {
|
|
|
|
return type === VolumeType.INPUT
|
|
|
|
? this._input.getLevel()
|
|
|
|
: this._output.getLevel();
|
2020-06-20 20:51:01 -04:00
|
|
|
}
|
|
|
|
|
2021-01-13 16:56:04 -05:00
|
|
|
getMaxLevel(type) {
|
|
|
|
return type === VolumeType.INPUT
|
|
|
|
? this._input.getMaxLevel()
|
|
|
|
: this._output.getMaxLevel();
|
2012-08-26 10:05:46 -04:00
|
|
|
}
|
2019-09-14 08:41:08 -04:00
|
|
|
|
|
|
|
getInputVisible() {
|
|
|
|
return this._input.item.visible;
|
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
};
|
2012-08-26 10:05:46 -04:00
|
|
|
|
2019-10-28 14:35:33 -04:00
|
|
|
var Indicator = GObject.registerClass(
|
|
|
|
class Indicator extends PanelMenu.SystemIndicator {
|
2019-07-16 05:24:13 -04:00
|
|
|
_init() {
|
|
|
|
super._init();
|
2013-06-06 17:27:25 -04:00
|
|
|
|
2013-07-19 06:05:47 -04:00
|
|
|
this._primaryIndicator = this._addIndicator();
|
2019-09-14 08:41:08 -04:00
|
|
|
this._inputIndicator = this._addIndicator();
|
2012-08-26 10:05:46 -04:00
|
|
|
|
2021-01-13 16:56:04 -05:00
|
|
|
this._primaryIndicator.reactive = true;
|
|
|
|
this._inputIndicator.reactive = true;
|
|
|
|
|
|
|
|
this._primaryIndicator.connect('scroll-event',
|
|
|
|
(actor, event) => this._handleScrollEvent(VolumeType.OUTPUT, event));
|
|
|
|
this._inputIndicator.connect('scroll-event',
|
|
|
|
(actor, event) => this._handleScrollEvent(VolumeType.INPUT, event));
|
|
|
|
|
2012-08-26 10:05:46 -04:00
|
|
|
this._control = getMixerControl();
|
|
|
|
this._volumeMenu = new VolumeMenu(this._control);
|
2020-06-20 20:51:01 -04:00
|
|
|
this._volumeMenu.connect('output-icon-changed', () => {
|
2021-01-13 16:56:04 -05:00
|
|
|
let icon = this._volumeMenu.getIcon(VolumeType.OUTPUT);
|
2013-06-06 17:27:25 -04:00
|
|
|
|
2019-09-14 08:41:08 -04:00
|
|
|
if (icon != null)
|
2013-06-06 17:27:25 -04:00
|
|
|
this._primaryIndicator.icon_name = icon;
|
2019-09-14 08:41:08 -04:00
|
|
|
this._primaryIndicator.visible = icon !== null;
|
|
|
|
});
|
|
|
|
|
2020-06-20 20:51:01 -04:00
|
|
|
this._inputIndicator.visible = this._volumeMenu.getInputVisible();
|
2019-09-14 08:41:08 -04:00
|
|
|
this._volumeMenu.connect('input-visible-changed', () => {
|
|
|
|
this._inputIndicator.visible = this._volumeMenu.getInputVisible();
|
2017-10-30 20:38:18 -04:00
|
|
|
});
|
2020-06-20 20:51:01 -04:00
|
|
|
this._volumeMenu.connect('input-icon-changed', () => {
|
2021-01-13 16:56:04 -05:00
|
|
|
let icon = this._volumeMenu.getIcon(VolumeType.INPUT);
|
2020-06-20 20:51:01 -04:00
|
|
|
|
|
|
|
if (icon !== null)
|
|
|
|
this._inputIndicator.icon_name = icon;
|
|
|
|
});
|
2012-08-26 10:05:46 -04:00
|
|
|
|
|
|
|
this.menu.addMenuItem(this._volumeMenu);
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-08-26 10:05:46 -04:00
|
|
|
|
2021-01-13 16:56:04 -05:00
|
|
|
_handleScrollEvent(type, event) {
|
|
|
|
const result = this._volumeMenu.scroll(type, event);
|
2017-06-09 10:06:39 -04:00
|
|
|
if (result == Clutter.EVENT_PROPAGATE || this.menu.actor.mapped)
|
|
|
|
return result;
|
|
|
|
|
2021-01-13 16:56:04 -05:00
|
|
|
const gicon = new Gio.ThemedIcon({ name: this._volumeMenu.getIcon(type) });
|
|
|
|
const level = this._volumeMenu.getLevel(type);
|
|
|
|
const maxLevel = this._volumeMenu.getMaxLevel(type);
|
2018-07-31 02:02:04 -04:00
|
|
|
Main.osdWindowManager.show(-1, gicon, null, level, maxLevel);
|
2017-06-09 10:06:39 -04:00
|
|
|
return result;
|
2010-07-22 20:39:44 -04:00
|
|
|
}
|
2019-07-16 05:24:13 -04:00
|
|
|
});
|