summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Kareh <[email protected]>2019-08-11 07:04:50 +0300
committerlukefromdc <[email protected]>2019-08-20 04:05:44 +0000
commitc352e1fe2360e4607617cd355d6aac4f41c43425 (patch)
treec7699eed352c6237eb59d539950df71f44adbf00
parent8db7a896b266992a76fc0d3c3785aff926309891 (diff)
downloadmate-media-c352e1fe2360e4607617cd355d6aac4f41c43425.tar.bz2
mate-media-c352e1fe2360e4607617cd355d6aac4f41c43425.tar.xz
applet: Update default output
When a new output device is connected and configured as the default, the mate-volume-control applet (and the status icon) should update the attached control stream. This allows hot-keys and mouse-scroll events to affect the new output device.
-rw-r--r--mate-volume-control/gvc-applet.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/mate-volume-control/gvc-applet.c b/mate-volume-control/gvc-applet.c
index 0c1d5ac..fc41ee6 100644
--- a/mate-volume-control/gvc-applet.c
+++ b/mate-volume-control/gvc-applet.c
@@ -68,6 +68,7 @@ struct _GvcAppletPrivate
GvcStreamAppletIcon *icon_output;
gboolean running;
MateMixerContext *context;
+ MateMixerStream *output;
MateMixerStream *input;
MatePanelApplet *applet;
@@ -174,6 +175,28 @@ update_icon_output (GvcApplet *applet)
}
static void
+on_output_stream_control_added (MateMixerStream *stream,
+ const gchar *name,
+ GvcApplet *applet)
+{
+ MateMixerStreamControl *control;
+
+ control = mate_mixer_stream_get_control (stream, name);
+ if (G_LIKELY (control != NULL)) {
+ MateMixerStreamControlRole role = mate_mixer_stream_control_get_role (control);
+
+ /* Non-application output control doesn't affect the icon */
+ if (role != MATE_MIXER_STREAM_CONTROL_ROLE_APPLICATION)
+ return;
+ }
+
+ /* Either an application control has been added or we couldn't
+ * read the control, this shouldn't happen but let's revalidate the
+ * icon to be sure if it does */
+ update_icon_output (applet);
+}
+
+static void
on_input_stream_control_added (MateMixerStream *stream,
const gchar *name,
GvcApplet *applet)
@@ -196,6 +219,16 @@ on_input_stream_control_added (MateMixerStream *stream,
}
static void
+on_output_stream_control_removed (MateMixerStream *stream,
+ const gchar *name,
+ GvcApplet *applet)
+{
+ /* The removed stream could be an application output, which may cause
+ * the output applet icon to disappear */
+ update_icon_output (applet);
+}
+
+static void
on_input_stream_control_removed (MateMixerStream *stream,
const gchar *name,
GvcApplet *applet)
@@ -206,6 +239,37 @@ on_input_stream_control_removed (MateMixerStream *stream,
}
static gboolean
+update_default_output_stream (GvcApplet *applet)
+{
+ MateMixerStream *stream;
+
+ stream = mate_mixer_context_get_default_output_stream (applet->priv->context);
+ if (stream == applet->priv->output)
+ return FALSE;
+
+ /* The output stream has changed */
+ if (applet->priv->output != NULL) {
+ g_signal_handlers_disconnect_by_data (G_OBJECT (applet->priv->output), applet);
+ g_object_unref (applet->priv->output);
+ }
+
+ applet->priv->output = (stream == NULL) ? NULL : g_object_ref (stream);
+ if (applet->priv->output != NULL) {
+ g_signal_connect (G_OBJECT (applet->priv->output),
+ "control-added",
+ G_CALLBACK (on_output_stream_control_added),
+ applet);
+ g_signal_connect (G_OBJECT (applet->priv->output),
+ "control-removed",
+ G_CALLBACK (on_output_stream_control_removed),
+ applet);
+ }
+
+ /* Return TRUE if the default output stream has changed */
+ return TRUE;
+}
+
+static gboolean
update_default_input_stream (GvcApplet *applet)
{
MateMixerStream *stream;
@@ -249,6 +313,7 @@ on_context_state_notify (MateMixerContext *context,
break;
case MATE_MIXER_STATE_READY:
+ update_default_output_stream (applet);
update_default_input_stream (applet);
/* Each applet change may affect the visibility of the icons */
@@ -276,6 +341,9 @@ on_context_default_output_stream_notify (MateMixerContext *control,
GParamSpec *pspec,
GvcApplet *applet)
{
+ if (update_default_output_stream (applet) == FALSE)
+ return;
+
update_icon_output (applet);
}
@@ -303,6 +371,10 @@ gvc_applet_dispose (GObject *object)
{
GvcApplet *applet = GVC_APPLET (object);
+ if (applet->priv->output != NULL) {
+ g_signal_handlers_disconnect_by_data (G_OBJECT (applet->priv->output), applet);
+ g_clear_object (&applet->priv->output);
+ }
if (applet->priv->input != NULL) {
g_signal_handlers_disconnect_by_data (G_OBJECT (applet->priv->input), applet);
g_clear_object (&applet->priv->input);