diff options
Diffstat (limited to 'plugins/media-keys/msd-media-keys-manager.c')
-rw-r--r-- | plugins/media-keys/msd-media-keys-manager.c | 526 |
1 files changed, 319 insertions, 207 deletions
diff --git a/plugins/media-keys/msd-media-keys-manager.c b/plugins/media-keys/msd-media-keys-manager.c index f5b97c3..5ab8946 100644 --- a/plugins/media-keys/msd-media-keys-manager.c +++ b/plugins/media-keys/msd-media-keys-manager.c @@ -1,9 +1,9 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * vim: set ts=8 sts=8 sw=8 expandtab: * * Copyright (C) 2001-2003 Bastien Nocera <[email protected]> * Copyright (C) 2006-2007 William Jon McCann <[email protected]> * Copyright (C) 2014 Michal Ratajsky <[email protected]> + * Copyright (C) 2012-2021 MATE Developers * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -41,7 +41,6 @@ #include "mate-settings-profile.h" #include "msd-marshal.h" #include "msd-media-keys-manager.h" -#include "msd-media-keys-generated.h" #include "eggaccelerators.h" #include "acme.h" @@ -56,9 +55,28 @@ #define TOUCHPAD_SCHEMA "org.mate.peripherals-touchpad" #define TOUCHPAD_ENABLED_KEY "touchpad-enabled" +#define SOUND_SCHEMA "org.mate.sound" +#define VOLUME_OVERAMPLIFIABLE_KEY "volume-overamplifiable" + +static const gchar introspection_xml[] = +"<node name='/org/mate/SettingsDaemon/MediaKeys'>" +" <interface name='org.mate.SettingsDaemon.MediaKeys'>" +" <method name='GrabMediaPlayerKeys'>" +" <arg name='application' direction='in' type='s'/>" +" <arg name='time' direction='in' type='u'/>" +" </method>" +" <method name='ReleaseMediaPlayerKeys'>" +" <arg name='application' direction='in' type='s'/>" +" </method>" +" <signal name='MediaPlayerKeyPressed'/>" +" </interface>" +"</node>"; + typedef struct { char *application; + char *dbus_name; guint32 time; + guint watch_id; } MediaPlayer; struct _MsdMediaKeysManagerPrivate @@ -73,6 +91,7 @@ struct _MsdMediaKeysManagerPrivate #endif GtkWidget *dialog; GSettings *settings; + GSettings *sound_settings; GVolumeMonitor *volume_monitor; /* Multihead stuff */ @@ -86,31 +105,20 @@ struct _MsdMediaKeysManagerPrivate GList *media_players; + GDBusNodeInfo *introspection_data; GDBusConnection *connection; - guint bus_name_id; - MateSettingsMediaKeys *skeleton; + GCancellable *bus_cancellable; - guint notify[HANDLED_KEYS]; -}; + guint start_idle_id; -enum { - MEDIA_PLAYER_KEY_PRESSED, - LAST_SIGNAL + guint owner_id; + guint notify[HANDLED_KEYS]; }; -static guint signals[LAST_SIGNAL] = { 0 }; G_DEFINE_TYPE_WITH_PRIVATE (MsdMediaKeysManager, msd_media_keys_manager, G_TYPE_OBJECT) static gpointer manager_object = NULL; -static gboolean on_grab_media_player_keys (MateSettingsMediaKeys *object, - GDBusMethodInvocation *invocation, - const gchar *application, - guint time, - gpointer user_data); -static gboolean on_release_media_player_keys (MateSettingsMediaKeys *object, - GDBusMethodInvocation *invocation, - const gchar *application, - gpointer user_data); +static void register_manager (MsdMediaKeysManager *manager); static void init_screens (MsdMediaKeysManager *manager) @@ -139,7 +147,7 @@ acme_error (char * msg) GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, - msg, NULL); + "%s", msg); gtk_dialog_set_default_response (GTK_DIALOG (error_dialog), GTK_RESPONSE_OK); gtk_widget_show (error_dialog); @@ -329,8 +337,7 @@ update_kbd_cb (GSettings *settings, g_warning ("Grab failed for some keys, another application may already have access the them."); } -static void -init_kbd (MsdMediaKeysManager* manager) +static void init_kbd(MsdMediaKeysManager* manager) { int i; GdkDisplay *dpy; @@ -486,26 +493,31 @@ dialog_show (MsdMediaKeysManager *manager) } static void +launch_default_for_uri_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GError *error = NULL; + gchar *uri = user_data; + + if (!g_app_info_launch_default_for_uri_finish (res, &error)) + { + g_warning ("Could not launch '%s': %s", uri, + error->message); + g_clear_error (&error); + } + g_free (uri); +} + +static void do_url_action (MsdMediaKeysManager *manager, const gchar *scheme) { - GError *error = NULL; - GAppInfo *app_info; - - app_info = g_app_info_get_default_for_uri_scheme (scheme); - - if (app_info != NULL) { - if (!g_app_info_launch (app_info, NULL, NULL, &error)) { - g_warning ("Could not launch '%s': %s", - g_app_info_get_commandline (app_info), - error->message); - g_object_unref (app_info); - g_error_free (error); - } - } - else { - g_warning ("Could not find default application for '%s' scheme", scheme); - } + g_app_info_launch_default_for_uri_async (scheme, + NULL, + NULL, + launch_default_for_uri_cb, + g_strdup (scheme)); } static void @@ -610,7 +622,6 @@ do_eject_action (MsdMediaKeysManager *manager) continue; if (score < SCORE_HAS_MEDIA) { fav_drive = drive; - score = SCORE_HAS_MEDIA; break; } } @@ -627,7 +638,7 @@ do_eject_action (MsdMediaKeysManager *manager) if (fav_drive != NULL) fav_drive = g_object_ref (fav_drive); - g_list_foreach (drives, (GFunc) g_object_unref, NULL); + g_list_free_full (drives, g_object_unref); if (fav_drive == NULL) return; @@ -676,7 +687,7 @@ update_dialog (MsdMediaKeysManager *manager, gboolean is_mic) { if (muted) - volume = 0.0; + volume = 0; dialog_init (manager); @@ -716,7 +727,8 @@ do_sound_action (MsdMediaKeysManager *manager, gboolean sound_changed = FALSE; guint volume; guint volume_min, volume_max; - guint volume_step; + gint volume_step; + guint volume_step_scaled; guint volume_last; MateMixerStreamControl *control; @@ -732,17 +744,21 @@ do_sound_action (MsdMediaKeysManager *manager, /* 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 (control); - volume_max = mate_mixer_stream_control_get_normal_volume (control); + if (g_settings_get_boolean (manager->priv->sound_settings, VOLUME_OVERAMPLIFIABLE_KEY)) + volume_max = mate_mixer_stream_control_get_max_volume (control); + else + 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 || volume_step > 100) { GVariant *variant = g_settings_get_default_value (manager->priv->settings, "volume-step"); - volume_step = g_variant_get_int32 (variant); + gint32 volume_step_default = g_variant_get_int32 (variant); + volume_step = (gint) volume_step_default; g_variant_unref (variant); } /* Scale the volume step size accordingly to the range used by the control */ - volume_step = (volume_max - volume_min) * volume_step / 100; + volume_step_scaled = (volume_max - volume_min) * (guint) volume_step / 100; volume = volume_last = mate_mixer_stream_control_get_volume (control); @@ -755,11 +771,11 @@ do_sound_action (MsdMediaKeysManager *manager, muted = !muted; break; case VOLUME_DOWN_KEY: - if (volume <= (volume_min + volume_step)) { + if (volume <= (volume_min + volume_step_scaled)) { volume = volume_min; muted = TRUE; } else { - volume -= volume_step; + volume -= volume_step_scaled; muted = FALSE; } break; @@ -767,9 +783,9 @@ do_sound_action (MsdMediaKeysManager *manager, if (muted) { muted = FALSE; if (volume <= volume_min) - volume = volume_min + volume_step; + volume = volume_min + volume_step_scaled; } else - volume = CLAMP (volume + volume_step, + volume = CLAMP (volume + volume_step_scaled, volume_min, volume_max); break; @@ -1048,6 +1064,18 @@ do_display_osd_action (MsdMediaKeysManager *manager) dialog_show (manager); } +static void +free_media_player (MediaPlayer *player) +{ + if (player->watch_id > 0) { + g_bus_unwatch_name (player->watch_id); + player->watch_id = 0; + } + g_free (player->application); + g_free (player->dbus_name); + g_free (player); +} + static gint find_by_application (gconstpointer a, gconstpointer b) @@ -1056,16 +1084,131 @@ find_by_application (gconstpointer a, } static gint +find_by_name (gconstpointer a, + gconstpointer b) +{ + return strcmp (((MediaPlayer *)a)->dbus_name, b); +} + +static gint find_by_time (gconstpointer a, gconstpointer b) { return ((MediaPlayer *)a)->time < ((MediaPlayer *)b)->time; } +static void +name_vanished_handler (GDBusConnection *connection, + const gchar *name, + MsdMediaKeysManager *manager) +{ + GList *iter; + + iter = g_list_find_custom (manager->priv->media_players, + name, + find_by_name); + + if (iter != NULL) { + MediaPlayer *player; + + player = iter->data; + g_debug ("Deregistering vanished %s (dbus_name: %s)", player->application, player->dbus_name); + free_media_player (player); + manager->priv->media_players = g_list_delete_link (manager->priv->media_players, iter); + } +} + +/* + * Register a new media player. Most applications will want to call + * this with time = GDK_CURRENT_TIME. This way, the last registered + * player will receive media events. In some cases, applications + * may want to register with a lower priority (usually 1), to grab + * events only nobody is interested. + */ +static void +msd_media_keys_manager_grab_media_player_keys (MsdMediaKeysManager *manager, + const char *application, + const char *dbus_name, + guint32 time) +{ + GList *iter; + MediaPlayer *media_player; + guint watch_id; + + if (time == GDK_CURRENT_TIME) { + time = (guint32)(g_get_monotonic_time () / 1000); + } + + iter = g_list_find_custom (manager->priv->media_players, + application, + find_by_application); + + if (iter != NULL) { + if (((MediaPlayer *)iter->data)->time < time) { + MediaPlayer *player = iter->data; + free_media_player (player); + manager->priv->media_players = g_list_delete_link (manager->priv->media_players, iter); + } else { + return; + } + } + + watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION, + dbus_name, + G_BUS_NAME_WATCHER_FLAGS_NONE, + NULL, + (GBusNameVanishedCallback) name_vanished_handler, + manager, + NULL); + + g_debug ("Registering %s at %u", application, time); + media_player = g_new0 (MediaPlayer, 1); + media_player->application = g_strdup (application); + media_player->dbus_name = g_strdup (dbus_name); + media_player->time = time; + media_player->watch_id = watch_id; + + manager->priv->media_players = g_list_insert_sorted (manager->priv->media_players, + media_player, + find_by_time); +} + +static void +msd_media_keys_manager_release_media_player_keys (MsdMediaKeysManager *manager, + const char *application, + const char *name) +{ + GList *iter = NULL; + + g_return_if_fail (application != NULL || name != NULL); + + if (application != NULL) { + iter = g_list_find_custom (manager->priv->media_players, + application, + find_by_application); + } + + if (iter == NULL && name != NULL) { + iter = g_list_find_custom (manager->priv->media_players, + name, + find_by_name); + } + + if (iter != NULL) { + MediaPlayer *player; + + player = iter->data; + g_debug ("Deregistering %s (dbus_name: %s)", application, player->dbus_name); + free_media_player (player); + manager->priv->media_players = g_list_delete_link (manager->priv->media_players, iter); + } +} + static gboolean msd_media_player_key_pressed (MsdMediaKeysManager *manager, const char *key) { + GError *error = NULL; const char *application = NULL; gboolean have_listeners; @@ -1075,11 +1218,55 @@ msd_media_player_key_pressed (MsdMediaKeysManager *manager, application = ((MediaPlayer *)manager->priv->media_players->data)->application; } - g_signal_emit (manager, signals[MEDIA_PLAYER_KEY_PRESSED], 0, application, key); + if (g_dbus_connection_emit_signal (manager->priv->connection, + NULL, + MSD_MEDIA_KEYS_DBUS_PATH, + MSD_MEDIA_KEYS_DBUS_NAME, + "MediaPlayerKeyPressed", + g_variant_new ("(ss)", application, key), + &error) == FALSE) { + g_debug ("Error emitting signal: %s", error->message); + g_error_free (error); + } return !have_listeners; } +static void +handle_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + MsdMediaKeysManager *manager = (MsdMediaKeysManager *) user_data; + + g_debug ("Calling method '%s' for media-keys", method_name); + + if (g_strcmp0 (method_name, "ReleaseMediaPlayerKeys") == 0) { + const char *app_name; + + g_variant_get (parameters, "(&s)", &app_name); + msd_media_keys_manager_release_media_player_keys (manager, app_name, sender); + g_dbus_method_invocation_return_value (invocation, NULL); + } else if (g_strcmp0 (method_name, "GrabMediaPlayerKeys") == 0) { + const char *app_name; + guint32 time; + + g_variant_get (parameters, "(&su)", &app_name, &time); + msd_media_keys_manager_grab_media_player_keys (manager, app_name, sender, time); + g_dbus_method_invocation_return_value (invocation, NULL); + } +} + +static const GDBusInterfaceVTable interface_vtable = +{ + .method_call = handle_method_call, +}; + static gboolean do_multimedia_player_action (MsdMediaKeysManager *manager, const char *key) @@ -1343,7 +1530,7 @@ rfkill_appeared_cb (GDBusConnection *connection, g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, 0, NULL, - "org.mate.SettingsDaemon.Rfkill", + "org.mate.SettingsDaemon", "/org/mate/SettingsDaemon/Rfkill", "org.mate.SettingsDaemon.Rfkill", manager->priv->rfkill_cancellable, @@ -1365,6 +1552,7 @@ start_media_keys_idle_cb (MsdMediaKeysManager *manager) manager->priv->volume_monitor = g_volume_monitor_get (); manager->priv->settings = g_settings_new (BINDING_SCHEMA); + manager->priv->sound_settings = g_settings_new (SOUND_SCHEMA); ensure_cancellable (&manager->priv->rfkill_cancellable); @@ -1407,6 +1595,8 @@ start_media_keys_idle_cb (MsdMediaKeysManager *manager) mate_settings_profile_end (NULL); + manager->priv->start_idle_id = 0; + return FALSE; } @@ -1443,7 +1633,8 @@ msd_media_keys_manager_start (MsdMediaKeysManager *manager, GError **error) mate_settings_profile_end ("mate_mixer_context_new"); } #endif - g_idle_add ((GSourceFunc) start_media_keys_idle_cb, manager); + manager->priv->start_idle_id = g_idle_add ((GSourceFunc) start_media_keys_idle_cb, manager); + g_source_set_name_by_id (manager->priv->start_idle_id, "[mate-settings-daemon] start_media_keys_idle_cb"); mate_settings_profile_end (NULL); @@ -1478,16 +1669,39 @@ msd_media_keys_manager_stop (MsdMediaKeysManager *manager) priv->settings = NULL; } + if (priv->sound_settings != NULL) { + g_object_unref (priv->sound_settings); + priv->sound_settings = NULL; + } + if (priv->volume_monitor != NULL) { g_object_unref (priv->volume_monitor); priv->volume_monitor = NULL; } + if (priv->start_idle_id != 0) { + g_source_remove (priv->start_idle_id); + priv->start_idle_id = 0; + } + + if (priv->owner_id > 0) { + g_bus_unown_name (priv->owner_id); + priv->owner_id = 0; + } + if (priv->connection != NULL) { g_object_unref (priv->connection); priv->connection = NULL; } + if (priv->bus_cancellable != NULL) { + g_cancellable_cancel (priv->bus_cancellable); + g_object_unref (priv->bus_cancellable); + priv->bus_cancellable = NULL; + } + + g_clear_pointer (&priv->introspection_data, g_dbus_node_info_unref); + need_flush = FALSE; dpy = gdk_display_get_default (); gdk_x11_display_error_trap_push (dpy); @@ -1538,187 +1752,82 @@ msd_media_keys_manager_stop (MsdMediaKeysManager *manager) priv->media_players = NULL; } -/* - * Register a new media player. Most applications will want to call - * this with time = GDK_CURRENT_TIME. This way, the last registered - * player will receive media events. In some cases, applications - * may want to register with a lower priority (usually 1), to grab - * events only nobody is interested. - */ -static gboolean -on_grab_media_player_keys (MateSettingsMediaKeys *object, - GDBusMethodInvocation *invocation, - const gchar *application, - guint time, - gpointer user_data) +static void +msd_media_keys_manager_finalize (GObject *object) { - GList *iter; - MediaPlayer *media_player; MsdMediaKeysManager *manager; - if (time == GDK_CURRENT_TIME) { - GTimeVal tv; - - g_get_current_time (&tv); - time = tv.tv_sec * 1000 + tv.tv_usec / 1000; - } - - manager = MSD_MEDIA_KEYS_MANAGER (user_data); - iter = g_list_find_custom (manager->priv->media_players, - application, - find_by_application); + g_return_if_fail (object != NULL); + g_return_if_fail (MSD_IS_MEDIA_KEYS_MANAGER (object)); - if (iter != NULL) { - if (((MediaPlayer *)iter->data)->time < time) { - g_free (((MediaPlayer *)iter->data)->application); - g_free (iter->data); - manager->priv->media_players = g_list_delete_link (manager->priv->media_players, iter); - } else { - mate_settings_media_keys_complete_grab_media_player_keys (object, invocation); - return TRUE; - } - } + manager = MSD_MEDIA_KEYS_MANAGER (object); - g_debug ("Registering %s at %u", application, time); - media_player = g_new0 (MediaPlayer, 1); - media_player->application = g_strdup (application); - media_player->time = time; + g_return_if_fail (manager->priv != NULL); - manager->priv->media_players = g_list_insert_sorted (manager->priv->media_players, - media_player, - find_by_time); + msd_media_keys_manager_stop (manager); - mate_settings_media_keys_complete_grab_media_player_keys (object, invocation); - return TRUE; + G_OBJECT_CLASS (msd_media_keys_manager_parent_class)->finalize (object); } -static gboolean -on_release_media_player_keys (MateSettingsMediaKeys *object, - GDBusMethodInvocation *invocation, - const gchar *application, - gpointer user_data) -{ - GList *iter; - MsdMediaKeysManager *manager; - manager = MSD_MEDIA_KEYS_MANAGER (user_data); - iter = g_list_find_custom (manager->priv->media_players, - application, - find_by_application); - - if (iter != NULL) { - g_debug ("Deregistering %s", application); - g_free (((MediaPlayer *)iter->data)->application); - g_free (iter->data); - manager->priv->media_players = g_list_delete_link (manager->priv->media_players, iter); - } +static void +msd_media_keys_manager_class_init (MsdMediaKeysManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); - mate_settings_media_keys_complete_release_media_player_keys (object, invocation); - return TRUE; + object_class->finalize = msd_media_keys_manager_finalize; } static void -bus_acquired_handler_cb (GDBusConnection *connection, - const gchar *name G_GNUC_UNUSED, - gpointer user_data) +msd_media_keys_manager_init (MsdMediaKeysManager *manager) { - MsdMediaKeysManager *manager; - GError *error = NULL; - gboolean exported; - - manager = MSD_MEDIA_KEYS_MANAGER (user_data); - - g_signal_connect (manager->priv->skeleton, - "handle-grab-media-player-keys", - G_CALLBACK (on_grab_media_player_keys), - manager); - g_signal_connect (manager->priv->skeleton, - "handle-release-media-player-keys", - G_CALLBACK (on_release_media_player_keys), - manager); - - exported = g_dbus_interface_skeleton_export ( - G_DBUS_INTERFACE_SKELETON (manager->priv->skeleton), - connection, - MSD_MEDIA_KEYS_DBUS_PATH, - &error); - if (!exported) - { - g_warning ("Failed to export interface: %s", error->message); - g_error_free (error); - gtk_main_quit (); - } - manager->priv->connection = g_object_ref(connection); + manager->priv = msd_media_keys_manager_get_instance_private (manager); } -static void msd_media_keys_manager_constructed (GObject *object) -{ - MsdMediaKeysManager *manager; - manager = MSD_MEDIA_KEYS_MANAGER (object); - G_OBJECT_CLASS (msd_media_keys_manager_parent_class)->constructed (object); - - manager->priv->bus_name_id = g_bus_own_name (G_BUS_TYPE_SESSION, - MSD_MEDIA_KEYS_DBUS_NAME, - G_BUS_NAME_OWNER_FLAGS_NONE, - bus_acquired_handler_cb, - NULL, - NULL, - manager, - NULL); -} - -static void msd_media_keys_manager_dispose (GObject *object) +static void +on_bus_gotten (GObject *source_object, + GAsyncResult *res, + MsdMediaKeysManager *manager) { - MsdMediaKeysManager *manager; - manager = MSD_MEDIA_KEYS_MANAGER (object); - - if (manager->priv->skeleton != NULL) - { - GDBusInterfaceSkeleton *skeleton; - - skeleton = G_DBUS_INTERFACE_SKELETON (manager->priv->skeleton); - g_dbus_interface_skeleton_unexport (skeleton); - g_clear_object (&manager->priv->skeleton); - } + GDBusConnection *connection; + GError *error = NULL; - if (manager->priv->bus_name_id > 0) - { - g_bus_unown_name (manager->priv->bus_name_id); - manager->priv->bus_name_id = 0; + connection = g_bus_get_finish (res, &error); + if (connection == NULL) { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("Could not get session bus: %s", error->message); + g_error_free (error); + return; } - - G_OBJECT_CLASS (msd_media_keys_manager_parent_class)->dispose (object); + manager->priv->connection = connection; + + g_dbus_connection_register_object (connection, + MSD_MEDIA_KEYS_DBUS_PATH, + manager->priv->introspection_data->interfaces[0], + &interface_vtable, + manager, + NULL, + NULL); + + manager->priv->owner_id = g_bus_own_name_on_connection (manager->priv->connection, + "org.mate.SettingsDaemon", + G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT, + NULL, NULL, NULL, NULL); } - static void -msd_media_keys_manager_class_init (MsdMediaKeysManagerClass *klass) +register_manager (MsdMediaKeysManager *manager) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->constructed = msd_media_keys_manager_constructed; - object_class->dispose = msd_media_keys_manager_dispose; - - signals[MEDIA_PLAYER_KEY_PRESSED] = - g_signal_new ("media-player-key-pressed", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MsdMediaKeysManagerClass, media_player_key_pressed), - NULL, - NULL, - msd_marshal_VOID__STRING_STRING, - G_TYPE_NONE, - 2, - G_TYPE_STRING, - G_TYPE_STRING); -} + manager->priv->introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); + manager->priv->bus_cancellable = g_cancellable_new (); + g_assert (manager->priv->introspection_data != NULL); -static void -msd_media_keys_manager_init (MsdMediaKeysManager *manager) -{ - manager->priv = msd_media_keys_manager_get_instance_private (manager); - manager->priv->skeleton = mate_settings_media_keys_skeleton_new (); + g_bus_get (G_BUS_TYPE_SESSION, + manager->priv->bus_cancellable, + (GAsyncReadyCallback) on_bus_gotten, + manager); } MsdMediaKeysManager * @@ -1728,6 +1837,9 @@ msd_media_keys_manager_new (void) g_object_ref (manager_object); } else { manager_object = g_object_new (MSD_TYPE_MEDIA_KEYS_MANAGER, NULL); + g_object_add_weak_pointer (manager_object, + (gpointer *) &manager_object); + register_manager (manager_object); } return MSD_MEDIA_KEYS_MANAGER (manager_object); |