[pulseaudio-commits] src/cardwidget.cc src/cardwidget.h src/mainwindow.cc src/mainwindow.h src/pavucontrol.cc src/pavucontrol.glade src/pavucontrol.h

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jun 10 10:43:41 UTC 2021


 src/cardwidget.cc     |   37 +++++++++++++++++++++++++++++++++++++
 src/cardwidget.h      |    4 ++++
 src/mainwindow.cc     |   22 ++++++++++++++++++++++
 src/mainwindow.h      |    2 ++
 src/pavucontrol.cc    |   45 +++++++++++++++++++++++++++++++++++++++++++++
 src/pavucontrol.glade |   35 +++++++++++++++++++++++++++++++++++
 src/pavucontrol.h     |    1 +
 7 files changed, 146 insertions(+)

New commits:
commit a1b4622ad5de0513361b8638152d5e5b1ac6980f
Author: Igor V. Kovalenko <igor.v.kovalenko at gmail.com>
Date:   Fri Dec 25 17:38:01 2020 +0300

    cardwidget: add flag to lock profile from switching automatically
    
    Part-of: <https://gitlab.freedesktop.org/pulseaudio/pavucontrol/-/merge_requests/60>

diff --git a/src/cardwidget.cc b/src/cardwidget.cc
index b4fe378..d751fd2 100644
--- a/src/cardwidget.cc
+++ b/src/cardwidget.cc
@@ -35,6 +35,7 @@ CardWidget::CardWidget(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>
     x->get_widget("cardIconImage", iconImage);
     x->get_widget("codecBox", codecBox);
     x->get_widget("codecList", codecList);
+    x->get_widget("profileLockToggleButton", profileLockToggleButton);
 
     profileListStore = Gtk::ListStore::create(profileModel);
     profileList->set_model(profileListStore);
@@ -49,6 +50,12 @@ CardWidget::CardWidget(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>
     codecList->pack_start(codecModel.desc);
 
     codecList->signal_changed().connect( sigc::mem_fun(*this, &CardWidget::onCodecChange));
+
+    hasProfileLock = false;
+
+    profileLockToggleButton->signal_clicked().connect(sigc::mem_fun(*this, &CardWidget::onProfileLockToggleButton));
+    profileLockToggleButton->set_sensitive(true);
+    profileLockToggleButton->set_visible(hasProfileLock);
 }
 
 CardWidget* CardWidget::create() {
@@ -96,6 +103,8 @@ void CardWidget::prepareMenu() {
         codecBox->show();
     else
         codecBox->hide();
+
+    profileLockToggleButton->set_visible(hasProfileLock);
 }
 
 void CardWidget::onProfileChange() {
@@ -150,3 +159,31 @@ void CardWidget::onCodecChange() {
     }
 #endif
 }
+
+void CardWidget::onProfileLockToggleButton() {
+    if (updating)
+        return;
+
+#ifdef HAVE_PULSE_MESSAGING_API
+    Gtk::TreeModel::iterator iter = profileList->get_active();
+    if (iter)
+    {
+        Gtk::TreeModel::Row row = *iter;
+        if (row)
+        {
+          pa_operation* o;
+          Glib::ustring profile = row[profileModel.name];
+
+          bool profileIsLocked = profileLockToggleButton->get_active();
+
+          if (!(o = pa_context_send_message_to_object(get_context(), card_message_handler_path(pulse_card_name).c_str(),
+              "set-profile-sticky", profileIsLocked ? "true" : "false", NULL, NULL))) {
+              g_debug(_("pa_context_send_message_to_object() failed: %s"), pa_strerror(pa_context_errno(get_context())));
+              return;
+          }
+
+          pa_operation_unref(o);
+        }
+    }
+#endif
+}
diff --git a/src/cardwidget.h b/src/cardwidget.h
index 98201a4..3c86659 100644
--- a/src/cardwidget.h
+++ b/src/cardwidget.h
@@ -45,6 +45,7 @@ public:
     Glib::ustring name;
     std::string pulse_card_name;
     Gtk::Box *codecBox;
+    Gtk::ToggleButton *profileLockToggleButton;
     uint32_t index;
     bool updating;
 
@@ -59,11 +60,14 @@ public:
     std::vector<std::pair<Glib::ustring, Glib::ustring>> codecs;
     Glib::ustring activeCodec;
 
+    bool hasProfileLock;
+
     void prepareMenu();
 
 protected:
   virtual void onProfileChange();
   virtual void onCodecChange();
+  virtual void onProfileLockToggleButton();
 
   /* Tree model columns */
   class ModelColumns : public Gtk::TreeModel::ColumnRecord
diff --git a/src/mainwindow.cc b/src/mainwindow.cc
index ea290bd..bae4c7a 100644
--- a/src/mainwindow.cc
+++ b/src/mainwindow.cc
@@ -522,6 +522,28 @@ void MainWindow::setActiveCodec(const std::string& card_name, const std::string&
     w->updating = false;
 }
 
+void MainWindow::setCardProfileIsSticky(const std::string& card_name, gboolean profile_is_sticky) {
+    CardWidget *w = NULL;
+
+    for (auto c : cardWidgets) {
+        if (card_name.compare(c.second->pulse_card_name) == 0)
+            w = c.second;
+    }
+
+    if (!w)
+        return;
+
+    w->updating = true;
+
+    /* make sure that profile lock toggle button is visible */
+    w->hasProfileLock = true;
+    w->profileLockToggleButton->set_active(profile_is_sticky);
+
+    w->prepareMenu();
+
+    w->updating = false;
+}
+
 bool MainWindow::updateSink(const pa_sink_info &info) {
     SinkWidget *w;
     bool is_new = false;
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 50f3985..5015144 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -59,6 +59,8 @@ public:
     void updateCardCodecs(const std::string& card_name, const std::unordered_map<std::string, std::string>& codecs);
     void setActiveCodec(const std::string& card_name, const std::string& codec);
 
+    void setCardProfileIsSticky(const std::string& card_name, gboolean profile_is_sticky);
+
     void removeCard(uint32_t index);
     void removeSink(uint32_t index);
     void removeSource(uint32_t index);
diff --git a/src/pavucontrol.cc b/src/pavucontrol.cc
index 3f5c218..18d5400 100644
--- a/src/pavucontrol.cc
+++ b/src/pavucontrol.cc
@@ -81,6 +81,10 @@ static void dec_outstanding(MainWindow *w) {
 
 #ifdef HAVE_PULSE_MESSAGING_API
 
+std::string card_message_handler_path(const std::string& name) {
+    return "/card/" + name;
+}
+
 std::string card_bluez_message_handler_path(const std::string& name) {
     return "/card/" + name + "/bluez";
 }
@@ -201,6 +205,39 @@ static void context_bluetooth_card_active_codec_cb(pa_context *c, int success, c
     g_object_unref(parser);
 }
 
+static void context_card_profile_is_sticky_cb(pa_context *c, int success, char *response, void *userdata) {
+    auto u = std::unique_ptr<WindowAndCardName>(reinterpret_cast<WindowAndCardName*>(userdata));
+
+    if (!success)
+        return;
+
+    gboolean profile_is_sticky;
+    GError *gerror = NULL;
+
+    JsonParser *parser = json_parser_new();
+
+    if (!json_parser_load_from_data(parser, response, strlen(response), &gerror)) {
+        g_debug(_("could not read JSON from get-profile-sticky message response: %s"), gerror->message);
+        g_error_free(gerror);
+        g_object_unref(parser);
+        return;
+    }
+
+    JsonNode *root = json_parser_get_root(parser);
+
+    if (!root || JSON_NODE_TYPE(root) != JSON_NODE_VALUE) {
+        g_debug(_("get-profile-sticky message response is not a JSON value"));
+        g_object_unref(parser);
+        return;
+    }
+
+    profile_is_sticky = json_node_get_boolean(root);
+
+    u->first->setCardProfileIsSticky(u->second, profile_is_sticky);
+
+    g_object_unref(parser);
+}
+
 template<typename U> void send_message(pa_context *c, const char *target, const char *request, pa_context_string_cb_t cb, const U& u)
 {
     auto send_message_userdata = new U(u);
@@ -300,6 +337,14 @@ static void context_message_handlers_cb(pa_context *c, int success, char *respon
         /* list-codecs: retrieve list of codecs */
         send_message(c, e->first.c_str(), "list-codecs", context_bluetooth_card_codec_list_cb, *u);
     }
+
+    /* send requests to card if card message handler is registered */
+    e = message_handler_map.find(card_message_handler_path(u->second));
+
+    if (e != message_handler_map.end()) {
+        /* get-profile-sticky: retrieve active codec name */
+        send_message(c, e->first.c_str(), "get-profile-sticky", context_card_profile_is_sticky_cb, *u);
+    }
 }
 #endif
 
diff --git a/src/pavucontrol.glade b/src/pavucontrol.glade
index e5cf31a..253534e 100644
--- a/src/pavucontrol.glade
+++ b/src/pavucontrol.glade
@@ -134,6 +134,41 @@
                         <property name="position">1</property>
                       </packing>
                     </child>
+                    <child>
+                      <object class="GtkHBox" id="hbox14">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="spacing">3</property>
+                        <child>
+                          <object class="GtkToggleButton" id="profileLockToggleButton">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <property name="tooltip_text" translatable="yes">Lock card to this profile</property>
+                            <property name="relief">none</property>
+                            <property name="active">True</property>
+                            <child>
+                              <object class="GtkImage" id="image4">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="icon_name">changes-prevent</property>
+                                <property name="icon_size">1</property>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
                   </object>
                   <packing>
                     <property name="expand">False</property>
diff --git a/src/pavucontrol.h b/src/pavucontrol.h
index 7bf7f49..c8696e6 100644
--- a/src/pavucontrol.h
+++ b/src/pavucontrol.h
@@ -79,6 +79,7 @@ void show_error(const char *txt);
 MainWindow* pavucontrol_get_window(pa_glib_mainloop *m, bool maximize, bool retry, int tab_number);
 
 #ifdef HAVE_PULSE_MESSAGING_API
+std::string card_message_handler_path(const std::string& name);
 std::string card_bluez_message_handler_path(const std::string& name);
 #endif
 



More information about the pulseaudio-commits mailing list