--- a/pidgin/meson.build Fri May 20 01:37:47 2022 -0500
+++ b/pidgin/meson.build Fri May 20 02:24:05 2022 -0500
@@ -67,6 +67,11 @@
'prefs/pidginnetworkprefs.c',
'prefs/pidginproxyprefs.c',
+ 'prefs/pidginvvprefs.c', @@ -139,6 +144,11 @@
'prefs/pidginnetworkprefs.h',
'prefs/pidginproxyprefs.h',
+ libpidgin_prefs_headers += [ + 'prefs/pidginvvprefs.h', libpidgin_enum_headers = [
--- a/pidgin/prefs/pidginprefs.c Fri May 20 01:37:47 2022 -0500
+++ b/pidgin/prefs/pidginprefs.c Fri May 20 02:24:05 2022 -0500
@@ -42,6 +42,9 @@
#include "pidginprefsinternal.h"
+#include "pidginvvprefs.h" #include <libsoup/soup.h>
#define PREFS_OPTIMAL_ICON_SIZE 32
@@ -54,30 +57,6 @@
- PidginPrefCombo output;
- PidginPrefCombo output;
- GtkWidget *sink_widget;
@@ -494,530 +473,19 @@
-populate_vv_device_menuitems(PurpleMediaElementType type, GtkListStore *store)
- PurpleMediaManager *manager = NULL;
- gtk_list_store_clear(store);
- manager = purple_media_manager_get();
- devices = purple_media_manager_enumerate_elements(manager, type);
- for (; devices; devices = g_list_delete_link(devices, devices)) {
- PurpleMediaElementInfo *info = devices->data;
- const gchar *name, *id;
- name = purple_media_element_info_get_name(info);
- id = purple_media_element_info_get_id(info);
- gtk_list_store_append(store, &iter);
- gtk_list_store_set(store, &iter, PIDGIN_PREF_COMBO_TEXT, name,
- PIDGIN_PREF_COMBO_VALUE, id, -1);
-create_test_element(PurpleMediaElementType type)
- PurpleMediaElementInfo *element_info;
- element_info = purple_media_manager_get_active_element(purple_media_manager_get(), type);
- g_return_val_if_fail(element_info, NULL);
- return purple_media_element_info_call_create(element_info,
vv_test_switch_page_cb(GtkStack *stack, G_GNUC_UNUSED GParamSpec *pspec,
- PidginPrefsWindow *win = data;
+ PidginVVPrefs *vv_prefs = data; if (!g_str_equal(gtk_stack_get_visible_child_name(stack), "vv")) {
/* Disable any running test pipelines. */
- gtk_toggle_button_set_active(
- GTK_TOGGLE_BUTTON(win->vv.voice.test), FALSE);
- gtk_toggle_button_set_active(
- GTK_TOGGLE_BUTTON(win->vv.video.test), FALSE);
-create_voice_pipeline(void)
- GstElement *src, *sink;
- pipeline = gst_pipeline_new("voicetest");
- src = create_test_element(PURPLE_MEDIA_ELEMENT_AUDIO | PURPLE_MEDIA_ELEMENT_SRC);
- sink = create_test_element(PURPLE_MEDIA_ELEMENT_AUDIO | PURPLE_MEDIA_ELEMENT_SINK);
- volume = gst_element_factory_make("volume", "volume");
- level = gst_element_factory_make("level", "level");
- valve = gst_element_factory_make("valve", "valve");
- gst_bin_add_many(GST_BIN(pipeline), src, volume, level, valve, sink, NULL);
- gst_element_link_many(src, volume, level, valve, sink, NULL);
- purple_debug_info("gtkprefs", "create_voice_pipeline: setting pipeline "
- "state to GST_STATE_PLAYING - it may hang here on win32\n");
- gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING);
- purple_debug_info("gtkprefs", "create_voice_pipeline: state is set\n");
-on_volume_change_cb(GtkWidget *w, gdouble value, gpointer data)
- PidginPrefsWindow *win = PIDGIN_PREFS_WINDOW(data);
- if (!win->vv.voice.pipeline) {
- volume = gst_bin_get_by_name(GST_BIN(win->vv.voice.pipeline), "volume");
- g_object_set(volume, "volume",
- gtk_scale_button_get_value(GTK_SCALE_BUTTON(w)) / 100.0, NULL);
-gst_msg_db_to_percent(GstMessage *msg, gchar *value_name)
- list = gst_structure_get_value(gst_message_get_structure(msg), value_name);
-G_GNUC_BEGIN_IGNORE_DEPRECATIONS
- value = g_value_array_get_nth(g_value_get_boxed(list), 0);
-G_GNUC_END_IGNORE_DEPRECATIONS
- value_db = g_value_get_double(value);
- percent = pow(10, value_db / 20);
- return (percent > 1.0) ? 1.0 : percent;
-gst_bus_cb(GstBus *bus, GstMessage *msg, gpointer data)
- PidginPrefsWindow *win = PIDGIN_PREFS_WINDOW(data);
- if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ELEMENT &&
- gst_structure_has_name(gst_message_get_structure(msg), "level")) {
- GstElement *src = GST_ELEMENT(GST_MESSAGE_SRC(msg));
- gchar *name = gst_element_get_name(src);
- if (purple_strequal(name, "level")) {
- percent = gst_msg_db_to_percent(msg, "rms");
- gtk_progress_bar_set_fraction(
- GTK_PROGRESS_BAR(win->vv.voice.level), percent);
- percent = gst_msg_db_to_percent(msg, "decay");
- threshold = gtk_range_get_value(GTK_RANGE(
- win->vv.voice.threshold)) /
- valve = gst_bin_get_by_name(GST_BIN(GST_ELEMENT_PARENT(src)), "valve");
- g_object_set(valve, "drop", (percent < threshold), NULL);
- g_object_set(win->vv.voice.level, "text",
- (percent < threshold) ? _("DROP") : " ",
-voice_test_destroy_cb(GtkWidget *w, gpointer data)
- PidginPrefsWindow *win = PIDGIN_PREFS_WINDOW(data);
- if (!win->vv.voice.pipeline) {
- gst_element_set_state(win->vv.voice.pipeline, GST_STATE_NULL);
- g_clear_pointer(&win->vv.voice.pipeline, gst_object_unref);
-enable_voice_test(PidginPrefsWindow *win)
- win->vv.voice.pipeline = create_voice_pipeline();
- bus = gst_pipeline_get_bus(GST_PIPELINE(win->vv.voice.pipeline));
- gst_bus_add_signal_watch(bus);
- g_signal_connect(bus, "message", G_CALLBACK(gst_bus_cb), win);
-toggle_voice_test_cb(GtkToggleButton *test, gpointer data)
- PidginPrefsWindow *win = PIDGIN_PREFS_WINDOW(data);
- if (gtk_toggle_button_get_active(test)) {
- gtk_widget_set_sensitive(win->vv.voice.level, TRUE);
- enable_voice_test(win);
- g_signal_connect(win->vv.voice.volume, "value-changed",
- G_CALLBACK(on_volume_change_cb), win);
- g_signal_connect(test, "destroy",
- G_CALLBACK(voice_test_destroy_cb), win);
- gtk_progress_bar_set_fraction(
- GTK_PROGRESS_BAR(win->vv.voice.level), 0.0);
- gtk_widget_set_sensitive(win->vv.voice.level, FALSE);
- g_object_disconnect(win->vv.voice.volume,
- "any-signal::value-changed",
- G_CALLBACK(on_volume_change_cb), win, NULL);
- g_object_disconnect(test, "any-signal::destroy",
- G_CALLBACK(voice_test_destroy_cb), win,
- voice_test_destroy_cb(NULL, win);
+ pidgin_vv_prefs_disable_test_pipelines(vv_prefs);
-volume_changed_cb(GtkScaleButton *button, gdouble value, gpointer data)
- purple_prefs_set_int("/purple/media/audio/volume/input", value * 100);
-threshold_value_changed_cb(GtkScale *scale, GtkWidget *label)
- value = (int)gtk_range_get_value(GTK_RANGE(scale));
- tmp = g_strdup_printf(_("Silence threshold: %d%%"), value);
- gtk_label_set_label(GTK_LABEL(label), tmp);
- purple_prefs_set_int("/purple/media/audio/silence_threshold", value);
-bind_voice_test(PidginPrefsWindow *win, GtkBuilder *builder)
- volume = gtk_builder_get_object(builder, "vv.voice.volume");
- win->vv.voice.volume = GTK_WIDGET(volume);
- gtk_scale_button_set_value(GTK_SCALE_BUTTON(volume),
- purple_prefs_get_int("/purple/media/audio/volume/input") / 100.0);
- g_signal_connect(volume, "value-changed",
- G_CALLBACK(volume_changed_cb), NULL);
- label = gtk_builder_get_object(builder, "vv.voice.threshold_label");
- tmp = g_strdup_printf(_("Silence threshold: %d%%"),
- purple_prefs_get_int("/purple/media/audio/silence_threshold"));
- gtk_label_set_text(GTK_LABEL(label), tmp);
- threshold = gtk_builder_get_object(builder, "vv.voice.threshold");
- win->vv.voice.threshold = GTK_WIDGET(threshold);
- gtk_range_set_value(GTK_RANGE(threshold),
- purple_prefs_get_int("/purple/media/audio/silence_threshold"));
- g_signal_connect(threshold, "value-changed",
- G_CALLBACK(threshold_value_changed_cb), label);
- GTK_WIDGET(gtk_builder_get_object(builder, "vv.voice.level"));
- test = gtk_builder_get_object(builder, "vv.voice.test");
- g_signal_connect(test, "toggled",
- G_CALLBACK(toggle_voice_test_cb), win);
- win->vv.voice.test = GTK_WIDGET(test);
-create_video_pipeline(void)
- GstElement *src, *sink;
- GstElement *videoconvert;
- GstElement *videoscale;
- pipeline = gst_pipeline_new("videotest");
- src = create_test_element(PURPLE_MEDIA_ELEMENT_VIDEO | PURPLE_MEDIA_ELEMENT_SRC);
- sink = create_test_element(PURPLE_MEDIA_ELEMENT_VIDEO | PURPLE_MEDIA_ELEMENT_SINK);
- videoconvert = gst_element_factory_make("videoconvert", NULL);
- videoscale = gst_element_factory_make("videoscale", NULL);
- g_object_set_data(G_OBJECT(pipeline), "sink", sink);
- gst_bin_add_many(GST_BIN(pipeline), src, videoconvert, videoscale, sink,
- gst_element_link_many(src, videoconvert, videoscale, sink, NULL);
-video_test_destroy_cb(GtkWidget *w, gpointer data)
- PidginPrefsWindow *win = PIDGIN_PREFS_WINDOW(data);
- if (!win->vv.video.pipeline) {
- gst_element_set_state(win->vv.video.pipeline, GST_STATE_NULL);
- g_clear_pointer(&win->vv.video.pipeline, gst_object_unref);
-enable_video_test(PidginPrefsWindow *win)
- GtkWidget *video = NULL;
- GstElement *sink = NULL;
- win->vv.video.pipeline = create_video_pipeline();
- sink = g_object_get_data(G_OBJECT(win->vv.video.pipeline), "sink");
- g_object_get(sink, "widget", &video, NULL);
- gtk_widget_show(video);
- g_clear_pointer(&win->vv.video.sink_widget, gtk_widget_destroy);
- gtk_container_add(GTK_CONTAINER(win->vv.video.frame), video);
- win->vv.video.sink_widget = video;
- gst_element_set_state(GST_ELEMENT(win->vv.video.pipeline),
-toggle_video_test_cb(GtkToggleButton *test, gpointer data)
- PidginPrefsWindow *win = PIDGIN_PREFS_WINDOW(data);
- if (gtk_toggle_button_get_active(test)) {
- enable_video_test(win);
- g_signal_connect(test, "destroy",
- G_CALLBACK(video_test_destroy_cb), win);
- g_object_disconnect(test, "any-signal::destroy",
- G_CALLBACK(video_test_destroy_cb), win,
- video_test_destroy_cb(NULL, win);
-bind_video_test(PidginPrefsWindow *win, GtkBuilder *builder)
- win->vv.video.frame = GTK_WIDGET(
- gtk_builder_get_object(builder, "vv.video.frame"));
- test = gtk_builder_get_object(builder, "vv.video.test");
- g_signal_connect(test, "toggled",
- G_CALLBACK(toggle_video_test_cb), win);
- win->vv.video.test = GTK_WIDGET(test);
-vv_device_changed_cb(const gchar *name, PurplePrefType type,
- gconstpointer value, gpointer data)
- PidginPrefsWindow *win = PIDGIN_PREFS_WINDOW(data);
- PurpleMediaManager *manager;
- PurpleMediaElementInfo *info;
- manager = purple_media_manager_get();
- info = purple_media_manager_get_element_info(manager, value);
- purple_media_manager_set_active_element(manager, info);
- /* Refresh test viewers */
- if (strstr(name, "audio") && win->vv.voice.pipeline) {
- voice_test_destroy_cb(NULL, win);
- enable_voice_test(win);
- } else if (strstr(name, "video") && win->vv.video.pipeline) {
- video_test_destroy_cb(NULL, win);
- enable_video_test(win);
-purple_media_type_to_preference_key(PurpleMediaElementType type)
- if (type & PURPLE_MEDIA_ELEMENT_AUDIO) {
- if (type & PURPLE_MEDIA_ELEMENT_SRC) {
- return PIDGIN_PREFS_ROOT "/vvconfig/audio/src/device";
- } else if (type & PURPLE_MEDIA_ELEMENT_SINK) {
- return PIDGIN_PREFS_ROOT "/vvconfig/audio/sink/device";
- } else if (type & PURPLE_MEDIA_ELEMENT_VIDEO) {
- if (type & PURPLE_MEDIA_ELEMENT_SRC) {
- return PIDGIN_PREFS_ROOT "/vvconfig/video/src/device";
- } else if (type & PURPLE_MEDIA_ELEMENT_SINK) {
- return PIDGIN_PREFS_ROOT "/vvconfig/video/sink/device";
-bind_vv_dropdown(PidginPrefCombo *combo, PurpleMediaElementType element_type)
- const gchar *preference_key;
- preference_key = purple_media_type_to_preference_key(element_type);
- model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo->combo));
- populate_vv_device_menuitems(element_type, GTK_LIST_STORE(model));
- combo->type = PURPLE_PREF_STRING;
- combo->key = preference_key;
- pidgin_prefs_bind_dropdown(combo);
-bind_vv_frame(PidginPrefsWindow *win, PidginPrefCombo *combo,
- PurpleMediaElementType type)
- bind_vv_dropdown(combo, type);
- purple_prefs_connect_callback(combo->combo,
- purple_media_type_to_preference_key(type),
- vv_device_changed_cb, win);
- g_signal_connect_swapped(combo->combo, "destroy",
- G_CALLBACK(purple_prefs_disconnect_by_handle),
- g_object_set_data(G_OBJECT(combo->combo), "vv_media_type",
- g_object_set_data(G_OBJECT(combo->combo), "vv_combo", combo);
-device_list_changed_cb(PurpleMediaManager *manager, GtkWidget *widget)
- PidginPrefCombo *combo;
- PurpleMediaElementType media_type;
- combo = g_object_get_data(G_OBJECT(widget), "vv_combo");
- media_type = (PurpleMediaElementType)g_object_get_data(G_OBJECT(widget),
- /* Block signals so pref doesn't get re-saved while changing UI. */
- signal_id = g_signal_lookup("changed", GTK_TYPE_COMBO_BOX);
- g_signal_handlers_block_matched(combo->combo, G_SIGNAL_MATCH_ID, signal_id,
- model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo->combo));
- populate_vv_device_menuitems(media_type, GTK_LIST_STORE(model));
- g_signal_handlers_unblock_matched(combo->combo, G_SIGNAL_MATCH_ID,
- signal_id, 0, NULL, NULL, NULL);
-vv_page(PidginPrefsWindow *win)
- PurpleMediaManager *manager;
- builder = gtk_builder_new_from_resource("/im/pidgin/Pidgin3/Prefs/vv.ui");
- gtk_builder_set_translation_domain(builder, PACKAGE);
- ret = GTK_WIDGET(gtk_builder_get_object(builder, "vv.page"));
- manager = purple_media_manager_get();
- win->vv.voice.input.combo = GTK_WIDGET(
- gtk_builder_get_object(builder, "vv.voice.input.combo"));
- bind_vv_frame(win, &win->vv.voice.input,
- PURPLE_MEDIA_ELEMENT_AUDIO | PURPLE_MEDIA_ELEMENT_SRC);
- g_signal_connect_object(manager, "elements-changed::audiosrc",
- G_CALLBACK(device_list_changed_cb),
- win->vv.voice.input.combo, 0);
- win->vv.voice.output.combo = GTK_WIDGET(
- gtk_builder_get_object(builder, "vv.voice.output.combo"));
- bind_vv_frame(win, &win->vv.voice.output,
- PURPLE_MEDIA_ELEMENT_AUDIO | PURPLE_MEDIA_ELEMENT_SINK);
- g_signal_connect_object(manager, "elements-changed::audiosink",
- G_CALLBACK(device_list_changed_cb),
- win->vv.voice.output.combo, 0);
- bind_voice_test(win, builder);
- win->vv.video.input.combo = GTK_WIDGET(
- gtk_builder_get_object(builder, "vv.video.input.combo"));
- bind_vv_frame(win, &win->vv.video.input,
- PURPLE_MEDIA_ELEMENT_VIDEO | PURPLE_MEDIA_ELEMENT_SRC);
- g_signal_connect_object(manager, "elements-changed::videosrc",
- G_CALLBACK(device_list_changed_cb),
- win->vv.video.input.combo, 0);
- win->vv.video.output.combo = GTK_WIDGET(
- gtk_builder_get_object(builder, "vv.video.output.combo"));
- bind_vv_frame(win, &win->vv.video.output,
- PURPLE_MEDIA_ELEMENT_VIDEO | PURPLE_MEDIA_ELEMENT_SINK);
- g_signal_connect_object(manager, "elements-changed::videosink",
- G_CALLBACK(device_list_changed_cb),
- win->vv.video.output.combo, 0);
- bind_video_test(win, builder);
- g_signal_connect(win->stack, "notify::visible-child",
- G_CALLBACK(vv_test_switch_page_cb), win);
- g_object_unref(builder);
-prefs_stack_init(PidginPrefsWindow *win)
- GtkStack *stack = GTK_STACK(win->stack);
- gtk_container_add_with_properties(GTK_CONTAINER(stack), vv, "name",
- "vv", "title", _("Voice/Video"),
pidgin_prefs_window_class_init(PidginPrefsWindowClass *klass)
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
@@ -1036,6 +504,9 @@
pidgin_prefs_window_init(PidginPrefsWindow *win)
/* copy the preferences to tmp values...
* I liked "take affect immediately" Oh well :-( */
/* (that should have been "effect," right?) */
@@ -1045,7 +516,12 @@
gtk_widget_init_template(GTK_WIDGET(win));
+ vv = pidgin_vv_prefs_new(); + gtk_stack_add_titled(GTK_STACK(win->stack), vv, "vv", _("Voice/Video")); + g_signal_connect(win->stack, "notify::visible-child", + G_CALLBACK(vv_test_switch_page_cb), vv); --- a/pidgin/resources/Prefs/vv.ui Fri May 20 01:37:47 2022 -0500
+++ b/pidgin/resources/Prefs/vv.ui Fri May 20 02:24:05 2022 -0500
@@ -35,7 +35,7 @@
<property name="step-increment">1</property>
<property name="page-increment">10</property>
- <object class="GtkListStore" id="vv.video.input.store">
+ <object class="GtkListStore" id="video.input.store"> <!-- column-name text -->
<column type="gchararray"/>
@@ -43,7 +43,7 @@
<column type="gchararray"/>
- <object class="GtkListStore" id="vv.video.output.store">
+ <object class="GtkListStore" id="video.output.store"> <!-- column-name text -->
<column type="gchararray"/>
@@ -51,7 +51,7 @@
<column type="gchararray"/>
- <object class="GtkListStore" id="vv.voice.input.store">
+ <object class="GtkListStore" id="voice.input.store"> <!-- column-name text -->
<column type="gchararray"/>
@@ -59,7 +59,7 @@
<column type="gchararray"/>
- <object class="GtkListStore" id="vv.voice.output.store">
+ <object class="GtkListStore" id="voice.output.store"> <!-- column-name text -->
<column type="gchararray"/>
@@ -67,95 +67,173 @@
<column type="gchararray"/>
- <object class="GtkBox" id="vv.page">
+ <template class="PidginVVPrefs" parent="HdyPreferencesPage"> <property name="visible">True</property>
<property name="can-focus">False</property>
- <property name="border-width">12</property>
- <property name="orientation">vertical</property>
- <property name="spacing">18</property>
- <object class="GtkBox">
+ <object class="HdyPreferencesGroup"> <property name="visible">True</property>
<property name="can-focus">False</property>
- <property name="spacing">6</property>
+ <property name="title" translatable="yes">Audio</property> - <object class="GtkFrame">
+ <object class="GtkAlignment"> <property name="visible">True</property>
<property name="can-focus">False</property>
- <property name="label-xalign">0</property>
- <property name="shadow-type">none</property>
+ <property name="left-padding">12</property> - <object class="GtkAlignment">
+ <object class="GtkBox"> <property name="visible">True</property>
<property name="can-focus">False</property>
- <property name="left-padding">12</property>
+ <property name="orientation">vertical</property> + <property name="spacing">6</property> + <object class="GtkFrame"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label-xalign">0</property> + <property name="shadow-type">none</property> + <object class="GtkAlignment"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="left-padding">12</property> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="spacing">6</property> + <object class="GtkLabel" id="label1"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="Device for Audio Input">Device</property> + <property name="xalign">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + <object class="GtkComboBox" id="voice.input.combo"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="id-column">1</property> + <property name="model">voice.input.store</property> + <object class="GtkCellRendererText"/> + <attribute name="text">0</attribute> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="Input for Audio">Input</property> + <attribute name="weight" value="bold"/> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + <object class="GtkFrame"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label-xalign">0</property> + <property name="shadow-type">none</property> + <object class="GtkAlignment"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="left-padding">12</property> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="spacing">6</property> + <object class="GtkLabel" id="label2"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="Device for Audio Output">Device</property> + <property name="xalign">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + <object class="GtkComboBox" id="voice.output.combo"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="id-column">1</property> + <property name="model">voice.output.store</property> + <object class="GtkCellRendererText"/> + <attribute name="text">0</attribute> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="Output for Audio">Output</property> + <attribute name="weight" value="bold"/> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> <property name="visible">True</property>
<property name="can-focus">False</property>
- <property name="orientation">vertical</property>
<property name="spacing">6</property>
- <object class="GtkFrame">
+ <object class="GtkLabel"> <property name="visible">True</property>
<property name="can-focus">False</property>
- <property name="label-xalign">0</property>
- <property name="shadow-type">none</property>
- <object class="GtkAlignment">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="left-padding">12</property>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="spacing">6</property>
- <object class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="label" translatable="yes" context="Device for Audio Input">Device</property>
- <property name="xalign">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- <object class="GtkComboBox" id="vv.voice.input.combo">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="model">vv.voice.input.store</property>
- <object class="GtkCellRendererText"/>
- <attribute name="text">0</attribute>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="label" translatable="yes" context="Input for Audio">Input</property>
- <attribute name="weight" value="bold"/>
+ <property name="label" translatable="yes">Volume:</property> <property name="expand">False</property>
@@ -164,64 +242,31 @@
- <object class="GtkFrame">
+ <object class="GtkVolumeButton" id="voice.volume"> <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="label-xalign">0</property>
- <property name="shadow-type">none</property>
- <object class="GtkAlignment">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="left-padding">12</property>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="spacing">6</property>
- <object class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="label" translatable="yes" context="Device for Audio Output">Device</property>
- <property name="xalign">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- <object class="GtkComboBox" id="vv.voice.output.combo">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="model">vv.voice.output.store</property>
- <object class="GtkCellRendererText"/>
- <attribute name="text">0</attribute>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
+ <property name="can-focus">True</property> + <property name="focus-on-click">False</property> + <property name="receives-default">True</property> + <property name="relief">none</property> + <property name="orientation">vertical</property> + <property name="adjustment">adjustment2</property> + <signal name="value-changed" handler="volume_changed_cb" swapped="no"/> + <child internal-child="plus_button"> + <object class="GtkButton"> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="halign">center</property> + <property name="valign">center</property> + <property name="relief">none</property>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="label" translatable="yes" context="Output for Audio">Output</property>
- <attribute name="weight" value="bold"/>
+ <child internal-child="minus_button"> + <object class="GtkButton"> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="halign">center</property> + <property name="valign">center</property> + <property name="relief">none</property> @@ -231,355 +276,277 @@
<property name="position">1</property>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="spacing">6</property>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="label" translatable="yes">Volume:</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- <object class="GtkVolumeButton" id="vv.voice.volume">
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="focus-on-click">False</property>
- <property name="receives-default">True</property>
- <property name="relief">none</property>
- <property name="orientation">vertical</property>
- <property name="adjustment">adjustment2</property>
- <property name="icons">audio-volume-muted-symbolic
-audio-volume-high-symbolic
-audio-volume-low-symbolic
-audio-volume-medium-symbolic</property>
- <child internal-child="plus_button">
- <object class="GtkButton">
- <property name="can-focus">True</property>
- <property name="receives-default">True</property>
- <property name="halign">center</property>
- <property name="valign">center</property>
- <property name="relief">none</property>
- <child internal-child="minus_button">
- <object class="GtkButton">
- <property name="can-focus">True</property>
- <property name="receives-default">True</property>
- <property name="halign">center</property>
- <property name="valign">center</property>
- <property name="relief">none</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- <object class="GtkLabel" id="vv.voice.threshold_label">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="label" translatable="yes">Silence threshold:</property>
- <property name="xalign">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">3</property>
- <object class="GtkScale" id="vv.voice.threshold">
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="adjustment">adjustment1</property>
- <property name="round-digits">0</property>
- <property name="digits">0</property>
- <property name="draw-value">False</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">4</property>
- <object class="GtkToggleButton" id="vv.voice.test">
- <property name="label" translatable="yes">Test Audio</property>
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="receives-default">True</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">5</property>
- <object class="GtkProgressBar" id="vv.voice.level">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can-focus">False</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">6</property>
+ <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + <object class="GtkLabel" id="voice.threshold_label"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes">Silence threshold:</property> + <property name="xalign">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">3</property> + <object class="GtkScale" id="voice.threshold"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="adjustment">adjustment1</property> + <property name="round-digits">0</property> + <property name="digits">0</property> + <property name="draw-value">False</property> + <signal name="value-changed" handler="threshold_value_changed_cb" object="PidginVVPrefs" swapped="no"/> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">4</property>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="label" translatable="yes">Audio</property>
- <attribute name="weight" value="bold"/>
+ <object class="GtkToggleButton" id="voice.test"> + <property name="label" translatable="yes">Test Audio</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <signal name="toggled" handler="toggle_voice_test_cb" object="PidginVVPrefs" swapped="no"/> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">5</property> + <object class="GtkProgressBar" id="voice.level"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can-focus">False</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">6</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
+ <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + <object class="HdyPreferencesGroup"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="title" translatable="yes">Video</property> - <object class="GtkFrame">
+ <object class="GtkAlignment"> <property name="visible">True</property>
<property name="can-focus">False</property>
- <property name="label-xalign">0</property>
- <property name="shadow-type">none</property>
+ <property name="left-padding">12</property> - <object class="GtkAlignment">
+ <object class="GtkBox"> <property name="visible">True</property>
<property name="can-focus">False</property>
- <property name="left-padding">12</property>
+ <property name="orientation">vertical</property> + <property name="spacing">6</property> - <object class="GtkBox">
+ <object class="GtkFrame"> <property name="visible">True</property>
<property name="can-focus">False</property>
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
+ <property name="label-xalign">0</property> + <property name="shadow-type">none</property> - <object class="GtkFrame">
+ <object class="GtkAlignment"> <property name="visible">True</property>
<property name="can-focus">False</property>
- <property name="label-xalign">0</property>
- <property name="shadow-type">none</property>
+ <property name="left-padding">12</property> - <object class="GtkAlignment">
+ <object class="GtkBox"> <property name="visible">True</property>
<property name="can-focus">False</property>
- <property name="left-padding">12</property>
+ <property name="spacing">6</property> - <object class="GtkBox">
+ <object class="GtkLabel" id="label3"> <property name="visible">True</property>
<property name="can-focus">False</property>
- <property name="spacing">6</property>
- <object class="GtkLabel" id="label3">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="label" translatable="yes" context="Device for Video Input">Device</property>
- <property name="xalign">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
+ <property name="label" translatable="yes" context="Device for Video Input">Device</property> + <property name="xalign">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + <object class="GtkComboBox" id="video.input.combo"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="id-column">1</property> + <property name="model">video.input.store</property> - <object class="GtkComboBox" id="vv.video.input.combo">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="model">vv.video.input.store</property>
- <object class="GtkCellRendererText"/>
- <attribute name="text">0</attribute>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
+ <object class="GtkCellRendererText"/> + <attribute name="text">0</attribute> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="label" translatable="yes" context="Input for Video">Input</property>
- <attribute name="weight" value="bold"/>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- <object class="GtkFrame">
+ <object class="GtkLabel"> <property name="visible">True</property>
<property name="can-focus">False</property>
- <property name="label-xalign">0</property>
- <property name="shadow-type">none</property>
+ <property name="label" translatable="yes" context="Input for Video">Input</property> + <attribute name="weight" value="bold"/> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + <object class="GtkFrame"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label-xalign">0</property> + <property name="shadow-type">none</property> + <object class="GtkAlignment"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="left-padding">12</property> - <object class="GtkAlignment">
+ <object class="GtkBox"> <property name="visible">True</property>
<property name="can-focus">False</property>
- <property name="left-padding">12</property>
+ <property name="spacing">6</property> - <object class="GtkBox">
+ <object class="GtkLabel" id="label4"> <property name="visible">True</property>
<property name="can-focus">False</property>
- <property name="spacing">6</property>
- <object class="GtkLabel" id="label4">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="label" translatable="yes" context="Device for Video Output">Device</property>
- <property name="xalign">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
+ <property name="label" translatable="yes" context="Device for Video Output">Device</property> + <property name="xalign">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + <object class="GtkComboBox" id="video.output.combo"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="id-column">1</property> + <property name="model">video.output.store</property> - <object class="GtkComboBox" id="vv.video.output.combo">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="model">vv.video.output.store</property>
- <object class="GtkCellRendererText"/>
- <attribute name="text">0</attribute>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
+ <object class="GtkCellRendererText"/> + <attribute name="text">0</attribute> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="label" translatable="yes" context="Output for Video">Output</property>
- <attribute name="weight" value="bold"/>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- <object class="GtkAspectFrame" id="vv.video.frame">
+ <object class="GtkLabel"> <property name="visible">True</property>
<property name="can-focus">False</property>
- <property name="label-xalign">0</property>
- <property name="shadow-type">none</property>
- <property name="ratio">1.3300000429153442</property>
+ <property name="label" translatable="yes" context="Output for Video">Output</property> + <attribute name="weight" value="bold"/>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- <object class="GtkToggleButton" id="vv.video.test">
- <property name="label" translatable="yes">Test Video</property>
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="receives-default">True</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">3</property>
+ <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + <object class="GtkAspectFrame" id="video.frame"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label-xalign">0</property> + <property name="shadow-type">none</property> + <property name="ratio">1.33</property> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">2</property> + <object class="GtkToggleButton" id="video.test"> + <property name="label" translatable="yes">Test Video</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <signal name="toggled" handler="toggle_video_test_cb" object="PidginVVPrefs" swapped="no"/> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">3</property>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="label" translatable="yes">Video</property>
- <attribute name="weight" value="bold"/>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
<property name="expand">True</property>
<property name="fill">True</property>
- <property name="position">0</property>
+ <property name="position">1</property>
- <object class="GtkSizeGroup" id="vv.sg">
+ <object class="GtkSizeGroup" id="sg"> --- a/po/POTFILES.in Fri May 20 01:37:47 2022 -0500
+++ b/po/POTFILES.in Fri May 20 02:24:05 2022 -0500
@@ -394,6 +394,7 @@
pidgin/prefs/pidginnetworkpage.c
pidgin/prefs/pidginprefs.c
pidgin/prefs/pidginproxyprefs.c
+pidgin/prefs/pidginvvprefs.c pidgin/resources/About/about.ui
pidgin/resources/Accounts/actionsmenu.ui
pidgin/resources/Accounts/chooser.ui