From 4216b19f3552d1271db44fc5524643cf56fecf18 Mon Sep 17 00:00:00 2001
From: Ruben Rodriguez <ruben@trisquel.info>
Date: Sat, 29 Jan 2022 12:00:21 -0500
Subject: [PATCH] celluloid: fixed mpris integration

---
 helpers/DATA/celluloid/mpris-v0.22.patch | 786 +++++++++++++++++++++++
 helpers/make-celluloid                   |   5 +-
 2 files changed, 790 insertions(+), 1 deletion(-)
 create mode 100644 helpers/DATA/celluloid/mpris-v0.22.patch

diff --git a/helpers/DATA/celluloid/mpris-v0.22.patch b/helpers/DATA/celluloid/mpris-v0.22.patch
new file mode 100644
index 00000000..2fea2a45
--- /dev/null
+++ b/helpers/DATA/celluloid/mpris-v0.22.patch
@@ -0,0 +1,786 @@
+Backports src/mpris from upstream v0.22 to fix mpris integration
+
+diff --git a/src/mpris/celluloid-mpris-base.c b/src/mpris/celluloid-mpris-base.c
+index 223f571..c44a63e 100644
+--- a/src/mpris/celluloid-mpris-base.c
++++ b/src/mpris/celluloid-mpris-base.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2015-2019 gnome-mpv
++ * Copyright (c) 2015-2019, 2021 gnome-mpv
+  *
+  * This file is part of Celluloid.
+  *
+@@ -42,6 +42,7 @@ struct _CelluloidMprisBase
+ {
+ 	CelluloidMprisModule parent;
+ 	CelluloidController *controller;
++	GHashTable *readonly_table;
+ 	guint reg_id;
+ };
+ 
+@@ -230,6 +231,7 @@ method_handler(	GDBusConnection *connection,
+ 		gpointer data )
+ {
+ 	CelluloidMprisBase *base = data;
++	gboolean unknown_method = FALSE;
+ 
+ 	if(g_strcmp0(method_name, "Raise") == 0)
+ 	{
+@@ -240,9 +242,25 @@ method_handler(	GDBusConnection *connection,
+ 	{
+ 		celluloid_controller_quit(base->controller);
+ 	}
++	else
++	{
++		unknown_method = TRUE;
++	}
+ 
+-	g_dbus_method_invocation_return_value
+-		(invocation, g_variant_new("()", NULL));
++	if(unknown_method)
++	{
++		g_dbus_method_invocation_return_error
++			(	invocation,
++				CELLULOID_MPRIS_ERROR,
++				CELLULOID_MPRIS_ERROR_UNKNOWN_METHOD,
++				"Attempted to call unknown method \"%s\"",
++				method_name );
++	}
++	else
++	{
++		g_dbus_method_invocation_return_value
++			(invocation, g_variant_new("()", NULL));
++	}
+ }
+ 
+ static GVariant *
+@@ -254,9 +272,24 @@ get_prop_handler(	GDBusConnection *connection,
+ 			GError **error,
+ 			gpointer data )
+ {
++	CelluloidMprisBase *base = CELLULOID_MPRIS_BASE(data);
++	CelluloidMprisModule *module = CELLULOID_MPRIS_MODULE(data);
+ 	GVariant *value = NULL;
+ 
+-	celluloid_mpris_module_get_properties(data, property_name, &value, NULL);
++	if(!g_hash_table_contains(base->readonly_table, property_name))
++	{
++		g_set_error
++			(	error,
++				CELLULOID_MPRIS_ERROR,
++				CELLULOID_MPRIS_ERROR_UNKNOWN_PROPERTY,
++				"Failed to get value of unknown property \"%s\"",
++				property_name );
++	}
++	else
++	{
++		celluloid_mpris_module_get_properties
++			(module, property_name, &value, NULL);
++	}
+ 
+ 	return value?g_variant_ref(value):NULL;
+ }
+@@ -271,22 +304,39 @@ set_prop_handler(	GDBusConnection *connection,
+ 			GError **error,
+ 			gpointer data )
+ {
+-	CelluloidMprisBase *base = data;
++	CelluloidMprisBase *base = CELLULOID_MPRIS_BASE(data);
++	gboolean result = TRUE;
+ 
+-	if(g_strcmp0(property_name, "Fullscreen") == 0)
++	if(!g_hash_table_contains(base->readonly_table, property_name))
++	{
++		result = FALSE;
++
++		g_set_error
++			(	error,
++				CELLULOID_MPRIS_ERROR,
++				CELLULOID_MPRIS_ERROR_UNKNOWN_PROPERTY,
++				"Failed to set value of unknown property \"%s\"",
++				property_name );
++	}
++	else if(GPOINTER_TO_INT(g_hash_table_lookup(base->readonly_table, property_name)))
++	{
++		result = FALSE;
++
++		g_set_error
++			(	error,
++				CELLULOID_MPRIS_ERROR,
++				CELLULOID_MPRIS_ERROR_SET_READONLY,
++				"Attempted to set value of readonly property \"%s\"",
++				property_name );
++	}
++	else if(g_strcmp0(property_name, "Fullscreen") == 0)
+ 	{
+ 		CelluloidView *view = celluloid_controller_get_view(base->controller);
+ 
+ 		celluloid_view_set_fullscreen(view, g_variant_get_boolean(value));
+ 	}
+-	else
+-	{
+-		celluloid_mpris_module_set_properties(	data,
+-							property_name, value,
+-							NULL );
+-	}
+ 
+-	return TRUE; /* This function should always succeed */
++	return result;
+ }
+ 
+ static void
+@@ -360,8 +410,39 @@ celluloid_mpris_base_class_init(CelluloidMprisBaseClass *klass)
+ static void
+ celluloid_mpris_base_init(CelluloidMprisBase *base)
+ {
+-	base->controller = NULL;
+-	base->reg_id = 0;
++	const struct
++	{
++		const gchar *name;
++		gboolean readonly;
++	}
++	properties[] =
++	{
++		{"CanQuit", TRUE},
++		{"Fullscreen", FALSE},
++		{"CanSetFullscreen", TRUE},
++		{"CanRaise", TRUE},
++		{"HasTrackList", TRUE},
++		{"Identity", TRUE},
++		{"DesktopEntry", TRUE},
++		{"SupportedUriSchemes", TRUE},
++		{"SupportedMimeTypes", TRUE},
++		{NULL, FALSE}
++	};
++
++	base->controller =
++		NULL;
++	base->readonly_table =
++		g_hash_table_new_full(g_str_hash, g_int_equal, g_free, NULL);
++	base->reg_id =
++		0;
++
++	for(gint i = 0; properties[i].name; i++)
++	{
++		g_hash_table_replace
++			(	base->readonly_table,
++				g_strdup(properties[i].name),
++				GINT_TO_POINTER(properties[i].readonly) );
++	}
+ }
+ 
+ CelluloidMprisModule *
+diff --git a/src/mpris/celluloid-mpris-module.c b/src/mpris/celluloid-mpris-module.c
+index 677c8a0..358516c 100644
+--- a/src/mpris/celluloid-mpris-module.c
++++ b/src/mpris/celluloid-mpris-module.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2017-2019 gnome-mpv
++ * Copyright (c) 2017-2019, 2021 gnome-mpv
+  *
+  * This file is part of Celluloid.
+  *
+@@ -83,9 +83,8 @@ set_property(	GObject *object,
+ {
+ 	CelluloidMprisModulePrivate *priv;
+ 
+-	priv =	G_TYPE_INSTANCE_GET_PRIVATE(	object,
+-						CELLULOID_TYPE_MPRIS_MODULE,
+-						CelluloidMprisModulePrivate );
++	priv =	celluloid_mpris_module_get_instance_private
++		(CELLULOID_MPRIS_MODULE(object));
+ 
+ 	switch(property_id)
+ 	{
+@@ -111,9 +110,8 @@ get_property(	GObject *object,
+ {
+ 	CelluloidMprisModulePrivate *priv;
+ 
+-	priv =	G_TYPE_INSTANCE_GET_PRIVATE(	object,
+-						CELLULOID_TYPE_MPRIS_MODULE,
+-						CelluloidMprisModulePrivate );
++	priv =	celluloid_mpris_module_get_instance_private
++		(CELLULOID_MPRIS_MODULE(object));
+ 
+ 	switch(property_id)
+ 	{
+@@ -136,9 +134,8 @@ dispose(GObject *object)
+ {
+ 	CelluloidMprisModulePrivate *priv;
+ 
+-	priv =	G_TYPE_INSTANCE_GET_PRIVATE(	object,
+-						CELLULOID_TYPE_MPRIS_MODULE,
+-						CelluloidMprisModulePrivate );
++	priv =	celluloid_mpris_module_get_instance_private
++		(CELLULOID_MPRIS_MODULE(object));
+ 
+ 	g_hash_table_unref(priv->prop_table);
+ 
+@@ -150,9 +147,8 @@ finalize(GObject *object)
+ {
+ 	CelluloidMprisModulePrivate *priv;
+ 
+-	priv =	G_TYPE_INSTANCE_GET_PRIVATE(	object,
+-						CELLULOID_TYPE_MPRIS_MODULE,
+-						CelluloidMprisModulePrivate );
++	priv =	celluloid_mpris_module_get_instance_private
++		(CELLULOID_MPRIS_MODULE(object));
+ 
+ 	g_slist_foreach(priv->signal_ids, (GFunc)disconnect_signal, NULL);
+ 	g_slist_free_full(priv->signal_ids, g_free);
+@@ -197,9 +193,7 @@ celluloid_mpris_module_init(CelluloidMprisModule *module)
+ {
+ 	CelluloidMprisModulePrivate *priv;
+ 
+-	priv =	G_TYPE_INSTANCE_GET_PRIVATE(	module,
+-						CELLULOID_TYPE_MPRIS_MODULE,
+-						CelluloidMprisModulePrivate );
++	priv = celluloid_mpris_module_get_instance_private(module);
+ 
+ 	priv->conn = NULL;
+ 	priv->iface = NULL;
+@@ -222,9 +216,7 @@ celluloid_mpris_module_connect_signal(	CelluloidMprisModule *module,
+ 	CelluloidMprisModulePrivate *priv;
+ 	CelluloidSignalHandlerInfo *info;
+ 
+-	priv =	G_TYPE_INSTANCE_GET_PRIVATE(	module,
+-						CELLULOID_TYPE_MPRIS_MODULE,
+-						CelluloidMprisModulePrivate );
++	priv = celluloid_mpris_module_get_instance_private(module);
+ 	info = g_malloc(sizeof(CelluloidSignalHandlerInfo));
+ 
+ 	info->instance = instance;
+@@ -241,9 +233,7 @@ celluloid_mpris_module_get_properties(CelluloidMprisModule *module, ...)
+ 	gchar *name;
+ 	GVariant **value_ptr;
+ 
+-	priv =	G_TYPE_INSTANCE_GET_PRIVATE(	module,
+-						CELLULOID_TYPE_MPRIS_MODULE,
+-						CelluloidMprisModulePrivate );
++	priv = celluloid_mpris_module_get_instance_private(module);
+ 
+ 	va_start(arg, module);
+ 
+@@ -255,6 +245,8 @@ celluloid_mpris_module_get_properties(CelluloidMprisModule *module, ...)
+ 	{
+ 		*value_ptr = g_hash_table_lookup(priv->prop_table, name);
+ 	}
++
++	va_end(arg);
+ }
+ 
+ void
+@@ -271,9 +263,7 @@ celluloid_mpris_module_set_properties_full(	CelluloidMprisModule *module,
+ 	const gchar *elem_type_string;
+ 	GVariant *sig_args;
+ 
+-	priv =	G_TYPE_INSTANCE_GET_PRIVATE(	module,
+-						CELLULOID_TYPE_MPRIS_MODULE,
+-						CelluloidMprisModulePrivate );
++	priv = celluloid_mpris_module_get_instance_private(module);
+ 	builder_type_string = send_new_value?"a{sv}":"as";
+ 	elem_type_string = builder_type_string+1;
+ 
+@@ -296,6 +286,8 @@ celluloid_mpris_module_set_properties_full(	CelluloidMprisModule *module,
+ 		g_variant_builder_add(&builder, elem_type_string, name, value);
+ 	}
+ 
++	va_end(arg);
++
+ 	sig_args = g_variant_new(	"(sa{sv}as)",
+ 					priv->iface->name,
+ 					send_new_value?&builder:NULL,
+diff --git a/src/mpris/celluloid-mpris-player.c b/src/mpris/celluloid-mpris-player.c
+index cd276d0..a3a52cf 100644
+--- a/src/mpris/celluloid-mpris-player.c
++++ b/src/mpris/celluloid-mpris-player.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2015-2019 gnome-mpv
++ * Copyright (c) 2015-2019, 2021 gnome-mpv
+  *
+  * This file is part of Celluloid.
+  *
+@@ -42,6 +42,7 @@ struct _CelluloidMprisPlayer
+ {
+ 	CelluloidMprisModule parent;
+ 	CelluloidController *controller;
++	GHashTable *readonly_table;
+ 	guint reg_id;
+ };
+ 
+@@ -402,30 +403,34 @@ method_handler(	GDBusConnection *connection,
+ 	CelluloidMprisPlayer *player = data;
+ 	CelluloidModel *model =	celluloid_controller_get_model
+ 				(player->controller);
++	gboolean unknown_method = FALSE;
+ 
+ 	if(g_strcmp0(method_name, "Next") == 0)
+ 	{
+-		celluloid_model_key_press(model, "NEXT");
++		celluloid_model_next_playlist_entry(model);
+ 	}
+ 	else if(g_strcmp0(method_name, "Previous") == 0)
+ 	{
+-		celluloid_model_key_press(model, "PREV");
++		celluloid_model_previous_playlist_entry(model);
+ 	}
+ 	else if(g_strcmp0(method_name, "Pause") == 0)
+ 	{
+-		celluloid_model_key_press(model, "PAUSE");
++		celluloid_model_pause(model);
+ 	}
+ 	else if(g_strcmp0(method_name, "PlayPause") == 0)
+ 	{
+-		celluloid_model_key_press(model, "PLAYPAUSE");
++		gboolean pause = FALSE;
++
++		g_object_get(model, "pause", &pause, NULL);
++		g_object_set(model, "pause", !pause, NULL);
+ 	}
+ 	else if(g_strcmp0(method_name, "Stop") == 0)
+ 	{
+-		celluloid_model_key_press(model, "STOP");
++		celluloid_model_stop(model);
+ 	}
+ 	else if(g_strcmp0(method_name, "Play") == 0)
+ 	{
+-		celluloid_model_key_press(model, "PLAY");
++		celluloid_model_play(model);
+ 	}
+ 	else if(g_strcmp0(method_name, "Seek") == 0)
+ 	{
+@@ -459,9 +464,25 @@ method_handler(	GDBusConnection *connection,
+ 		g_variant_get(parameters, "(&s)", &uri);
+ 		celluloid_model_load_file(model, uri, FALSE);
+ 	}
++	else
++	{
++		unknown_method = TRUE;
++	}
+ 
+-	g_dbus_method_invocation_return_value
+-		(invocation, g_variant_new("()", NULL));
++	if(unknown_method)
++	{
++		g_dbus_method_invocation_return_error
++			(	invocation,
++				CELLULOID_MPRIS_ERROR,
++				CELLULOID_MPRIS_ERROR_UNKNOWN_METHOD,
++				"Attempted to call unknown method \"%s\"",
++				method_name );
++	}
++	else
++	{
++		g_dbus_method_invocation_return_value
++			(invocation, g_variant_new("()", NULL));
++	}
+ }
+ 
+ static GVariant *
+@@ -473,10 +494,20 @@ get_prop_handler(	GDBusConnection *connection,
+ 			GError **error,
+ 			gpointer data )
+ {
+-	CelluloidMprisPlayer *player = data;
+-	GVariant *value;
++	CelluloidMprisPlayer *player = CELLULOID_MPRIS_PLAYER(data);
++	CelluloidMprisModule *module = CELLULOID_MPRIS_MODULE(data);
++	GVariant *value = NULL;
+ 
+-	if(g_strcmp0(property_name, "Position") == 0)
++	if(!g_hash_table_contains(player->readonly_table, property_name))
++	{
++		g_set_error
++			(	error,
++				CELLULOID_MPRIS_ERROR,
++				CELLULOID_MPRIS_ERROR_UNKNOWN_PROPERTY,
++				"Failed to get value of unknown property \"%s\"",
++				property_name );
++	}
++	else if(g_strcmp0(property_name, "Position") == 0)
+ 	{
+ 		CelluloidModel *model;
+ 		gdouble position;
+@@ -488,7 +519,7 @@ get_prop_handler(	GDBusConnection *connection,
+ 	else
+ 	{
+ 		celluloid_mpris_module_get_properties
+-			(	CELLULOID_MPRIS_MODULE(data),
++			(	module,
+ 				property_name, &value,
+ 				NULL );
+ 	}
+@@ -506,11 +537,32 @@ set_prop_handler(	GDBusConnection *connection,
+ 			GError **error,
+ 			gpointer data )
+ {
+-	CelluloidMprisPlayer *player = data;
++	CelluloidMprisPlayer *player = CELLULOID_MPRIS_PLAYER(data);
+ 	CelluloidModel *model =	celluloid_controller_get_model
+ 				(player->controller);
++	gboolean result = TRUE;
+ 
+-	if(g_strcmp0(property_name, "LoopStatus") == 0)
++	if(!g_hash_table_contains(player->readonly_table, property_name))
++	{
++		result = FALSE;
++
++		g_set_error
++			(	error,
++				CELLULOID_MPRIS_ERROR,
++				CELLULOID_MPRIS_ERROR_UNKNOWN_PROPERTY,
++				"Failed to set value of unknown property \"%s\"",
++				property_name );
++	}
++	else if(GPOINTER_TO_INT(g_hash_table_lookup(player->readonly_table, property_name)))
++	{
++		g_set_error
++			(	error,
++				CELLULOID_MPRIS_ERROR,
++				CELLULOID_MPRIS_ERROR_SET_READONLY,
++				"Attempted to set value of readonly property \"%s\"",
++				property_name );
++	}
++	else if(g_strcmp0(property_name, "LoopStatus") == 0)
+ 	{
+ 		const gchar *loop = g_variant_get_string(value, NULL);
+ 		const gchar *loop_file =	g_strcmp0(loop, "Track") == 0 ?
+@@ -536,11 +588,7 @@ set_prop_handler(	GDBusConnection *connection,
+ 				NULL );
+ 	}
+ 
+-	celluloid_mpris_module_set_properties(	CELLULOID_MPRIS_MODULE(data),
+-						property_name, value,
+-						NULL );
+-
+-	return TRUE; /* This function should always succeed */
++	return result;
+ }
+ 
+ static void
+@@ -840,8 +888,43 @@ celluloid_mpris_player_class_init(CelluloidMprisPlayerClass *klass)
+ static void
+ celluloid_mpris_player_init(CelluloidMprisPlayer *player)
+ {
+-	player->controller = NULL;
+-	player->reg_id = 0;
++	const struct
++	{
++		const gchar *name;
++		gboolean readonly;
++	}
++	properties[] =
++	{
++		{"PlaybackStatus", TRUE},
++		{"LoopStatus", FALSE},
++		{"Rate", FALSE},
++		{"Metadata", TRUE},
++		{"Volume", FALSE},
++		{"MinimumRate", TRUE},
++		{"MaximumRate", TRUE},
++		{"CanGoNext", TRUE},
++		{"CanGoPrevious", TRUE},
++		{"CanPlay", TRUE},
++		{"CanPause", TRUE},
++		{"CanSeek", TRUE},
++		{"CanControl", TRUE},
++		{NULL, FALSE}
++	};
++
++	player->controller =
++		NULL;
++	player->readonly_table =
++		g_hash_table_new_full(g_str_hash, g_int_equal, g_free, NULL);
++	player->reg_id =
++		0;
++
++	for(gint i = 0; properties[i].name; i++)
++	{
++		g_hash_table_replace
++			(	player->readonly_table,
++				g_strdup(properties[i].name),
++				GINT_TO_POINTER(properties[i].readonly) );
++	}
+ }
+ 
+ CelluloidMprisModule *
+diff --git a/src/mpris/celluloid-mpris-track-list.c b/src/mpris/celluloid-mpris-track-list.c
+index 7b5d8c5..7784ad2 100644
+--- a/src/mpris/celluloid-mpris-track-list.c
++++ b/src/mpris/celluloid-mpris-track-list.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2017-2019 gnome-mpv
++ * Copyright (c) 2017-2019, 2021 gnome-mpv
+  *
+  * This file is part of Celluloid.
+  *
+@@ -19,6 +19,7 @@
+ 
+ #include "celluloid-mpris-track-list.h"
+ #include "celluloid-mpris-gdbus.h"
++#include "celluloid-mpris.h"
+ #include "celluloid-common.h"
+ #include "celluloid-def.h"
+ 
+@@ -35,6 +36,7 @@ struct _CelluloidMprisTrackList
+ {
+ 	CelluloidMprisModule parent;
+ 	CelluloidController *controller;
++	GHashTable *readonly_table;
+ 	guint reg_id;
+ };
+ 
+@@ -226,6 +228,7 @@ method_handler(	GDBusConnection *connection,
+ 	CelluloidMprisTrackList *track_list = data;
+ 	CelluloidModel *model =	celluloid_controller_get_model
+ 				(track_list->controller);
++	gboolean unknown_method = FALSE;
+ 	GVariant *return_value = NULL;
+ 
+ 	if(g_strcmp0(method_name, "GetTracksMetadata") == 0)
+@@ -283,12 +286,22 @@ method_handler(	GDBusConnection *connection,
+ 	}
+ 	else
+ 	{
+-		g_critical("Attempted to call unknown method: %s", method_name);
+-
+-		return_value = g_variant_new("()", NULL);
++		unknown_method = TRUE;
+ 	}
+ 
+-	g_dbus_method_invocation_return_value(invocation, return_value);
++	if(unknown_method)
++	{
++		g_dbus_method_invocation_return_error
++			(	invocation,
++				CELLULOID_MPRIS_ERROR,
++				CELLULOID_MPRIS_ERROR_UNKNOWN_METHOD,
++				"Attempted to call unknown method \"%s\"",
++				method_name );
++	}
++	else
++	{
++		g_dbus_method_invocation_return_value(invocation, return_value);
++	}
+ }
+ 
+ static GVariant *
+@@ -300,15 +313,25 @@ get_prop_handler(	GDBusConnection *connection,
+ 			GError **error,
+ 			gpointer data )
+ {
++	CelluloidMprisTrackList *track_list = CELLULOID_MPRIS_TRACK_LIST(data);
++	CelluloidMprisModule *module = CELLULOID_MPRIS_MODULE(data);
+ 	GVariant *value = NULL;
+ 
+-	celluloid_mpris_module_get_properties(	CELLULOID_MPRIS_MODULE(data),
+-						property_name, &value,
+-						NULL );
++	if(!g_hash_table_contains(track_list->readonly_table, property_name))
++	{
++		g_set_error
++			(	error,
++				CELLULOID_MPRIS_ERROR,
++				CELLULOID_MPRIS_ERROR_UNKNOWN_PROPERTY,
++				"Failed to get value of unknown property \"%s\"",
++				property_name );
++	}
++	else
++	{
++		celluloid_mpris_module_get_properties
++			(module, property_name, &value, NULL);
++	}
+ 
+-	/* Call g_variant_ref() to prevent the value of the property in the
+-	 * properties table from being freed.
+-	 */
+ 	return value?g_variant_ref(value):NULL;
+ }
+ 
+@@ -322,10 +345,26 @@ set_prop_handler(	GDBusConnection *connection,
+ 			GError **error,
+ 			gpointer data )
+ {
+-	g_warning(	"Attempted to set property %s in "
+-			"org.mpris.MediaPlayer2.TrackList, but the interface "
+-			"only has read-only properties.",
+-			property_name );
++	CelluloidMprisTrackList *track_list = CELLULOID_MPRIS_TRACK_LIST(data);
++
++	if(!g_hash_table_contains(track_list->readonly_table, property_name))
++	{
++		g_set_error
++			(	error,
++				CELLULOID_MPRIS_ERROR,
++				CELLULOID_MPRIS_ERROR_UNKNOWN_PROPERTY,
++				"Failed to set value of unknown property \"%s\"",
++				property_name );
++	}
++	else if(GPOINTER_TO_INT(g_hash_table_lookup(track_list->readonly_table, property_name)))
++	{
++		g_set_error
++			(	error,
++				CELLULOID_MPRIS_ERROR,
++				CELLULOID_MPRIS_ERROR_SET_READONLY,
++				"Attempted to set value of readonly property \"%s\"",
++				property_name );
++	}
+ 
+ 	/* Always fail since the interface only has read-only properties */
+ 	return FALSE;
+@@ -576,8 +615,32 @@ celluloid_mpris_track_list_class_init(CelluloidMprisTrackListClass *klass)
+ static void
+ celluloid_mpris_track_list_init(CelluloidMprisTrackList *track_list)
+ {
+-	track_list->controller = NULL;
+-	track_list->reg_id = 0;
++	const struct
++	{
++		const gchar *name;
++		gboolean readonly;
++	}
++	properties[] =
++	{
++		{"Tracks", TRUE},
++		{"Fullscreen", TRUE},
++		{NULL, FALSE}
++	};
++
++	track_list->controller =
++		NULL;
++	track_list->readonly_table =
++		g_hash_table_new_full(g_str_hash, g_int_equal, g_free, NULL);
++	track_list->reg_id =
++		0;
++
++	for(gint i = 0; properties[i].name; i++)
++	{
++		g_hash_table_replace
++			(	track_list->readonly_table,
++				g_strdup(properties[i].name),
++				GINT_TO_POINTER(properties[i].readonly) );
++	}
+ }
+ 
+ CelluloidMprisModule *
+diff --git a/src/mpris/celluloid-mpris.c b/src/mpris/celluloid-mpris.c
+index 053aa4c..5d14065 100644
+--- a/src/mpris/celluloid-mpris.c
++++ b/src/mpris/celluloid-mpris.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2015-2019 gnome-mpv
++ * Copyright (c) 2015-2019, 2021 gnome-mpv
+  *
+  * This file is part of Celluloid.
+  *
+@@ -55,6 +55,8 @@ struct _CelluloidMprisClass
+ 
+ G_DEFINE_TYPE(CelluloidMpris, celluloid_mpris, G_TYPE_OBJECT)
+ 
++G_DEFINE_QUARK(celluloid-mpris-error-quark, celluloid_mpris_error)
++
+ static void
+ constructed(GObject *object);
+ 
+@@ -73,11 +75,6 @@ get_property(	GObject *object,
+ 		GValue *value,
+ 		GParamSpec *pspec );
+ 
+-static void
+-name_acquired_handler(	GDBusConnection *connection,
+-			const gchar *name,
+-			gpointer data );
+-
+ static void
+ name_lost_handler(	GDBusConnection *connection,
+ 			const gchar *name,
+@@ -119,12 +116,23 @@ constructed(GObject *object)
+ 		gchar *name =	g_strdup_printf
+ 				(MPRIS_BUS_NAME ".instance-%u", window_id);
+ 
++		self->session_bus_conn = conn;
++		self->base =	celluloid_mpris_base_new
++				(self->controller, conn);
++		self->player =	celluloid_mpris_player_new
++				(self->controller, conn);
++		self->track_list =	celluloid_mpris_track_list_new
++					(self->controller, conn);
++
++		celluloid_mpris_module_register(self->base);
++		celluloid_mpris_module_register(self->player);
++		celluloid_mpris_module_register(self->track_list);
++
+ 		self->name_id =	g_bus_own_name_on_connection
+ 				(	conn,
+ 					name,
+ 					G_BUS_NAME_OWNER_FLAGS_NONE,
+-					(GBusNameAcquiredCallback)
+-					name_acquired_handler,
++					NULL,
+ 					(GBusNameLostCallback)
+ 					name_lost_handler,
+ 					self,
+@@ -197,26 +205,6 @@ get_property(	GObject *object,
+ 
+ }
+ 
+-static void
+-name_acquired_handler(	GDBusConnection *connection,
+-			const gchar *name,
+-			gpointer data )
+-{
+-	CelluloidMpris *self = data;
+-
+-	self->session_bus_conn = connection;
+-	self->base =		celluloid_mpris_base_new
+-				(self->controller, connection);
+-	self->player =		celluloid_mpris_player_new
+-				(self->controller, connection);
+-	self->track_list =	celluloid_mpris_track_list_new
+-				(self->controller, connection);
+-
+-	celluloid_mpris_module_register(self->base);
+-	celluloid_mpris_module_register(self->player);
+-	celluloid_mpris_module_register(self->track_list);
+-}
+-
+ static void
+ name_lost_handler(	GDBusConnection *connection,
+ 			const gchar *name,
+diff --git a/src/mpris/celluloid-mpris.h b/src/mpris/celluloid-mpris.h
+index 3ac9d57..6618f4b 100644
+--- a/src/mpris/celluloid-mpris.h
++++ b/src/mpris/celluloid-mpris.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2015-2019 gnome-mpv
++ * Copyright (c) 2015-2019, 2021 gnome-mpv
+  *
+  * This file is part of Celluloid.
+  *
+@@ -31,6 +31,19 @@ G_BEGIN_DECLS
+ 
+ G_DECLARE_FINAL_TYPE(CelluloidMpris, celluloid_mpris, CELLULOID, MPRIS, GObject)
+ 
++#define CELLULOID_MPRIS_ERROR celluloid_mpris_error_quark()
++
++enum
++{
++	CELLULOID_MPRIS_ERROR_UNKNOWN_METHOD,
++	CELLULOID_MPRIS_ERROR_UNKNOWN_PROPERTY,
++	CELLULOID_MPRIS_ERROR_SET_READONLY,
++	CELLULOID_MPRIS_ERROR_FAILED
++};
++
++GQuark
++celluloid_mpris_error_quark(void);
++
+ GVariant *
+ celluloid_mpris_build_g_variant_string_array(const gchar** list);
+ 
diff --git a/helpers/make-celluloid b/helpers/make-celluloid
index de81a55a..4546ce79 100644
--- a/helpers/make-celluloid
+++ b/helpers/make-celluloid
@@ -18,7 +18,7 @@
 #
 #
 
-VERSION=1
+VERSION=2
 EXTERNAL='deb-src https://ppa.launchpadcontent.net/xuzhen666/gnome-mpv/ubuntu $UPSTREAM main'
 REPOKEY=6CAE7FA0B44EEF4EBD4E955F77D026E2EEAD66BD
 
@@ -42,6 +42,9 @@ diff -ur source.orig/src/celluloid-menu.c source/src/celluloid-menu.c
  	celluloid_menu_build_menu(menu, entries, TRUE);
 EOF
 
+# Fix mpris integration
+patch -p1 < $DATA/mpris-v0.22.patch
+
 changelog "Backported from ppa"
 
 compile
-- 
GitLab