diff --git a/src/mainwindow.cc b/src/mainwindow.cc index c9bbcdf..ef31339 100644 --- a/src/mainwindow.cc +++ b/src/mainwindow.cc @@ -100,6 +100,8 @@ MainWindow::MainWindow(BaseObjectType* cobject, const Glib::RefPtr hideUnavailableCardProfilesCheckButton = x->get_widget("hideUnavailableCardProfilesCheckButton"); monoAudioLabel = x->get_widget("monoAudioLabel"); monoAudioSwitch = x->get_widget("monoAudioSwitch"); + btAutoswitchLabel = x->get_widget("btAutoswitchLabel"); + btAutoswitchSwitch = x->get_widget("btAutoswitchSwitch"); sinkInputTypeComboBox->set_active((int) showSinkInputType); sourceOutputTypeComboBox->set_active((int) showSourceOutputType); @@ -115,6 +117,7 @@ MainWindow::MainWindow(BaseObjectType* cobject, const Glib::RefPtr #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; +} diff --git a/src/mainwindow.h b/src/mainwindow.h index 6fb1de5..0b5b145 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -93,6 +93,8 @@ class MainWindow : public Gtk::Window { *hideUnavailableCardProfilesCheckButton; Gtk::Label *monoAudioLabel; Gtk::Switch *monoAudioSwitch; + Gtk::Label *btAutoswitchLabel; + Gtk::Switch *btAutoswitchSwitch; std::map cardWidgets; std::map 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(); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index b8519c3..795801c 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -431,6 +431,24 @@ + + + horizontal + 12 + Requires PipeWire 1.6 or later + + + false + + + + + Automatically enable Bluetooth mic (reduces audio quality during capture) + false + + + + diff --git a/src/pavucontrol.cc b/src/pavucontrol.cc index 5788b3e..e2380bb 100644 --- a/src/pavucontrol.cc +++ b/src/pavucontrol.cc @@ -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(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(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;