Skip to content

Commit 958f274

Browse files
authored
[email protected]: Allow using PulseAudio (#6954)
1 parent 995c1b5 commit 958f274

File tree

2 files changed

+65
-35
lines changed

2 files changed

+65
-35
lines changed

[email protected]/files/[email protected]/applet.js

+58-35
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const APPNAME = "MuteToggler";
1616
const UUID = APPNAME + "@jebeaudet.com";
1717
const HOME_DIR = GLib.get_home_dir();
1818

19-
var VERBOSE = true; // VERBOSE value will be changed according to this applet settings.
19+
let VERBOSE = true; // VERBOSE value will be changed according to this applet settings.
2020

2121
const POTENTIAL_INPUTS = ["'Capture'", "'Mic'"];
2222

@@ -37,23 +37,34 @@ function logError(error) {
3737
bindtextdomain(UUID, HOME_DIR + "/.local/share/locale");
3838
function _(str) {
3939
let customTranslation = dgettext(UUID, str);
40-
if(customTranslation != str) {
40+
if(customTranslation !== str) {
4141
return customTranslation;
4242
}
4343
return gettext(str);
4444
}
4545

4646
function findFirstMatch(searchStrings, checkString) {
47-
for (let i = 0; i < searchStrings.length; i++) {
48-
if (checkString.includes(searchStrings[i])) {
49-
return searchStrings[i];
50-
}
51-
}
52-
return null; // Return null if no match is found
47+
for (let i = 0; i < searchStrings.length; i++) {
48+
if (checkString.includes(searchStrings[i])) {
49+
return searchStrings[i];
50+
}
51+
}
52+
return null; // Return null if no match is found
5353
}
5454

5555
MyApplet.prototype = {
5656
__proto__: Applet.IconApplet.prototype,
57+
settings: null,
58+
use_pulseaudio: false,
59+
soundcard: null,
60+
keybinding: null,
61+
use_symbolic_icon: false,
62+
tint_symbolic_icon: false,
63+
unmuted_color: null,
64+
muted_color: null,
65+
verbose: true,
66+
67+
applet_is_running: false,
5768

5869
_init: function(metadata, orientation, panel_height, instance_id) {
5970
try {
@@ -66,6 +77,11 @@ MyApplet.prototype = {
6677
this.set_applet_tooltip(_("Click to mute/unmute microphone"));
6778

6879
try {
80+
this.settings.bindProperty(Settings.BindingDirection.IN,
81+
"use_pulseaudio",
82+
"use_pulseaudio",
83+
this.on_settings_changed,
84+
null);
6985
this.settings.bindProperty(Settings.BindingDirection.IN,
7086
"soundcard",
7187
"soundcard",
@@ -105,9 +121,6 @@ MyApplet.prototype = {
105121
} catch (e) {
106122
logError(e);
107123
log("Error initializing from Settings, continuing.", true);
108-
this.settings = null;
109-
this.keybinding = null;
110-
this.verbose = true
111124
}
112125

113126
if (this.settings) {
@@ -135,25 +148,30 @@ MyApplet.prototype = {
135148
}
136149

137150
VERBOSE = this.verbose;
151+
// noinspection JSIgnoredPromiseFromCall
138152
this.evaluate_cmd_line();
139153
},
140154

141155
refresh_loop: function() {
142156
this.is_audio_muted();
143-
if (this.applet_is_running)
157+
if (this.applet_is_running) {
144158
Mainloop.timeout_add(1000, Lang.bind(this, this.refresh_loop));
159+
}
145160
},
146161

147162
is_audio_muted: function() {
148163
try {
149-
let cmd = [
164+
const cmd = [
150165
"sh",
151166
"-c",
152-
this.amixer + " sget " + this.input
153-
];
167+
this.use_pulseaudio
168+
? "pactl get-source-mute `pactl get-default-source`"
169+
: this.amixer + " sget " + this.input
170+
];
171+
const match_string = this.use_pulseaudio ? " no" : "] [on]";
154172
Util.spawn_async(cmd, (stdout) => {
155173
try{
156-
if(stdout.indexOf("] [on]") != -1){
174+
if(stdout.indexOf(match_string) !== -1){
157175
this.set_not_muted_icon();
158176
} else {
159177
this.set_muted_icon();
@@ -168,7 +186,6 @@ MyApplet.prototype = {
168186
},
169187

170188
set_not_muted_icon: function() {
171-
this.current_icon = "not_muted";
172189
if (this.use_symbolic_icon) {
173190
this.set_applet_icon_symbolic_name("microphone-sensitivity-high-symbolic");
174191
if (this.tint_symbolic_icon) {
@@ -182,7 +199,6 @@ MyApplet.prototype = {
182199
},
183200

184201
set_muted_icon: function() {
185-
this.current_icon = "muted";
186202
if (this.use_symbolic_icon) {
187203
this.set_applet_icon_symbolic_name("microphone-disabled-symbolic");
188204
if (this.tint_symbolic_icon) {
@@ -198,24 +214,25 @@ MyApplet.prototype = {
198214
evaluate_soundcard: function() {
199215
return new Promise((resolve, reject) => {
200216
// only use specific soundcard if searchstring is not empty
201-
if (this.soundcard.trim().length > 0) {
202-
// per default use first soundcard
203-
this.soundcard_id = "0";
204-
217+
if (this.soundcard?.trim().length > 0) {
205218
Util.spawn_async(["sh","-c","cat /proc/asound/cards"], (stdout) => {
206219
try {
207-
// Split the result into lines
220+
// per default use first soundcard
221+
let soundcard_id = "0";
222+
223+
// Split the result into lines
208224
let lines = stdout.split('\n');
209225

210226
// Filter lines that contain the soundcard search string
211227
let filteredLines = lines.filter(line => line.includes(this.soundcard));
212228

213-
// Extract the field after splitting by space and getting the second field (index 1)
229+
// Extract the field after splitting by space and getting the second field (index 1)
214230
if (filteredLines.length > 0) {
215-
this.soundcard_id = filteredLines[0].split(' ')[1];
231+
soundcard_id = filteredLines[0].split(' ')[1];
216232
}
217-
log("Use specific soundcard id: '" + this.soundcard_id + "'");
218-
this.amixer = this.amixer + " -c " + this.soundcard_id;
233+
234+
log("Use specific soundcard id: '" + soundcard_id + "'");
235+
this.amixer = this.amixer + " -c " + soundcard_id;
219236
resolve();
220237
} catch (e) {
221238
reject(e);
@@ -245,9 +262,13 @@ MyApplet.prototype = {
245262
});
246263
},
247264

248-
evaluate_cmd_line: async function() {
265+
evaluate_cmd_line: async function() {
266+
if (this.use_pulseaudio) {
267+
return;
268+
}
269+
249270
this.amixer = "amixer";
250-
await this.evaluate_soundcard();
271+
await this.evaluate_soundcard();
251272
await this.evaluate_input();
252273

253274
const parameters = ["", " -D pulse"];
@@ -256,22 +277,24 @@ MyApplet.prototype = {
256277
log("Test mixer command '" + cmd + "'");
257278
// TODO: Make it async.
258279
let [res, stdout] = GLib.spawn_command_line_sync(cmd);
259-
if (res && to_string(stdout).indexOf(this.input) != -1) {
280+
if (res && to_string(stdout).indexOf(this.input) !== -1) {
260281
this.amixer += param;
261282
log("Use mixer command '" + this.amixer + "'");
262283
break;
263284
}
264285
}
265286
},
266287

267-
on_applet_clicked: function(event) {
288+
on_applet_clicked: function(_event) {
268289
try{
269290
let cmd = [
270291
"sh",
271292
"-c",
272-
this.amixer + " set " + this.input + " toggle"
293+
this.use_pulseaudio
294+
? "pactl set-source-mute `pactl get-default-source` toggle"
295+
: this.amixer + " set " + this.input + " toggle"
273296
];
274-
Util.spawn_async(cmd, (stdout) => {
297+
Util.spawn_async(cmd, (_stdout) => {
275298
this.is_audio_muted();
276299
});
277300
}catch(e){
@@ -289,7 +312,7 @@ function MyApplet(metadata, orientation, panel_height, instance_id) {
289312
this._init(metadata, orientation, panel_height, instance_id);
290313
}
291314

315+
// noinspection JSUnusedLocalSymbols
292316
function main(metadata, orientation, panel_height, instance_id) {
293-
let myApplet = new MyApplet(metadata, orientation, panel_height, instance_id);
294-
return myApplet;
317+
return new MyApplet(metadata, orientation, panel_height, instance_id);
295318
}

[email protected]/files/[email protected]/settings-schema.json

+7
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,18 @@
33
"type": "section",
44
"description": "Soundcard settings",
55
"keys": [
6+
"use_pulseaudio",
67
"soundcard"
78
]
89
},
10+
"use_pulseaudio": {
11+
"type": "switch",
12+
"description": "Use PulseAudio (default: ALSA)",
13+
"default": false
14+
},
915
"soundcard": {
1016
"type": "entry",
17+
"dependency": "!use_pulseaudio",
1118
"description": "Soundcard search string in /proc/asound/cards (empty: deactivate)",
1219
"default": ""
1320
},

0 commit comments

Comments
 (0)