From c7de79dbec126e167bcb403a9c6faf7eb3a67854 Mon Sep 17 00:00:00 2001 From: "Clarence \"Sparr\" Risher" Date: Mon, 5 Sep 2022 08:38:51 -0400 Subject: [PATCH 1/2] Replace middle click mute with output cycling --- panel-plugin/pulseaudio-button.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/panel-plugin/pulseaudio-button.c b/panel-plugin/pulseaudio-button.c index ba92097..b2e4a61 100644 --- a/panel-plugin/pulseaudio-button.c +++ b/panel-plugin/pulseaudio-button.c @@ -239,7 +239,29 @@ G_GNUC_END_IGNORE_DEPRECATIONS if (event->button == 2) /* middle button */ { - pulseaudio_volume_toggle_muted (button->volume); + // pulseaudio_volume_toggle_muted (button->volume); + + GList *sources = NULL; + GList *list = NULL; + const gchar *default_output_name = NULL; + sources = pulseaudio_volume_get_output_list (button->volume); + if (g_list_length (sources) > 1) + { + default_output_name = pulseaudio_volume_get_default_output(button->volume); + for (list = sources; list != NULL; list = g_list_next(list)) + { + if (g_strcmp0((gchar *)list->data, default_output_name) == 0) { + list = g_list_next(list); + if (list == NULL) { list = sources; } + break; + } + } + if (list != NULL) { + pulseaudio_volume_set_default_output (button->volume, (gchar *)list->data); + } + } + g_list_free (sources); + return TRUE; } -- GitLab From 945fe2c2640e8ae4e3a5cce4a68cf1640fb81135 Mon Sep 17 00:00:00 2001 From: "Clarence \"Sparr\" Risher" Date: Mon, 5 Sep 2022 08:40:17 -0400 Subject: [PATCH 2/2] Implement configuration option for middle click action. BROKEN --- panel-plugin/pulseaudio-config.c | 62 +++++++++++++++++++++++++++ panel-plugin/pulseaudio-config.h | 14 +++++++ panel-plugin/pulseaudio-dialog.c | 63 ++++++++++++++++++++++++++++ panel-plugin/pulseaudio-dialog.glade | 43 +++++++++++++++++++ 4 files changed, 182 insertions(+) diff --git a/panel-plugin/pulseaudio-config.c b/panel-plugin/pulseaudio-config.c index e2767bc..3c13f65 100644 --- a/panel-plugin/pulseaudio-config.c +++ b/panel-plugin/pulseaudio-config.c @@ -60,6 +60,8 @@ #define DEFAULT_MPRIS_PLAYERS "" #define DEFAULT_ENABLE_WNCK FALSE +#define DEFAULT_MIDDLE_CLICK_ACTION 0 + static void pulseaudio_config_finalize (GObject *object); @@ -93,6 +95,7 @@ struct _PulseaudioConfig gchar *mpris_players; gchar *blacklisted_players; gboolean enable_wnck; + gint middle_click_action; }; @@ -110,6 +113,7 @@ enum PROP_MPRIS_PLAYERS, PROP_BLACKLISTED_PLAYERS, PROP_ENABLE_WNCK, + PROP_MIDDLE_CLICK_ACTION, N_PROPERTIES, }; @@ -230,6 +234,14 @@ pulseaudio_config_class_init (PulseaudioConfigClass *klass) + g_object_class_install_property (gobject_class, + PROP_MIDDLE_CLICK_ACTION, + g_param_spec_enum ("middle-click-action", NULL, NULL, + middle_click_action_get_type(), + DEFAULT_MIDDLE_CLICK_ACTION, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + pulseaudio_config_signals[CONFIGURATION_CHANGED] = g_signal_new (g_intern_static_string ("configuration-changed"), G_TYPE_FROM_CLASS (gobject_class), @@ -254,6 +266,7 @@ pulseaudio_config_init (PulseaudioConfig *config) config->mpris_players = g_strdup (DEFAULT_MPRIS_PLAYERS); config->blacklisted_players = g_strdup (DEFAULT_BLACKLISTED_PLAYERS); config->enable_wnck = DEFAULT_ENABLE_WNCK; + config->middle_click_action = DEFAULT_MIDDLE_CLICK_ACTION; } @@ -321,6 +334,10 @@ pulseaudio_config_get_property (GObject *object, g_value_set_boolean (value, config->enable_wnck); break; + case PROP_MIDDLE_CLICK_ACTION: + g_value_set_enum (value, config->middle_click_action); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -336,6 +353,7 @@ pulseaudio_config_set_property (GObject *object, GParamSpec *pspec) { PulseaudioConfig *config = PULSEAUDIO_CONFIG (object); + gint val_int; guint val_uint; gboolean val_bool; @@ -440,6 +458,17 @@ pulseaudio_config_set_property (GObject *object, } break; + case PROP_MIDDLE_CLICK_ACTION: + val_int = g_value_get_enum (value); + + if (config->middle_click_action != val_int) + { + config->middle_click_action = val_int; + g_object_notify (G_OBJECT (config), "middle-click-action"); + g_signal_emit (G_OBJECT (config), pulseaudio_config_signals [CONFIGURATION_CHANGED], 0); + } + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -800,6 +829,13 @@ pulseaudio_config_get_can_raise_wnck (PulseaudioConfig *config) +MiddleClickAction +pulseaudio_config_get_middle_click_action (PulseaudioConfig *config) +{ + return config->middle_click_action; +} + + PulseaudioConfig * pulseaudio_config_new (const gchar *property_base) { @@ -853,9 +889,35 @@ pulseaudio_config_new (const gchar *property_base) xfconf_g_property_bind (channel, property, G_TYPE_BOOLEAN, config, "enable-wnck"); g_free (property); + property = g_strconcat (property_base, "/middle-click-action", NULL); + xfconf_g_property_bind (channel, property, G_TYPE_ENUM, config, "middle-click-action"); + g_free (property); + g_object_notify (G_OBJECT (config), "enable-keyboard-shortcuts"); g_signal_emit (G_OBJECT (config), pulseaudio_config_signals [CONFIGURATION_CHANGED], 0); } return config; } + +/* enumerations from "pulseaudio-config.h" */ +GType +middle_click_action_get_type (void) +{ + static gsize static_g_enum_type_id; + + if (g_once_init_enter (&static_g_enum_type_id)) + { + static const GEnumValue values[] = { + { TOGGLEMUTED, "TOGGLEMUTED", "togglemuted" }, + { CYCLEOUTPUTS, "CYCLEOUTPUTS", "cycleoutputs" }, + { 0, NULL, NULL } + }; + + GType g_enum_type_id = + g_enum_register_static (g_intern_static_string ("MiddleClickAction"), values); + + g_once_init_leave (&static_g_enum_type_id, g_enum_type_id); + } + return static_g_enum_type_id; +} \ No newline at end of file diff --git a/panel-plugin/pulseaudio-config.h b/panel-plugin/pulseaudio-config.h index 7ab2964..74ca3af 100644 --- a/panel-plugin/pulseaudio-config.h +++ b/panel-plugin/pulseaudio-config.h @@ -34,6 +34,18 @@ typedef struct _PulseaudioConfig PulseaudioConfig; #define IS_PULSEAUDIO_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_PULSEAUDIO_CONFIG)) #define PULSEAUDIO_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_PULSEAUDIO_CONFIG, PulseaudioConfigClass)) +/** + * MiddleClickAction: + * @TOGGLEMUTED: Toggle the volume mute on/off + * @CYCLEOUTPUTS: Change to the output after the currently selected one + */ +typedef enum { + TOGGLEMUTED, + CYCLEOUTPUTS, +} MiddleClickAction; +GType middle_click_action_get_type (void) G_GNUC_CONST; +#define MIDDLE_CLICK_ACTION_TYPE (middle_click_action_get_type ()) + GType pulseaudio_config_get_type (void) G_GNUC_CONST; PulseaudioConfig *pulseaudio_config_new (const gchar *property_base); @@ -65,6 +77,8 @@ void pulseaudio_config_set_can_raise_wnck (PulseaudioC gboolean can_raise); gboolean pulseaudio_config_get_can_raise_wnck (PulseaudioConfig *config); +MiddleClickAction pulseaudio_config_get_middle_click_action (PulseaudioConfig *config); + G_END_DECLS #endif /* !__PULSEAUDIO_CONFIG_H__ */ diff --git a/panel-plugin/pulseaudio-dialog.c b/panel-plugin/pulseaudio-dialog.c index 1403d96..b2c850d 100644 --- a/panel-plugin/pulseaudio-dialog.c +++ b/panel-plugin/pulseaudio-dialog.c @@ -197,6 +197,47 @@ pulseaudio_dialog_clear_players_cb (GtkButton *button, } +//FIXME hard coding the false condition will break as soon as there are three options +static gboolean +middle_click_radio_bool_to_enum0 (GBinding *binding, + const GValue *from, + GValue *to, + gpointer user_data) +{ + *(gint*)to->data = (*(gboolean*)from->data) ? TOGGLEMUTED : CYCLEOUTPUTS; + return TRUE; +} + +static gboolean +middle_click_radio_bool_to_enum1 (GBinding *binding, + const GValue *from, + GValue *to, + gpointer user_data) +{ + *(gint*)to->data = (*(gboolean*)from->data) ? CYCLEOUTPUTS : TOGGLEMUTED; + return TRUE; +} + +static gboolean +middle_click_radio_enum0_to_bool (GBinding *binding, + const GValue *from, + GValue *to, + gpointer user_data) +{ + *(gboolean*)to->data = (*(gint*)from->data == TOGGLEMUTED); + return TRUE; +} + +static gboolean +middle_click_radio_enum1_to_bool (GBinding *binding, + const GValue *from, + GValue *to, + gpointer user_data) +{ + *(gboolean*)to->data = (*(gint*)from->data == CYCLEOUTPUTS); + return TRUE; +} + static void pulseaudio_dialog_build (PulseaudioDialog *dialog) @@ -247,6 +288,28 @@ pulseaudio_dialog_build (PulseaudioDialog *dialog) gtk_widget_set_visible (GTK_WIDGET (object), FALSE); #endif + // FIXME figure out how to properly bind multiple radio buttons to the same enum property + object = gtk_builder_get_object (builder, "radiobutton-middle-click-action-toggle-mute"); + g_return_if_fail (GTK_IS_RADIO_BUTTON (object)); + // FIXME this binding doesn't work, clicking the radio buttons produces the following error: + // (wrapper-2.0:492812): xfconf-CRITICAL **: 01:11:14.622: IA__xfconf_channel_set_property: assertion 'XFCONF_IS_CHANNEL(channel) && property && G_IS_VALUE(value)' failed + // and no xfconf property for middle-click-action is ever created + g_object_bind_property_full (G_OBJECT (dialog->config), "middle-click-action", + G_OBJECT (object), "active", + G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL, + middle_click_radio_enum0_to_bool, + middle_click_radio_bool_to_enum0, + NULL, NULL); + + object = gtk_builder_get_object (builder, "radiobutton-middle-click-action-cycle-outputs"); + g_return_if_fail (GTK_IS_RADIO_BUTTON (object)); + g_object_bind_property_full (G_OBJECT (dialog->config), "middle-click-action", + G_OBJECT (object), "active", + G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL, + middle_click_radio_enum1_to_bool, + middle_click_radio_bool_to_enum1, + NULL, NULL); + object = gtk_builder_get_object (builder, "entry-mixer-command"); g_return_if_fail (GTK_IS_ENTRY (object)); g_object_bind_property (G_OBJECT (dialog->config), "mixer-command", diff --git a/panel-plugin/pulseaudio-dialog.glade b/panel-plugin/pulseaudio-dialog.glade index 019dcbc..b0cd930 100644 --- a/panel-plugin/pulseaudio-dialog.glade +++ b/panel-plugin/pulseaudio-dialog.glade @@ -144,6 +144,49 @@ 1 + + + True + False + vertical + 6 + + + Middle click toggles mute + True + True + False + Middle click on the plugin icon in the panel will mute or unmute the volume. + start + True + True + + + True + True + 0 + + + + + Middle click cycles outputs + True + True + False + Middle click on the plugin icon in the panel will switch to the next output device. + start + True + True + radiobutton-middle-click-action-toggle-mute + + + True + True + 1 + + + + -- GitLab