summaryrefslogtreecommitdiff
path: root/src/backend/bacon-video-widget-gst-missing-plugins.c
diff options
context:
space:
mode:
authorKalev Lember <kalevlember@gmail.com>2015-02-13 16:30:13 +0100
committerKalev Lember <kalevlember@gmail.com>2015-02-20 17:38:26 +0100
commitdd42ebd45cf39bbdd8b1d5dd0fb0682c00d46b41 (patch)
treef755cc793d48b41ce140e45455bde413832d629b /src/backend/bacon-video-widget-gst-missing-plugins.c
parentda91464344277299902c6a1227d4d2b53e57b8b4 (diff)
downloadtotem-dd42ebd45cf39bbdd8b1d5dd0fb0682c00d46b41.tar.gz
missing plugins: Ask the user before spawning a plugin search
Previously, the PackageKit session service implementation would use Totem's window xid to attach its own dialogs. This however no longer works in Wayland world. Instead of attaching a dialog to Totem's window, gnome-software by default now pops up a Shell notification asking for confirmation before launching the codec search. This is however just a fallback and the preferred way is for an app to pop up its own dialog / in-app notification before starting the codec installation. This commit implements the confirmation dialog within Totem and passes down necessary flags to supress the Shell notification in that case. https://bugzilla.gnome.org/show_bug.cgi?id=744610
Diffstat (limited to 'src/backend/bacon-video-widget-gst-missing-plugins.c')
-rw-r--r--src/backend/bacon-video-widget-gst-missing-plugins.c156
1 files changed, 150 insertions, 6 deletions
diff --git a/src/backend/bacon-video-widget-gst-missing-plugins.c b/src/backend/bacon-video-widget-gst-missing-plugins.c
index 6ceead3de..c71756601 100644
--- a/src/backend/bacon-video-widget-gst-missing-plugins.c
+++ b/src/backend/bacon-video-widget-gst-missing-plugins.c
@@ -34,6 +34,8 @@
#include <gst/pbutils/pbutils.h>
#include <gst/pbutils/install-plugins.h>
+#include <gio/gdesktopappinfo.h>
+#include <glib/gi18n.h>
#include <gtk/gtk.h>
#ifdef GDK_WINDOWING_X11
@@ -236,8 +238,25 @@ on_plugin_installation_done (GstInstallPluginsReturn res, gpointer user_data)
bacon_video_widget_gst_codec_install_context_free (ctx);
}
+#ifdef GDK_WINDOWING_X11
+#if GST_CHECK_VERSION (1, 5, 0)
+static gchar *
+set_startup_notification_id (GstInstallPluginsContext *install_ctx)
+{
+ gchar *startup_id;
+ guint32 timestamp;
+
+ timestamp = gtk_get_current_event_time ();
+ startup_id = g_strdup_printf ("_TIME%u", timestamp);
+ gst_install_plugins_context_set_startup_notification_id (install_ctx, startup_id);
+ g_free (startup_id);
+}
+#endif
+#endif
+
static gboolean
-bacon_video_widget_start_plugin_installation (TotemCodecInstallContext *ctx)
+bacon_video_widget_start_plugin_installation (TotemCodecInstallContext *ctx,
+ gboolean confirm_search)
{
GstInstallPluginsContext *install_ctx;
GstInstallPluginsReturn status;
@@ -248,6 +267,7 @@ bacon_video_widget_start_plugin_installation (TotemCodecInstallContext *ctx)
install_ctx = gst_install_plugins_context_new ();
#if GST_CHECK_VERSION (1, 5, 0)
gst_install_plugins_context_set_desktop_id (install_ctx, "org.gnome.Totem.desktop");
+ gst_install_plugins_context_set_confirm_search (install_ctx, confirm_search);
#endif
#ifdef GDK_WINDOWING_X11
@@ -259,6 +279,10 @@ bacon_video_widget_start_plugin_installation (TotemCodecInstallContext *ctx)
{
gulong xid = 0;
+#if GST_CHECK_VERSION (1, 5, 0)
+ set_startup_notification_id (install_ctx);
+#endif
+
xid = bacon_video_widget_gst_get_toplevel (GTK_WIDGET (ctx->bvw));
gst_install_plugins_context_set_xid (install_ctx, xid);
}
@@ -289,10 +313,121 @@ bacon_video_widget_start_plugin_installation (TotemCodecInstallContext *ctx)
return TRUE;
}
+#if GST_CHECK_VERSION (1, 5, 0)
+static void
+codec_confirmation_dialog_response_cb (GtkDialog *dialog,
+ GtkResponseType response_type,
+ gpointer user_data)
+{
+ TotemCodecInstallContext *ctx = user_data;
+
+ switch (response_type) {
+ case GTK_RESPONSE_ACCEPT:
+ bacon_video_widget_start_plugin_installation (ctx, FALSE);
+ break;
+ case GTK_RESPONSE_CANCEL:
+ case GTK_RESPONSE_DELETE_EVENT:
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
+show_codec_confirmation_dialog (TotemCodecInstallContext *ctx,
+ const gchar *install_helper_display_name)
+{
+ GtkWidget *button;
+ GtkWidget *dialog;
+ GtkWidget *toplevel;
+ gchar *button_text;
+ gchar *descriptions_text;
+ gchar *message_text;
+
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (ctx->bvw));
+
+ dialog = gtk_message_dialog_new (GTK_WINDOW (toplevel),
+ GTK_DIALOG_MODAL |
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CANCEL,
+ _("Unable to play the file"));
+
+ descriptions_text = g_strjoinv (", ", ctx->descriptions);
+ message_text = g_strdup_printf (ngettext ("%s is required to play the file, but is not installed.",
+ "%s are required to play the file, but are not installed.",
+ g_strv_length (ctx->descriptions)),
+ descriptions_text);
+
+ /* TRANSLATORS: this is a button to launch a codec installer.
+ * %s will be replaced with the software installer's name, e.g.
+ * 'Software' in case of gnome-software. */
+ button_text = g_strdup_printf ("_Find in %s", install_helper_display_name);
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", message_text);
+ button = gtk_dialog_add_button (GTK_DIALOG (dialog),
+ button_text,
+ GTK_RESPONSE_ACCEPT);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
+ gtk_style_context_add_class (gtk_widget_get_style_context (button), "suggested-action");
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (codec_confirmation_dialog_response_cb),
+ ctx);
+
+ gtk_window_present (GTK_WINDOW (dialog));
+
+ g_free (button_text);
+ g_free (descriptions_text);
+ g_free (message_text);
+}
+#endif
+
+static void
+on_packagekit_proxy_ready (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ TotemCodecInstallContext *ctx = (TotemCodecInstallContext *) user_data;
+ GDBusProxy *packagekit_proxy = NULL;
+ GVariant *property = NULL;
+ GError *error = NULL;
+
+ packagekit_proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
+ if (packagekit_proxy == NULL &&
+ g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ goto out;
+ }
+
+#if GST_CHECK_VERSION (1, 5, 0)
+ if (packagekit_proxy != NULL) {
+ property = g_dbus_proxy_get_cached_property (packagekit_proxy, "DisplayName");
+ if (property != NULL) {
+ const gchar *display_name;
+
+ display_name = g_variant_get_string (property, NULL);
+ if (display_name != NULL && display_name[0] != '\0') {
+ show_codec_confirmation_dialog (ctx, display_name);
+ goto out;
+ }
+ }
+ }
+#endif
+
+ /* If the above failed, fall back to immediately starting the codec installation */
+ bacon_video_widget_start_plugin_installation (ctx, TRUE);
+
+out:
+ g_clear_error (&error);
+ g_clear_pointer (&property, g_variant_unref);
+ g_clear_object (&packagekit_proxy);
+}
+
static gboolean
-bacon_video_widget_gst_on_missing_plugins_event (BaconVideoWidget *bvw, char **details,
- char **descriptions, gboolean playing,
- gpointer user_data)
+bacon_video_widget_gst_on_missing_plugins_event (BaconVideoWidget *bvw,
+ char **details,
+ char **descriptions,
+ gboolean playing,
+ gpointer user_data)
{
TotemCodecInstallContext *ctx;
guint i, num;
@@ -331,8 +466,17 @@ bacon_video_widget_gst_on_missing_plugins_event (BaconVideoWidget *bvw, char **d
return FALSE;
}
- if (!bacon_video_widget_start_plugin_installation (ctx))
- return FALSE;
+ /* Get the PackageKit session interface proxy and continue with the
+ * codec installation in the callback */
+ g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL, /* g-interface-info */
+ "org.freedesktop.PackageKit",
+ "/org/freedesktop/PackageKit",
+ "org.freedesktop.PackageKit.Modify2",
+ g_object_get_data (G_OBJECT (bvw), "missing-plugins-cancellable"),
+ on_packagekit_proxy_ready,
+ ctx);
/* if we managed to start playing, pause playback, since some install
* wizard should now take over in a second anyway and the user might not