From 2830e71e72a1dd38f692cc5b24875d84f7d64a75 Mon Sep 17 00:00:00 2001 From: Zhang Xianwei Date: Tue, 4 Dec 2018 13:16:10 +0800 Subject: media-keys: Add microphone mute key support Pressing the microphone mute button now toggles the mute status. Fix https://github.com/mate-desktop/mate-settings-daemon/issues/175 Signed-off-by: Zhang Xianwei --- ...ettingsDaemon.plugins.media-keys.gschema.xml.in | 5 + plugins/media-keys/acme.h | 2 + plugins/media-keys/msd-media-keys-manager.c | 101 ++++++++++++++++++--- plugins/media-keys/msd-media-keys-window.c | 88 +++++++++++++++--- plugins/media-keys/msd-media-keys-window.h | 2 + 5 files changed, 173 insertions(+), 25 deletions(-) diff --git a/data/org.mate.SettingsDaemon.plugins.media-keys.gschema.xml.in b/data/org.mate.SettingsDaemon.plugins.media-keys.gschema.xml.in index 8983272..2d62556 100644 --- a/data/org.mate.SettingsDaemon.plugins.media-keys.gschema.xml.in +++ b/data/org.mate.SettingsDaemon.plugins.media-keys.gschema.xml.in @@ -55,6 +55,11 @@ Turn the volume up quietly Binding to raise the system volume quietly. + + 'XF86AudioMicMute' + Microphone mute/unmute + Binding to mute/unmute the microphone. + '<Control><Alt>Delete' Shut down diff --git a/plugins/media-keys/acme.h b/plugins/media-keys/acme.h index 8d6aba2..fa64cbb 100644 --- a/plugins/media-keys/acme.h +++ b/plugins/media-keys/acme.h @@ -35,6 +35,7 @@ enum { MUTE_QUIET_KEY, VOLUME_DOWN_QUIET_KEY, VOLUME_UP_QUIET_KEY, + MIC_MUTE_KEY, POWER_KEY, EJECT_KEY, HOME_KEY, @@ -80,6 +81,7 @@ static struct { { MUTE_QUIET_KEY, "volume-mute-quiet", NULL, NULL }, { VOLUME_DOWN_QUIET_KEY, "volume-down-quiet", NULL, NULL }, { VOLUME_UP_QUIET_KEY, "volume-up-quiet", NULL, NULL }, + { MIC_MUTE_KEY, "mic-mute", NULL, NULL }, { POWER_KEY, "power", NULL, NULL }, { EJECT_KEY, "eject", NULL, NULL }, { HOME_KEY, "home", NULL, NULL }, diff --git a/plugins/media-keys/msd-media-keys-manager.c b/plugins/media-keys/msd-media-keys-manager.c index 33ac891..7a82cab 100644 --- a/plugins/media-keys/msd-media-keys-manager.c +++ b/plugins/media-keys/msd-media-keys-manager.c @@ -73,7 +73,9 @@ struct _MsdMediaKeysManagerPrivate /* Volume bits */ MateMixerContext *context; MateMixerStream *stream; + MateMixerStream *source_stream; MateMixerStreamControl *control; + MateMixerStreamControl *source_control; #endif GtkWidget *dialog; GSettings *settings; @@ -635,15 +637,21 @@ update_dialog (MsdMediaKeysManager *manager, guint volume, gboolean muted, gboolean sound_changed, - gboolean quiet) + gboolean quiet, + gboolean is_mic) { if (muted) volume = 0.0; dialog_init (manager); - msd_media_keys_window_set_volume_muted (MSD_MEDIA_KEYS_WINDOW (manager->priv->dialog), - muted); + if (is_mic) + msd_media_keys_window_set_mic_muted (MSD_MEDIA_KEYS_WINDOW (manager->priv->dialog), + muted); + else + msd_media_keys_window_set_volume_muted (MSD_MEDIA_KEYS_WINDOW (manager->priv->dialog), + muted); + msd_media_keys_window_set_volume_level (MSD_MEDIA_KEYS_WINDOW (manager->priv->dialog), volume); @@ -652,7 +660,7 @@ update_dialog (MsdMediaKeysManager *manager, dialog_show (manager); #ifdef HAVE_LIBCANBERRA - if (quiet == FALSE && sound_changed != FALSE && muted == FALSE) + if (quiet == FALSE && sound_changed != FALSE && muted == FALSE && is_mic == FALSE) ca_gtk_play_for_widget (manager->priv->dialog, 0, CA_PROP_EVENT_ID, "audio-volume-change", CA_PROP_EVENT_DESCRIPTION, "Volume changed through key press", @@ -675,14 +683,21 @@ do_sound_action (MsdMediaKeysManager *manager, guint volume_min, volume_max; guint volume_step; guint volume_last; + MateMixerStreamControl *control; - if (manager->priv->control == NULL) + gboolean is_input_control = + type == MIC_MUTE_KEY ? TRUE : FALSE; + if (is_input_control) + control = manager->priv->source_control; + else + control = manager->priv->control; + if (control == NULL) return; /* Theoretically the volume limits might be different for different * streams, also the minimum might not always start at 0 */ - volume_min = mate_mixer_stream_control_get_min_volume (manager->priv->control); - volume_max = mate_mixer_stream_control_get_normal_volume (manager->priv->control); + volume_min = mate_mixer_stream_control_get_min_volume (control); + volume_max = mate_mixer_stream_control_get_normal_volume (control); volume_step = g_settings_get_int (manager->priv->settings, "volume-step"); if (volume_step <= 0 || @@ -693,12 +708,13 @@ do_sound_action (MsdMediaKeysManager *manager, volume_step = (volume_max - volume_min) * volume_step / 100; volume = volume_last = - mate_mixer_stream_control_get_volume (manager->priv->control); + mate_mixer_stream_control_get_volume (control); muted = muted_last = - mate_mixer_stream_control_get_mute (manager->priv->control); + mate_mixer_stream_control_get_mute (control); switch (type) { case MUTE_KEY: + case MIC_MUTE_KEY: muted = !muted; break; case VOLUME_DOWN_KEY: @@ -723,13 +739,14 @@ do_sound_action (MsdMediaKeysManager *manager, } if (muted != muted_last) { - if (mate_mixer_stream_control_set_mute (manager->priv->control, muted)) + if (mate_mixer_stream_control_set_mute (control, muted)) sound_changed = TRUE; else muted = muted_last; } - if (volume != mate_mixer_stream_control_get_volume (manager->priv->control)) { - if (mate_mixer_stream_control_set_volume (manager->priv->control, volume)) + + if (volume != mate_mixer_stream_control_get_volume (control)) { + if (mate_mixer_stream_control_set_volume (control, volume)) sound_changed = TRUE; else volume = volume_last; @@ -739,7 +756,8 @@ do_sound_action (MsdMediaKeysManager *manager, CLAMP (100 * volume / (volume_max - volume_min), 0, 100), muted, sound_changed, - quiet); + quiet, + is_input_control); } static void @@ -775,12 +793,45 @@ update_default_output (MsdMediaKeysManager *manager) g_debug ("Default output stream unset"); } +static void +update_default_input (MsdMediaKeysManager *manager) +{ + MateMixerStream *stream; + MateMixerStreamControl *control = NULL; + + stream = mate_mixer_context_get_default_input_stream (manager->priv->context); + if (stream != NULL) + control = mate_mixer_stream_get_default_control (stream); + + if (stream == manager->priv->source_stream) + return; + + g_clear_object (&manager->priv->source_stream); + g_clear_object (&manager->priv->source_control); + + if (control != NULL) { + MateMixerStreamControlFlags flags = mate_mixer_stream_control_get_flags (control); + + /* Do not use the stream if it is not possible to mute it or + * change the volume */ + if (!(flags & MATE_MIXER_STREAM_CONTROL_MUTE_WRITABLE)) + return; + + manager->priv->source_stream = g_object_ref (stream); + manager->priv->source_control = g_object_ref (control); + g_debug ("Default input stream updated to %s", + mate_mixer_stream_get_name (stream)); + } else + g_debug ("Default input stream unset"); +} + static void on_context_state_notify (MateMixerContext *context, GParamSpec *pspec, MsdMediaKeysManager *manager) { update_default_output (manager); + update_default_input (manager); } static void @@ -791,6 +842,14 @@ on_context_default_output_notify (MateMixerContext *context, update_default_output (manager); } +static void +on_context_default_input_notify (MateMixerContext *context, + GParamSpec *pspec, + MsdMediaKeysManager *manager) +{ + update_default_input (manager); +} + static void on_context_stream_removed (MateMixerContext *context, const gchar *name, @@ -805,6 +864,15 @@ on_context_stream_removed (MateMixerContext *context, g_clear_object (&manager->priv->control); } } + if (manager->priv->source_stream != NULL) { + MateMixerStream *stream = + mate_mixer_context_get_stream (manager->priv->context, name); + + if (stream == manager->priv->source_stream) { + g_clear_object (&manager->priv->source_stream); + g_clear_object (&manager->priv->source_control); + } + } } #endif /* HAVE_LIBMATEMIXER */ @@ -1102,6 +1170,7 @@ do_action (MsdMediaKeysManager *manager, case MUTE_KEY: case VOLUME_DOWN_KEY: case VOLUME_UP_KEY: + case MIC_MUTE_KEY: #ifdef HAVE_LIBMATEMIXER do_sound_action (manager, type, FALSE); #endif @@ -1398,6 +1467,10 @@ msd_media_keys_manager_start (MsdMediaKeysManager *manager, GError **error) "notify::default-output-stream", G_CALLBACK (on_context_default_output_notify), manager); + g_signal_connect (manager->priv->context, + "notify::default-input-stream", + G_CALLBACK (on_context_default_input_notify), + manager); g_signal_connect (manager->priv->context, "stream-removed", G_CALLBACK (on_context_stream_removed), @@ -1483,7 +1556,9 @@ msd_media_keys_manager_stop (MsdMediaKeysManager *manager) #ifdef HAVE_LIBMATEMIXER g_clear_object (&priv->stream); + g_clear_object (&priv->source_stream); g_clear_object (&priv->control); + g_clear_object (&priv->source_control); g_clear_object (&priv->context); #endif diff --git a/plugins/media-keys/msd-media-keys-window.c b/plugins/media-keys/msd-media-keys-window.c index 3f87bd0..dfe180d 100644 --- a/plugins/media-keys/msd-media-keys-window.c +++ b/plugins/media-keys/msd-media-keys-window.c @@ -43,6 +43,8 @@ struct MsdMediaKeysWindowPrivate char *description; guint volume_muted : 1; + guint mic_muted : 1; + guint is_mic :1; int volume_level; GtkImage *image; @@ -98,10 +100,16 @@ action_changed (MsdMediaKeysWindow *window) volume_controls_set_visible (window, TRUE); description_label_set_visible (window, FALSE); - if (window->priv->volume_muted) { - window_set_icon_name (window, "audio-volume-muted"); + if (window->priv->is_mic) { + if (window->priv->mic_muted) + window_set_icon_name (window, "microphone-sensitivity-muted"); + else + window_set_icon_name (window, "microphone-sensitivity-high"); } else { - window_set_icon_name (window, "audio-volume-high"); + if (window->priv->volume_muted) + window_set_icon_name (window, "audio-volume-muted"); + else + window_set_icon_name (window, "audio-volume-high"); } break; @@ -148,6 +156,20 @@ volume_muted_changed (MsdMediaKeysWindow *window) } } +static void +mic_muted_changed (MsdMediaKeysWindow *window) +{ + msd_osd_window_update_and_hide (MSD_OSD_WINDOW (window)); + + if (!msd_osd_window_is_composited (MSD_OSD_WINDOW (window))) { + if (window->priv->mic_muted) { + window_set_icon_name (window, "microphone-sensitivity-muted"); + } else { + window_set_icon_name (window, "microphone-sensitivity-high"); + } + } +} + void msd_media_keys_window_set_action (MsdMediaKeysWindow *window, MsdMediaKeysWindowAction action) @@ -159,6 +181,17 @@ msd_media_keys_window_set_action (MsdMediaKeysWindow *window, window->priv->action = action; action_changed (window); } else { + if (window->priv->is_mic) { + if (window->priv->mic_muted) + window_set_icon_name (window, "microphone-sensitivity-muted"); + else + window_set_icon_name (window, "microphone-sensitivity-high"); + } else { + if (window->priv->volume_muted) + window_set_icon_name (window, "audio-volume-muted"); + else + window_set_icon_name (window, "audio-volume-high"); + } msd_osd_window_update_and_hide (MSD_OSD_WINDOW (window)); } } @@ -195,6 +228,20 @@ msd_media_keys_window_set_volume_muted (MsdMediaKeysWindow *window, window->priv->volume_muted = muted; volume_muted_changed (window); } + window->priv->is_mic = FALSE; +} + +void +msd_media_keys_window_set_mic_muted (MsdMediaKeysWindow *window, + gboolean muted) +{ + g_return_if_fail (MSD_IS_MEDIA_KEYS_WINDOW (window)); + + if (window->priv->mic_muted != muted) { + window->priv->mic_muted = muted; + mic_muted_changed (window); + } + window->priv->is_mic = TRUE; } void @@ -379,18 +426,35 @@ render_speaker (MsdMediaKeysWindow *window, "audio-volume-low", "audio-volume-medium", "audio-volume-high", + "microphone-sensitivity-muted", + "microphone-sensitivity-low", + "microphone-sensitivity-medium", + "microphone-sensitivity-high", NULL }; - - if (window->priv->volume_muted) { - n = 0; + if (!window->priv->is_mic) { + if (window->priv->volume_muted) { + n = 0; + } else { + /* select volume image */ + n = 3 * window->priv->volume_level / 100 + 1; + if (n < 1) { + n = 1; + } else if (n > 3) { + n = 3; + } + } } else { - /* select image */ - n = 3 * window->priv->volume_level / 100 + 1; - if (n < 1) { - n = 1; - } else if (n > 3) { - n = 3; + if (window->priv->mic_muted) { + n = 4; + } else { + /* select microphone image */ + n = 3 * window->priv->volume_level / 100 + 5; + if (n < 5) { + n = 5; + } else if (n > 7) { + n = 7; + } } } diff --git a/plugins/media-keys/msd-media-keys-window.h b/plugins/media-keys/msd-media-keys-window.h index 228da32..88c3748 100644 --- a/plugins/media-keys/msd-media-keys-window.h +++ b/plugins/media-keys/msd-media-keys-window.h @@ -65,6 +65,8 @@ void msd_media_keys_window_set_action (MsdMediaKeysWindo void msd_media_keys_window_set_action_custom (MsdMediaKeysWindow *window, const char *icon_name, const char *description); +void msd_media_keys_window_set_mic_muted (MsdMediaKeysWindow *window, + gboolean muted); void msd_media_keys_window_set_volume_muted (MsdMediaKeysWindow *window, gboolean muted); void msd_media_keys_window_set_volume_level (MsdMediaKeysWindow *window, -- cgit v1.2.1