[pulseaudio-commits] src/mainwindow.cc src/pavucontrol.glade src/rolewidget.cc src/sinkinputwidget.cc src/sinkinputwidget.h src/sourceoutputwidget.cc src/sourceoutputwidget.h src/streamwidget.cc src/streamwidget.h
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Nov 27 19:55:08 UTC 2019
src/mainwindow.cc | 18 ++++++++---
src/pavucontrol.glade | 6 ---
src/rolewidget.cc | 2 -
src/sinkinputwidget.cc | 75 +++++++++++++++++-----------------------------
src/sinkinputwidget.h | 26 +--------------
src/sourceoutputwidget.cc | 75 +++++++++++++++++-----------------------------
src/sourceoutputwidget.h | 26 +--------------
src/streamwidget.cc | 9 ++---
src/streamwidget.h | 7 +++-
9 files changed, 86 insertions(+), 158 deletions(-)
New commits:
commit ae278b8643cf1089f66df18713c8154208d9a505
Author: Tanu Kaskinen <tanuk at iki.fi>
Date: Fri Sep 6 11:32:12 2019 +0300
streamwidget: Use a drop-down list instead of a button and a popup for selecting the device
This looks better, requires less code and probably fixes
https://gitlab.freedesktop.org/pulseaudio/pavucontrol/issues/63
diff --git a/src/mainwindow.cc b/src/mainwindow.cc
index 459ebbb..a402945 100644
--- a/src/mainwindow.cc
+++ b/src/mainwindow.cc
@@ -1084,12 +1084,15 @@ void MainWindow::reallyUpdateDeviceVisibility() {
for (std::map<uint32_t, SinkInputWidget*>::iterator i = sinkInputWidgets.begin(); i != sinkInputWidgets.end(); ++i) {
SinkInputWidget* w = i->second;
+ w->updating = true;
+ w->updateDeviceComboBox();
+
if (sinkWidgets.size() > 1) {
w->directionLabel->show();
- w->deviceButton->show();
+ w->deviceComboBox->show();
} else {
w->directionLabel->hide();
- w->deviceButton->hide();
+ w->deviceComboBox->hide();
}
if (showSinkInputType == SINK_INPUT_ALL || w->type == showSinkInputType) {
@@ -1097,6 +1100,8 @@ void MainWindow::reallyUpdateDeviceVisibility() {
is_empty = false;
} else
w->hide();
+
+ w->updating = false;
}
if (eventRoleWidget)
@@ -1112,12 +1117,15 @@ void MainWindow::reallyUpdateDeviceVisibility() {
for (std::map<uint32_t, SourceOutputWidget*>::iterator i = sourceOutputWidgets.begin(); i != sourceOutputWidgets.end(); ++i) {
SourceOutputWidget* w = i->second;
+ w->updating = true;
+ w->updateDeviceComboBox();
+
if (sourceWidgets.size() > 1) {
w->directionLabel->show();
- w->deviceButton->show();
+ w->deviceComboBox->show();
} else {
w->directionLabel->hide();
- w->deviceButton->hide();
+ w->deviceComboBox->hide();
}
if (showSourceOutputType == SOURCE_OUTPUT_ALL || w->type == showSourceOutputType) {
@@ -1125,6 +1133,8 @@ void MainWindow::reallyUpdateDeviceVisibility() {
is_empty = false;
} else
w->hide();
+
+ w->updating = false;
}
if (is_empty)
diff --git a/src/pavucontrol.glade b/src/pavucontrol.glade
index a66e193..fe6c635 100644
--- a/src/pavucontrol.glade
+++ b/src/pavucontrol.glade
@@ -1496,13 +1496,9 @@
</packing>
</child>
<child>
- <object class="GtkButton" id="deviceButton">
- <property name="label" translatable="yes">Device</property>
+ <object class="GtkComboBoxText" id="deviceComboBox">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="relief">half</property>
- <property name="xalign">0</property>
</object>
<packing>
<property name="expand">False</property>
diff --git a/src/rolewidget.cc b/src/rolewidget.cc
index db07f92..7f755aa 100644
--- a/src/rolewidget.cc
+++ b/src/rolewidget.cc
@@ -33,7 +33,7 @@ RoleWidget::RoleWidget(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>
lockToggleButton->hide();
directionLabel->hide();
- deviceButton->hide();
+ deviceComboBox->hide();
}
RoleWidget* RoleWidget::create() {
diff --git a/src/sinkinputwidget.cc b/src/sinkinputwidget.cc
index 5a0ba39..ff086d6 100644
--- a/src/sinkinputwidget.cc
+++ b/src/sinkinputwidget.cc
@@ -44,28 +44,42 @@ SinkInputWidget* SinkInputWidget::create(MainWindow* mainWindow) {
x->get_widget_derived("streamWidget", w);
w->init(mainWindow);
w->reference();
+
return w;
}
SinkInputWidget::~SinkInputWidget(void) {
- clearMenu();
}
void SinkInputWidget::setSinkIndex(uint32_t idx) {
mSinkIndex = idx;
-
- if (mpMainWindow->sinkWidgets.count(idx)) {
- SinkWidget *w = mpMainWindow->sinkWidgets[idx];
- deviceButton->set_label(w->description.c_str());
- }
- else
- deviceButton->set_label(_("Unknown output"));
+ updateDeviceComboBox();
}
uint32_t SinkInputWidget::sinkIndex() {
return mSinkIndex;
}
+void SinkInputWidget::updateDeviceComboBox() {
+ Glib::ustring currentSinkName = UNKNOWN_DEVICE_NAME;
+
+ deviceComboBox->remove_all();
+
+ for (auto i = mpMainWindow->sinkWidgets.begin(); i != mpMainWindow->sinkWidgets.end(); i++) {
+ SinkWidget *sink = i->second;
+
+ deviceComboBox->append(sink->name, sink->description);
+
+ if (sink->index == mSinkIndex)
+ currentSinkName = sink->name;
+ }
+
+ if (currentSinkName == UNKNOWN_DEVICE_NAME)
+ deviceComboBox->append(UNKNOWN_DEVICE_NAME, _("Unknown output"));
+
+ deviceComboBox->set_active_id(currentSinkName);
+}
+
void SinkInputWidget::executeVolumeUpdate() {
pa_operation* o;
@@ -102,44 +116,13 @@ void SinkInputWidget::onKill() {
pa_operation_unref(o);
}
-void SinkInputWidget::clearMenu() {
- while (!sinkMenuItems.empty()) {
- std::map<uint32_t, SinkMenuItem*>::iterator i = sinkMenuItems.begin();
- delete i->second;
- sinkMenuItems.erase(i);
- }
-}
-
-void SinkInputWidget::buildMenu() {
- for (std::map<uint32_t, SinkWidget*>::iterator i = mpMainWindow->sinkWidgets.begin(); i != mpMainWindow->sinkWidgets.end(); ++i) {
- SinkMenuItem *m;
- sinkMenuItems[i->second->index] = m = new SinkMenuItem(this, i->second->description.c_str(), i->second->index, i->second->index == mSinkIndex);
- menu.append(m->menuItem);
- }
- menu.show_all();
-}
-
-void SinkInputWidget::SinkMenuItem::onToggle() {
- if (widget->updating)
- return;
-
- if (!menuItem.get_active())
- return;
-
- /*if (!mpMainWindow->sinkWidgets.count(widget->index))
- return;*/
-
- pa_operation* o;
- if (!(o = pa_context_move_sink_input_by_index(get_context(), widget->index, index, NULL, NULL))) {
- show_error(_("pa_context_move_sink_input_by_index() failed"));
- return;
- }
+void SinkInputWidget::onDeviceComboBoxChanged() {
+ if (updating)
+ return;
- pa_operation_unref(o);
-}
+ Glib::ustring sinkName = deviceComboBox->get_active_id();
-void SinkInputWidget::onDeviceChangePopup() {
- clearMenu();
- buildMenu();
- menu.popup(1, 0);
+ pa_operation *o = pa_context_move_sink_input_by_name(get_context(), index, sinkName.c_str(), NULL, NULL);
+ if (o)
+ pa_operation_unref(o);
}
diff --git a/src/sinkinputwidget.h b/src/sinkinputwidget.h
index 368dde0..af40d03 100644
--- a/src/sinkinputwidget.h
+++ b/src/sinkinputwidget.h
@@ -38,36 +38,14 @@ public:
uint32_t index, clientIndex;
void setSinkIndex(uint32_t idx);
uint32_t sinkIndex();
+ void updateDeviceComboBox();
virtual void executeVolumeUpdate();
virtual void onMuteToggleButton();
- virtual void onDeviceChangePopup();
virtual void onKill();
+ virtual void onDeviceComboBoxChanged();
private:
uint32_t mSinkIndex;
-
- void clearMenu();
- void buildMenu();
-
- Gtk::Menu menu;
-
- struct SinkMenuItem {
- SinkMenuItem(SinkInputWidget *w, const char *label, uint32_t i, bool active) :
- widget(w),
- menuItem(label),
- index(i) {
- menuItem.set_active(active);
- menuItem.set_draw_as_radio(true);
- menuItem.signal_toggled().connect(sigc::mem_fun(*this, &SinkMenuItem::onToggle));
- }
-
- SinkInputWidget *widget;
- Gtk::CheckMenuItem menuItem;
- uint32_t index;
- void onToggle();
- };
-
- std::map<uint32_t, SinkMenuItem*> sinkMenuItems;
};
#endif
diff --git a/src/sourceoutputwidget.cc b/src/sourceoutputwidget.cc
index 4d915b0..1c2e762 100644
--- a/src/sourceoutputwidget.cc
+++ b/src/sourceoutputwidget.cc
@@ -54,24 +54,37 @@ SourceOutputWidget* SourceOutputWidget::create(MainWindow* mainWindow) {
}
SourceOutputWidget::~SourceOutputWidget(void) {
- clearMenu();
}
void SourceOutputWidget::setSourceIndex(uint32_t idx) {
mSourceIndex = idx;
-
- if (mpMainWindow->sourceWidgets.count(idx)) {
- SourceWidget *w = mpMainWindow->sourceWidgets[idx];
- deviceButton->set_label(w->description.c_str());
- }
- else
- deviceButton->set_label(_("Unknown input"));
+ updateDeviceComboBox();
}
uint32_t SourceOutputWidget::sourceIndex() {
return mSourceIndex;
}
+void SourceOutputWidget::updateDeviceComboBox() {
+ Glib::ustring currentSourceName = UNKNOWN_DEVICE_NAME;
+
+ deviceComboBox->remove_all();
+
+ for (auto i = mpMainWindow->sourceWidgets.begin(); i != mpMainWindow->sourceWidgets.end(); i++) {
+ SourceWidget *source = i->second;
+
+ deviceComboBox->append(source->name, source->description);
+
+ if (source->index == mSourceIndex)
+ currentSourceName = source->name;
+ }
+
+ if (currentSourceName == UNKNOWN_DEVICE_NAME)
+ deviceComboBox->append(UNKNOWN_DEVICE_NAME, _("Unknown input"));
+
+ deviceComboBox->set_active_id(currentSourceName);
+}
+
#if HAVE_SOURCE_OUTPUT_VOLUMES
void SourceOutputWidget::executeVolumeUpdate() {
pa_operation* o;
@@ -110,45 +123,13 @@ void SourceOutputWidget::onKill() {
pa_operation_unref(o);
}
+void SourceOutputWidget::onDeviceComboBoxChanged() {
+ if (updating)
+ return;
-void SourceOutputWidget::clearMenu() {
- while (!sourceMenuItems.empty()) {
- std::map<uint32_t, SourceMenuItem*>::iterator i = sourceMenuItems.begin();
- delete i->second;
- sourceMenuItems.erase(i);
- }
-}
-
-void SourceOutputWidget::buildMenu() {
- for (std::map<uint32_t, SourceWidget*>::iterator i = mpMainWindow->sourceWidgets.begin(); i != mpMainWindow->sourceWidgets.end(); ++i) {
- SourceMenuItem *m;
- sourceMenuItems[i->second->index] = m = new SourceMenuItem(this, i->second->description.c_str(), i->second->index, i->second->index == mSourceIndex);
- menu.append(m->menuItem);
- }
- menu.show_all();
-}
-
-void SourceOutputWidget::SourceMenuItem::onToggle() {
- if (widget->updating)
- return;
-
- if (!menuItem.get_active())
- return;
-
- /*if (!mpMainWindow->sourceWidgets.count(widget->index))
- return;*/
-
- pa_operation* o;
- if (!(o = pa_context_move_source_output_by_index(get_context(), widget->index, index, NULL, NULL))) {
- show_error(_("pa_context_move_source_output_by_index() failed"));
- return;
- }
-
- pa_operation_unref(o);
-}
+ Glib::ustring sourceName = deviceComboBox->get_active_id();
-void SourceOutputWidget::onDeviceChangePopup() {
- clearMenu();
- buildMenu();
- menu.popup(1, 0);
+ pa_operation *o = pa_context_move_source_output_by_name(get_context(), index, sourceName.c_str(), NULL, NULL);
+ if (o)
+ pa_operation_unref(o);
}
diff --git a/src/sourceoutputwidget.h b/src/sourceoutputwidget.h
index 1b9ab0f..5edd438 100644
--- a/src/sourceoutputwidget.h
+++ b/src/sourceoutputwidget.h
@@ -38,38 +38,16 @@ public:
uint32_t index, clientIndex;
void setSourceIndex(uint32_t idx);
uint32_t sourceIndex();
+ void updateDeviceComboBox();
#if HAVE_SOURCE_OUTPUT_VOLUMES
virtual void executeVolumeUpdate();
virtual void onMuteToggleButton();
#endif
- virtual void onDeviceChangePopup();
virtual void onKill();
+ virtual void onDeviceComboBoxChanged();
private:
uint32_t mSourceIndex;
-
- void clearMenu();
- void buildMenu();
-
- Gtk::Menu menu;
-
- struct SourceMenuItem {
- SourceMenuItem(SourceOutputWidget *w, const char *label, uint32_t i, bool active) :
- widget(w),
- menuItem(label),
- index(i) {
- menuItem.set_active(active);
- menuItem.set_draw_as_radio(true);
- menuItem.signal_toggled().connect(sigc::mem_fun(*this, &SourceMenuItem::onToggle));
- }
-
- SourceOutputWidget *widget;
- Gtk::CheckMenuItem menuItem;
- uint32_t index;
- void onToggle();
- };
-
- std::map<uint32_t, SourceMenuItem*> sourceMenuItems;
};
#endif
diff --git a/src/streamwidget.cc b/src/streamwidget.cc
index 00b7796..00df09f 100644
--- a/src/streamwidget.cc
+++ b/src/streamwidget.cc
@@ -42,12 +42,12 @@ StreamWidget::StreamWidget(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Buil
x->get_widget("streamLockToggleButton", lockToggleButton);
x->get_widget("streamMuteToggleButton", muteToggleButton);
x->get_widget("directionLabel", directionLabel);
- x->get_widget("deviceButton", deviceButton);
+ x->get_widget("deviceComboBox", deviceComboBox);
this->signal_button_press_event().connect(sigc::mem_fun(*this, &StreamWidget::onContextTriggerEvent));
muteToggleButton->signal_clicked().connect(sigc::mem_fun(*this, &StreamWidget::onMuteToggleButton));
lockToggleButton->signal_clicked().connect(sigc::mem_fun(*this, &StreamWidget::onLockToggleButton));
- deviceButton->signal_clicked().connect(sigc::mem_fun(*this, &StreamWidget::onDeviceChangePopup));
+ deviceComboBox->signal_changed().connect(sigc::mem_fun(*this, &StreamWidget::onDeviceComboBoxChanged));
terminate.set_label(_("Terminate"));
terminate.signal_activate().connect(sigc::mem_fun(*this, &StreamWidget::onKill));
@@ -58,7 +58,6 @@ StreamWidget::StreamWidget(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Buil
channelWidgets[i] = NULL;
}
-
void StreamWidget::init(MainWindow* mainWindow) {
mpMainWindow = mainWindow;
@@ -145,8 +144,8 @@ bool StreamWidget::timeoutEvent() {
void StreamWidget::executeVolumeUpdate() {
}
-void StreamWidget::onDeviceChangePopup() {
+void StreamWidget::onKill() {
}
-void StreamWidget::onKill() {
+void StreamWidget::onDeviceComboBoxChanged() {
}
diff --git a/src/streamwidget.h b/src/streamwidget.h
index 23bdf7b..c1a79da 100644
--- a/src/streamwidget.h
+++ b/src/streamwidget.h
@@ -28,6 +28,9 @@
class MainWindow;
class ChannelWidget;
+/* Used as the ID for the unknown device item in deviceComboBox. */
+#define UNKNOWN_DEVICE_NAME "#unknown#"
+
class StreamWidget : public MinimalStreamWidget {
public:
StreamWidget(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& x);
@@ -41,7 +44,7 @@ public:
Gtk::ToggleButton *lockToggleButton, *muteToggleButton;
Gtk::Label *directionLabel;
- Gtk::Button *deviceButton;
+ Gtk::ComboBoxText *deviceComboBox;
pa_channel_map channelMap;
pa_cvolume volume;
@@ -50,7 +53,6 @@ public:
virtual void onMuteToggleButton();
virtual void onLockToggleButton();
- virtual void onDeviceChangePopup();
virtual bool onContextTriggerEvent(GdkEventButton*);
sigc::connection timeoutConnection;
@@ -59,6 +61,7 @@ public:
virtual void executeVolumeUpdate();
virtual void onKill();
+ virtual void onDeviceComboBoxChanged();
protected:
MainWindow* mpMainWindow;
More information about the pulseaudio-commits
mailing list