Expose a setting for Bluetooth mic autoswitch

Requires libpulse with messaging support and PipeWire 1.6 or later.
This commit is contained in:
Arun Raghavan 2026-05-01 10:43:48 -07:00
parent f52656b10e
commit 27980e1fbe
4 changed files with 53 additions and 0 deletions

View file

@ -100,6 +100,8 @@ MainWindow::MainWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>
hideUnavailableCardProfilesCheckButton = x->get_widget<Gtk::CheckButton>("hideUnavailableCardProfilesCheckButton");
monoAudioLabel = x->get_widget<Gtk::Label>("monoAudioLabel");
monoAudioSwitch = x->get_widget<Gtk::Switch>("monoAudioSwitch");
btAutoswitchLabel = x->get_widget<Gtk::Label>("btAutoswitchLabel");
btAutoswitchSwitch = x->get_widget<Gtk::Switch>("btAutoswitchSwitch");
sinkInputTypeComboBox->set_active((int) showSinkInputType);
sourceOutputTypeComboBox->set_active((int) showSourceOutputType);
@ -115,6 +117,7 @@ MainWindow::MainWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>
#if HAVE_PULSE_MESSAGING_API
monoAudioSwitch->signal_state_set().connect(sigc::mem_fun(*this, &MainWindow::onMonoAudioStateSet), false);
btAutoswitchSwitch->signal_state_set().connect(sigc::mem_fun(*this, &MainWindow::onBtAutoswitchSet), false);
#endif
auto event_controller_key = Gtk::EventControllerKey::create();
@ -1493,3 +1496,15 @@ bool MainWindow::onMonoAudioStateSet(bool state) {
return false;
}
bool MainWindow::onBtAutoswitchSet(bool state) {
pa_context *c = get_context();
pa_operation *o;
const char *value = state ? "true" : "false";
o = pa_context_send_message_to_object(c, "/core", "pipewire-pulse:bluetooth-headset-autoswitch", value, NULL, NULL);
if (o)
pa_operation_unref(o);
return false;
}

View file

@ -93,6 +93,8 @@ class MainWindow : public Gtk::Window {
*hideUnavailableCardProfilesCheckButton;
Gtk::Label *monoAudioLabel;
Gtk::Switch *monoAudioSwitch;
Gtk::Label *btAutoswitchLabel;
Gtk::Switch *btAutoswitchSwitch;
std::map<uint32_t, CardWidget *> cardWidgets;
std::map<uint32_t, SinkWidget *> sinkWidgets;
@ -113,6 +115,7 @@ class MainWindow : public Gtk::Window {
virtual void onShowVolumeMetersCheckButtonToggled();
virtual void onHideUnavailableCardProfilesCheckButtonToggled();
virtual bool onMonoAudioStateSet(bool);
virtual bool onBtAutoswitchSet(bool);
void setConnectionState(gboolean connected);
void updateDeviceVisibility();

View file

@ -431,6 +431,24 @@
</child>
</object>
</child>
<child>
<object class="GtkBox" id="btAutoswitchBox">
<property name="orientation">horizontal</property>
<property name="spacing">12</property>
<property name="tooltip-text">Requires PipeWire 1.6 or later</property>
<child>
<object class="GtkSwitch" id="btAutoswitchSwitch">
<property name="sensitive">false</property>
</object>
</child>
<child>
<object class="GtkLabel" id="btAutoswitchLabel">
<property name="label" translatable="yes">Automatically enable Bluetooth mic (reduces audio quality during capture)</property>
<property name="sensitive">false</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>

View file

@ -626,6 +626,19 @@ static void probe_force_mono_output_cb(pa_context *c, int success, char *respons
dec_outstanding(w);
}
static void probe_bt_autoswitch_cb(pa_context *c, int success, char *response, void *userdata)
{
MainWindow *w = static_cast<MainWindow*>(userdata);
if (success && response && strcmp(response, "null") != 0) {
/* We know the setting is supported */
w->btAutoswitchLabel->set_sensitive(true);
w->btAutoswitchSwitch->set_sensitive(true);
}
dec_outstanding(w);
}
void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t index, void *userdata) {
MainWindow *w = static_cast<MainWindow*>(userdata);
@ -856,6 +869,10 @@ void context_state_callback(pa_context *c, void *userdata) {
n_outstanding++;
} else
g_debug(_("Failed to check if we can force mono audio: %s"), pa_strerror(pa_context_errno(context)));
if ((o = pa_context_send_message_to_object(c, "/core", "pipewire-pulse:bluetooth-headset-autoswitch", NULL, probe_bt_autoswitch_cb, w))) {
n_outstanding++;
} else
g_debug(_("Failed to check if we can autoswitch to bluetooth mic: %s"), pa_strerror(pa_context_errno(context)));
#endif
break;