From 50cb6eef306aa9139941ecbc4a9f6239505cefe0 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 18 Oct 2021 15:07:27 +0200 Subject: media-keys: Add some missing methods to MPRIS controller Make it possible to handle Seek() method calls, as well as toggling Repeat and Shuffle statuses as defined in: https://specifications.freedesktop.org/mpris-spec/latest/Player_Interface.html --- plugins/media-keys/mpris-controller.c | 111 ++++++++++++++++++++++++++++++++++ plugins/media-keys/mpris-controller.h | 2 + 2 files changed, 113 insertions(+) diff --git a/plugins/media-keys/mpris-controller.c b/plugins/media-keys/mpris-controller.c index 4fcbbf04..de113adb 100644 --- a/plugins/media-keys/mpris-controller.c +++ b/plugins/media-keys/mpris-controller.c @@ -95,6 +95,117 @@ mpris_controller_key (MprisController *self, const gchar *key) return TRUE; } +gboolean +mpris_controller_seek (MprisController *self, gint64 offset) +{ + g_return_val_if_fail (MPRIS_IS_CONTROLLER (self), FALSE); + + if (!self->mpris_client_proxy) + return FALSE; + + g_debug ("calling Seek over dbus to mpris client %s", + g_dbus_proxy_get_name (self->mpris_client_proxy)); + g_dbus_proxy_call (self->mpris_client_proxy, + "Seek", g_variant_new ("(x)", offset, NULL), + G_DBUS_CALL_FLAGS_NONE, -1, self->cancellable, + mpris_proxy_call_done, + NULL); + return TRUE; +} + +static GDBusProxy * +get_props_proxy (GDBusProxy *proxy, + GCancellable *cancellable) +{ + GDBusProxy *props = NULL; + g_autoptr(GError) error = NULL; + + g_return_val_if_fail (proxy != NULL, NULL); + + props = g_dbus_proxy_new_sync (g_dbus_proxy_get_connection (proxy), + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + g_dbus_proxy_get_name (proxy), + g_dbus_proxy_get_object_path (proxy), + "org.freedesktop.DBus.Properties", + cancellable, + &error); + if (!props) { + g_debug ("Could not get properties proxy for %s: %s", + g_dbus_proxy_get_interface_name (proxy), + error->message); + return NULL; + } + + return props; +} + +gboolean +mpris_controller_toggle (MprisController *self, const gchar *property) +{ + g_return_val_if_fail (MPRIS_IS_CONTROLLER (self), FALSE); + g_return_val_if_fail (property != NULL, FALSE); + + if (!self->mpris_client_proxy) + return FALSE; + + if (g_str_equal (property, "Repeat")) { + g_autoptr(GDBusProxy) props = NULL; + g_autoptr(GVariant) loop_status; + const gchar *status_str, *new_status; + + loop_status = g_dbus_proxy_get_cached_property (self->mpris_client_proxy, "LoopStatus"); + if (!loop_status) + return FALSE; + if (!g_variant_is_of_type (loop_status, G_VARIANT_TYPE_STRING)) + return FALSE; + status_str = g_variant_get_string (loop_status, NULL); + if (g_str_equal (status_str, "Playlist")) + new_status = "None"; + else + new_status = "Playlist"; + + props = get_props_proxy (self->mpris_client_proxy, self->cancellable); + if (!props) + return FALSE; + g_dbus_proxy_call (props, + "Set", + g_variant_new_parsed ("('org.mpris.MediaPlayer2.Player', 'LoopStatus', %v)", + g_variant_new_string (new_status)), + G_DBUS_CALL_FLAGS_NONE, + -1, + self->cancellable, + mpris_proxy_call_done, NULL); + } else if (g_str_equal (property, "Shuffle")) { + g_autoptr(GDBusProxy) props = NULL; + g_autoptr(GVariant) shuffle_status; + gboolean status; + + shuffle_status = g_dbus_proxy_get_cached_property (self->mpris_client_proxy, "Shuffle"); + if (!shuffle_status) + return FALSE; + if (!g_variant_is_of_type (shuffle_status, G_VARIANT_TYPE_BOOLEAN)) + return FALSE; + status = g_variant_get_boolean (shuffle_status); + + props = get_props_proxy (self->mpris_client_proxy, self->cancellable); + if (!props) + return FALSE; + g_dbus_proxy_call (props, + "Set", + g_variant_new_parsed ("('org.mpris.MediaPlayer2.Player', 'Shuffle', %v)", + g_variant_new_boolean (!status)), + G_DBUS_CALL_FLAGS_NONE, + -1, + self->cancellable, + mpris_proxy_call_done, NULL); + } + + g_debug ("Unhandled toggle property '%s'", property); + + return TRUE; +} + static gboolean mpris_client_is_playing (GDBusProxy *proxy) { diff --git a/plugins/media-keys/mpris-controller.h b/plugins/media-keys/mpris-controller.h index a0044c4d..e44bc904 100644 --- a/plugins/media-keys/mpris-controller.h +++ b/plugins/media-keys/mpris-controller.h @@ -29,6 +29,8 @@ G_DECLARE_FINAL_TYPE (MprisController, mpris_controller, MPRIS, CONTROLLER, GObj MprisController *mpris_controller_new (void); gboolean mpris_controller_key (MprisController *self, const gchar *key); +gboolean mpris_controller_seek (MprisController *self, gint64 offset); +gboolean mpris_controller_toggle (MprisController *self, const gchar *property); gboolean mpris_controller_get_has_active_player (MprisController *controller); G_END_DECLS -- cgit v1.2.1