summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Nocera <hadess@hadess.net>2022-02-09 13:26:56 +0100
committerBastien Nocera <hadess@hadess.net>2022-02-09 14:06:15 +0100
commitef4e800766ca5029257994c7cc482062f858b17c (patch)
tree2433860e7d8e41b68d28a825855dcd2393c07518
parent5c97fc953be8a9d876f59632d8dcaaa6870c08df (diff)
downloadtotem-ef4e800766ca5029257994c7cc482062f858b17c.tar.gz
backend: Remove GInitable interface
BaconVideoWidget could fail to initialise if GStreamer plugins were missing, but GStreamer is initialised after options are parsed in the GtkApplication's ->startup vfunc, which we want to use a GtkBuilder template for, which has the fallible widget inside it. This means that we can't be using a GInitable as we don't want to have unreportable errors during the template creation[1]. Instead, move all the initialisation inside the GObject's _init() function and add a function to check on its success and propagate an error. See https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/4461
-rw-r--r--src/backend/bacon-video-widget.c103
-rw-r--r--src/backend/bacon-video-widget.h4
2 files changed, 55 insertions, 52 deletions
diff --git a/src/backend/bacon-video-widget.c b/src/backend/bacon-video-widget.c
index 49a5203ec..ff2d2d555 100644
--- a/src/backend/bacon-video-widget.c
+++ b/src/backend/bacon-video-widget.c
@@ -105,8 +105,6 @@
#define I_(string) (g_intern_static_string (string))
-static void bacon_video_widget_initable_iface_init (GInitableIface *iface);
-
/* Signals */
enum
{
@@ -163,6 +161,8 @@ struct _BaconVideoWidget
GtkWidget *broken_video;
GtkWidget *video_widget;
+ GError *init_error;
+
char *user_agent;
char *referrer;
@@ -258,9 +258,7 @@ struct _BaconVideoWidget
float rate;
};
-G_DEFINE_TYPE_WITH_CODE (BaconVideoWidget, bacon_video_widget, GTK_TYPE_OVERLAY,
- G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
- bacon_video_widget_initable_iface_init))
+G_DEFINE_TYPE (BaconVideoWidget, bacon_video_widget, GTK_TYPE_OVERLAY)
static void bacon_video_widget_set_property (GObject * object,
guint property_id,
@@ -936,27 +934,6 @@ bacon_video_widget_class_init (BaconVideoWidgetClass * klass)
gtk_widget_class_bind_template_child (widget_class, BaconVideoWidget, broken_video);
}
-static void
-bacon_video_widget_init (BaconVideoWidget * bvw)
-{
- gtk_widget_set_can_focus (GTK_WIDGET (bvw), TRUE);
-
- g_type_class_ref (BVW_TYPE_METADATA_TYPE);
- g_type_class_ref (BVW_TYPE_DVD_EVENT);
- g_type_class_ref (BVW_TYPE_ROTATION);
-
- bvw->volume = -1.0;
- bvw->rate = FORWARD_RATE;
- bvw->tag_update_queue = g_async_queue_new_full ((GDestroyNotify) update_tags_delayed_data_destroy);
- g_mutex_init (&bvw->seek_mutex);
- bvw->clock = gst_system_clock_obtain ();
- bvw->seek_req_time = GST_CLOCK_TIME_NONE;
- bvw->seek_time = -1;
- bvw->auth_last_result = G_MOUNT_OPERATION_HANDLED;
-
- bacon_video_widget_gst_missing_plugins_block ();
-}
-
static gboolean bvw_query_timeout (BaconVideoWidget *bvw);
static gboolean bvw_query_buffering_timeout (BaconVideoWidget *bvw);
static void parse_stream_info (BaconVideoWidget *bvw);
@@ -2197,7 +2174,7 @@ playbin_element_setup_cb (GstElement *playbin,
if (g_strcmp0 (G_OBJECT_TYPE_NAME (element), "GstDownloadBuffer") != 0)
return;
- /* See also bacon_video_widget_initable_init() */
+ /* See also bacon_video_widget_init() */
template = g_build_filename (g_get_user_cache_dir (), "totem", "stream-buffer", "XXXXXX", NULL);
g_object_set (element, "temp-template", template, NULL);
GST_DEBUG ("Reconfigured file download template to '%s'", template);
@@ -2400,6 +2377,7 @@ bacon_video_widget_finalize (GObject * object)
g_clear_pointer (&bvw->bus, gst_object_unref);
}
+ g_clear_error (&bvw->init_error);
g_clear_pointer (&bvw->user_agent, g_free);
g_clear_pointer (&bvw->referrer, g_free);
g_clear_pointer (&bvw->mrl, g_free);
@@ -5295,12 +5273,9 @@ is_feature_enabled (const char *env)
return g_strcmp0 (value, "1") == 0;
}
-static gboolean
-bacon_video_widget_initable_init (GInitable *initable,
- GCancellable *cancellable,
- GError **error)
+static void
+bacon_video_widget_init (BaconVideoWidget *bvw)
{
- BaconVideoWidget *bvw;
GstElement *audio_sink = NULL;
gchar *version_str;
GstPlayFlags flags;
@@ -5308,7 +5283,22 @@ bacon_video_widget_initable_init (GInitable *initable,
GstPad *audio_pad;
char *template;
- bvw = BACON_VIDEO_WIDGET (initable);
+ gtk_widget_set_can_focus (GTK_WIDGET (bvw), TRUE);
+
+ g_type_class_ref (BVW_TYPE_METADATA_TYPE);
+ g_type_class_ref (BVW_TYPE_DVD_EVENT);
+ g_type_class_ref (BVW_TYPE_ROTATION);
+
+ bvw->volume = -1.0;
+ bvw->rate = FORWARD_RATE;
+ bvw->tag_update_queue = g_async_queue_new_full ((GDestroyNotify) update_tags_delayed_data_destroy);
+ g_mutex_init (&bvw->seek_mutex);
+ bvw->clock = gst_system_clock_obtain ();
+ bvw->seek_req_time = GST_CLOCK_TIME_NONE;
+ bvw->seek_time = -1;
+ bvw->auth_last_result = G_MOUNT_OPERATION_HANDLED;
+
+ bacon_video_widget_gst_missing_plugins_block ();
#ifndef GST_DISABLE_GST_DEBUG
if (_totem_gst_debug_cat == NULL) {
@@ -5348,10 +5338,10 @@ bacon_video_widget_initable_init (GInitable *initable,
g_object_ref_sink (bvw->video_sink);
if (audio_sink)
g_object_ref_sink (audio_sink);
- g_set_error_literal (error, BVW_ERROR, BVW_ERROR_PLUGIN_LOAD,
- _("Some necessary plug-ins are missing. "
- "Make sure that the program is correctly installed."));
- return FALSE;
+ bvw->init_error = g_error_new_literal (BVW_ERROR, BVW_ERROR_PLUGIN_LOAD,
+ _("Some necessary plug-ins are missing. "
+ "Make sure that the program is correctly installed."));
+ return;
}
bvw->bus = gst_element_get_bus (bvw->play);
@@ -5447,30 +5437,41 @@ bacon_video_widget_initable_init (GInitable *initable,
G_CALLBACK (audio_tags_changed_cb), bvw);
g_signal_connect (bvw->play, "text-tags-changed",
G_CALLBACK (text_tags_changed_cb), bvw);
-
- return TRUE;
-}
-
-static void
-bacon_video_widget_initable_iface_init (GInitableIface *iface)
-{
- iface->init = bacon_video_widget_initable_init;
}
/**
* bacon_video_widget_new:
- * @error: a #GError, or %NULL
*
* Creates a new #BaconVideoWidget.
*
- * A #BvwError will be returned on error.
- *
- * Return value: a new #BaconVideoWidget, or %NULL; destroy with gtk_widget_destroy()
+ * Return value: a new #BaconVideoWidget; destroy with gtk_widget_destroy()
**/
GtkWidget *
-bacon_video_widget_new (GError ** error)
+bacon_video_widget_new (void)
{
- return GTK_WIDGET (g_initable_new (BACON_TYPE_VIDEO_WIDGET, NULL, error, NULL));
+ return GTK_WIDGET (g_object_new (BACON_TYPE_VIDEO_WIDGET, NULL));
+}
+
+/**
+ * bacon_video_widget_check_init:
+ * @error: a #GError, or %NULL.
+ *
+ * Return value: if an error occured during initialisation, %FALSE is returned
+ * and @error is set. Otherwise, %TRUE is returned.
+ **/
+gboolean
+bacon_video_widget_check_init (BaconVideoWidget *bvw,
+ GError **error)
+{
+ g_return_val_if_fail (bvw != NULL, FALSE);
+ g_return_val_if_fail (BACON_IS_VIDEO_WIDGET (bvw), FALSE);
+
+ if (!bvw->init_error)
+ return TRUE;
+
+ g_propagate_error (error, bvw->init_error);
+ bvw->init_error = NULL;
+ return FALSE;
}
/**
diff --git a/src/backend/bacon-video-widget.h b/src/backend/bacon-video-widget.h
index 63ba2e16b..23764b6f2 100644
--- a/src/backend/bacon-video-widget.h
+++ b/src/backend/bacon-video-widget.h
@@ -86,7 +86,9 @@ GQuark bacon_video_widget_error_quark (void) G_GNUC_CONST;
GType bacon_video_widget_get_type (void);
GOptionGroup* bacon_video_widget_get_option_group (void);
-GtkWidget *bacon_video_widget_new (GError **error);
+GtkWidget *bacon_video_widget_new (void);
+gboolean bacon_video_widget_check_init (BaconVideoWidget *bvw,
+ GError **error);
/* Actions */
void bacon_video_widget_open (BaconVideoWidget *bvw,