gnome-shell/js/ui/audioDeviceSelection.js
Florian Müllner d3d165243c cleanup: Use non-deprecated key symbols
Clutter originally cluttered its namespace with key symbols, before
prefixing all symbols with KEY. We still use the unprefixed symbols
occasionally, replace them so mutter can drop the deprecated symbols.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/808
2019-11-06 09:42:57 +01:00

195 lines
6.4 KiB
JavaScript

/* exported AudioDeviceSelectionDBus */
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog;
const { loadInterfaceXML } = imports.misc.fileUtils;
var AudioDevice = {
HEADPHONES: 1 << 0,
HEADSET: 1 << 1,
MICROPHONE: 1 << 2
};
const AudioDeviceSelectionIface = loadInterfaceXML('org.gnome.Shell.AudioDeviceSelection');
var AudioDeviceSelectionDialog = GObject.registerClass({
Signals: { 'device-selected': { param_types: [GObject.TYPE_UINT] } }
}, class AudioDeviceSelectionDialog extends ModalDialog.ModalDialog {
_init(devices) {
super._init({ styleClass: 'audio-device-selection-dialog' });
this._deviceItems = {};
this._buildLayout();
if (devices & AudioDevice.HEADPHONES)
this._addDevice(AudioDevice.HEADPHONES);
if (devices & AudioDevice.HEADSET)
this._addDevice(AudioDevice.HEADSET);
if (devices & AudioDevice.MICROPHONE)
this._addDevice(AudioDevice.MICROPHONE);
if (this._selectionBox.get_n_children() < 2)
throw new Error('Too few devices for a selection');
}
_buildLayout() {
let title = new St.Label({ style_class: 'audio-selection-title',
text: _("Select Audio Device"),
x_align: Clutter.ActorAlign.CENTER });
this.contentLayout.style_class = 'audio-selection-content';
this.contentLayout.add(title);
this._selectionBox = new St.BoxLayout({
style_class: 'audio-selection-box',
x_expand: true,
});
this.contentLayout.add_child(this._selectionBox);
if (Main.sessionMode.allowSettings)
this.addButton({ action: this._openSettings.bind(this),
label: _("Sound Settings") });
this.addButton({ action: this.close.bind(this),
label: _("Cancel"),
key: Clutter.KEY_Escape });
}
_getDeviceLabel(device) {
switch (device) {
case AudioDevice.HEADPHONES:
return _("Headphones");
case AudioDevice.HEADSET:
return _("Headset");
case AudioDevice.MICROPHONE:
return _("Microphone");
default:
return null;
}
}
_getDeviceIcon(device) {
switch (device) {
case AudioDevice.HEADPHONES:
return 'audio-headphones-symbolic';
case AudioDevice.HEADSET:
return 'audio-headset-symbolic';
case AudioDevice.MICROPHONE:
return 'audio-input-microphone-symbolic';
default:
return null;
}
}
_addDevice(device) {
let box = new St.BoxLayout({ style_class: 'audio-selection-device-box',
vertical: true });
box.connect('notify::height', () => {
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
box.width = box.height;
return GLib.SOURCE_REMOVE;
});
});
let icon = new St.Icon({ style_class: 'audio-selection-device-icon',
icon_name: this._getDeviceIcon(device) });
box.add(icon);
let label = new St.Label({ style_class: 'audio-selection-device-label',
text: this._getDeviceLabel(device),
x_align: Clutter.ActorAlign.CENTER });
box.add(label);
let button = new St.Button({ style_class: 'audio-selection-device',
can_focus: true,
child: box });
this._selectionBox.add(button);
button.connect('clicked', () => {
this.emit('device-selected', device);
this.close();
Main.overview.hide();
});
}
_openSettings() {
let desktopFile = 'gnome-sound-panel.desktop';
let app = Shell.AppSystem.get_default().lookup_app(desktopFile);
if (!app) {
log(`Settings panel for desktop file ${desktopFile} could not be loaded!`);
return;
}
this.close();
Main.overview.hide();
app.activate();
}
});
var AudioDeviceSelectionDBus = class AudioDeviceSelectionDBus {
constructor() {
this._audioSelectionDialog = null;
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(AudioDeviceSelectionIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/AudioDeviceSelection');
Gio.DBus.session.own_name('org.gnome.Shell.AudioDeviceSelection', Gio.BusNameOwnerFlags.REPLACE, null, null);
}
_onDialogClosed() {
this._audioSelectionDialog = null;
}
_onDeviceSelected(dialog, device) {
let connection = this._dbusImpl.get_connection();
let info = this._dbusImpl.get_info();
let deviceName = Object.keys(AudioDevice).filter(
dev => AudioDevice[dev] == device
)[0].toLowerCase();
connection.emit_signal(this._audioSelectionDialog._sender,
this._dbusImpl.get_object_path(),
info ? info.name : null,
'DeviceSelected',
GLib.Variant.new('(s)', [deviceName]));
}
OpenAsync(params, invocation) {
if (this._audioSelectionDialog) {
invocation.return_value(null);
return;
}
let [deviceNames] = params;
let devices = 0;
deviceNames.forEach(n => (devices |= AudioDevice[n.toUpperCase()]));
let dialog;
try {
dialog = new AudioDeviceSelectionDialog(devices);
} catch (e) {
invocation.return_value(null);
return;
}
dialog._sender = invocation.get_sender();
dialog.connect('closed', this._onDialogClosed.bind(this));
dialog.connect('device-selected',
this._onDeviceSelected.bind(this));
dialog.open();
this._audioSelectionDialog = dialog;
invocation.return_value(null);
}
CloseAsync(params, invocation) {
if (this._audioSelectionDialog &&
this._audioSelectionDialog._sender == invocation.get_sender())
this._audioSelectionDialog.close();
invocation.return_value(null);
}
};