[gnome-software/wip/hughsie/steam] Move the desktop launch code to the plugin loader



commit 7e273f8160b0791e421f9a229deef7963fc80cfc
Author: Richard Hughes <richard hughsie com>
Date:   Fri Oct 2 13:32:42 2015 +0100

    Move the desktop launch code to the plugin loader
    
    This allows us to launch steam games with the linux client.

 src/gs-plugin-loader.c          |    5 ++
 src/gs-plugin-loader.h          |    1 +
 src/gs-plugin.h                 |    4 ++
 src/gs-shell-details.c          |   41 +++++++++--------
 src/plugins/Makefile.am         |    6 ++
 src/plugins/gs-plugin-desktop.c |   97 +++++++++++++++++++++++++++++++++++++++
 src/plugins/gs-plugin-steam.c   |   20 ++++++++
 7 files changed, 155 insertions(+), 19 deletions(-)
---
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index 27d9f5d..65c12ac 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -2519,6 +2519,11 @@ gs_plugin_loader_app_action_async (GsPluginLoader *plugin_loader,
                state->state_success = AS_APP_STATE_UNKNOWN;
                state->state_failure = AS_APP_STATE_UNKNOWN;
                break;
+       case GS_PLUGIN_LOADER_ACTION_LAUNCH:
+               state->function_name = "gs_plugin_app_launch";
+               state->state_success = AS_APP_STATE_UNKNOWN;
+               state->state_failure = AS_APP_STATE_UNKNOWN;
+               break;
        default:
                g_assert_not_reached ();
                break;
diff --git a/src/gs-plugin-loader.h b/src/gs-plugin-loader.h
index b823efd..c771239 100644
--- a/src/gs-plugin-loader.h
+++ b/src/gs-plugin-loader.h
@@ -56,6 +56,7 @@ typedef enum {
        GS_PLUGIN_LOADER_ACTION_INSTALL,
        GS_PLUGIN_LOADER_ACTION_REMOVE,
        GS_PLUGIN_LOADER_ACTION_SET_RATING,
+       GS_PLUGIN_LOADER_ACTION_LAUNCH,
        GS_PLUGIN_LOADER_ACTION_LAST
 } GsPluginLoaderAction;
 
diff --git a/src/gs-plugin.h b/src/gs-plugin.h
index b5b7005..6fd029c 100644
--- a/src/gs-plugin.h
+++ b/src/gs-plugin.h
@@ -242,6 +242,10 @@ gboolean    gs_plugin_app_remove                   (GsPlugin       *plugin,
                                                         GsApp          *app,
                                                         GCancellable   *cancellable,
                                                         GError         **error);
+gboolean        gs_plugin_app_launch                   (GsPlugin       *plugin,
+                                                        GsApp          *app,
+                                                        GCancellable   *cancellable,
+                                                        GError         **error);
 gboolean        gs_plugin_app_set_rating               (GsPlugin       *plugin,
                                                         GsApp          *app,
                                                         GCancellable   *cancellable,
diff --git a/src/gs-shell-details.c b/src/gs-shell-details.c
index 3e7240e..9390bae 100644
--- a/src/gs-shell-details.c
+++ b/src/gs-shell-details.c
@@ -1126,31 +1126,34 @@ gs_shell_details_addon_selected_cb (GsAppAddonRow *row,
 }
 
 /**
- * gs_shell_details_app_launch_button_cb:
+ * gs_shell_details_app_launch_cb:
  **/
 static void
-gs_shell_details_app_launch_button_cb (GtkWidget *widget, GsShellDetails *self)
+gs_shell_details_app_launch_cb (GObject *source,
+                               GAsyncResult *res,
+                               gpointer user_data)
 {
-       GdkDisplay *display;
-       const gchar *desktop_id;
+       GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (source);
+       GsShellDetails *self = GS_SHELL_DETAILS (user_data);
        g_autoptr(GError) error = NULL;
-       g_autoptr(GAppInfo) appinfo = NULL;
-       g_autoptr(GAppLaunchContext) context = NULL;
 
-       desktop_id = gs_app_get_id (self->app);
-       if (desktop_id == NULL) {
-               g_warning ("no such desktop file: %s", desktop_id);
-               return;
-       }
-       appinfo = G_APP_INFO (g_desktop_app_info_new (desktop_id));
-       if (appinfo == NULL) {
-               g_warning ("no such desktop file: %s", desktop_id);
-               return;
+       if (!gs_plugin_loader_app_action_finish (plugin_loader, res, &error)) {
+               g_warning ("failed to launch %s: %s",
+                          gs_app_get_id (self->app), error->message);
        }
-       display = gdk_display_get_default ();
-       context = G_APP_LAUNCH_CONTEXT (gdk_display_get_app_launch_context (display));
-       if (!g_app_info_launch (appinfo, NULL, context, &error))
-               g_warning ("launching %s failed: %s", desktop_id, error->message);
+}
+
+/**
+ * gs_shell_details_app_launch_button_cb:
+ **/
+static void
+gs_shell_details_app_launch_button_cb (GtkWidget *widget, GsShellDetails *self)
+{
+       gs_plugin_loader_app_action_async (self->plugin_loader, self->app,
+                                          GS_PLUGIN_LOADER_ACTION_LAUNCH,
+                                          self->cancellable,
+                                          gs_shell_details_app_launch_cb,
+                                          self);
 }
 
 /**
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 1a6d5ee..f9e4560 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -30,6 +30,7 @@ plugindir = $(libdir)/gs-plugins-${GS_PLUGIN_API_VERSION}
 plugin_LTLIBRARIES =                                   \
        libgs_plugin_steam.la                   \
        libgs_plugin_appstream.la                       \
+       libgs_plugin_desktop.la                         \
        libgs_plugin_hardcoded-featured.la              \
        libgs_plugin_moduleset.la                       \
        libgs_plugin_menu-spec-categories.la            \
@@ -54,6 +55,11 @@ if HAVE_LIMBA
 plugin_LTLIBRARIES += libgs_plugin_limba.la
 endif
 
+libgs_plugin_desktop_la_SOURCES = gs-plugin-desktop.c
+libgs_plugin_desktop_la_LIBADD = $(GS_PLUGIN_LIBS)
+libgs_plugin_desktop_la_LDFLAGS = -module -avoid-version
+libgs_plugin_desktop_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
+
 libgs_plugin_dummy_la_SOURCES = gs-plugin-dummy.c
 libgs_plugin_dummy_la_LIBADD = $(GS_PLUGIN_LIBS)
 libgs_plugin_dummy_la_LDFLAGS = -module -avoid-version
diff --git a/src/plugins/gs-plugin-desktop.c b/src/plugins/gs-plugin-desktop.c
new file mode 100644
index 0000000..c36d8dc
--- /dev/null
+++ b/src/plugins/gs-plugin-desktop.c
@@ -0,0 +1,97 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2015 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <config.h>
+
+#include <gs-plugin.h>
+#include <gio/gdesktopappinfo.h>
+
+/**
+ * gs_plugin_get_name:
+ */
+const gchar *
+gs_plugin_get_name (void)
+{
+       return "desktop";
+}
+
+/**
+ * gs_plugin_get_deps:
+ */
+const gchar **
+gs_plugin_get_deps (GsPlugin *plugin)
+{
+       static const gchar *deps[] = {
+               "steam",                /* this might handle */
+               NULL };
+       return deps;
+}
+
+/**
+ * gs_plugin_app_launch:
+ */
+static gboolean
+gs_plugin_desktop_app_launch_cb (gpointer user_data)
+{
+       GAppInfo *appinfo = G_APP_INFO (user_data);
+       GdkDisplay *display;
+       g_autoptr(GAppLaunchContext) context = NULL;
+       g_autoptr(GError) error = NULL;
+
+       display = gdk_display_get_default ();
+       context = G_APP_LAUNCH_CONTEXT (gdk_display_get_app_launch_context (display));
+       if (!g_app_info_launch (appinfo, NULL, context, &error))
+               g_warning ("Failed to launch: %s", error->message);
+       return G_SOURCE_REMOVE;
+}
+
+/**
+ * gs_plugin_app_launch:
+ */
+gboolean
+gs_plugin_app_launch (GsPlugin *plugin, GsApp *app,
+                     GCancellable *cancellable, GError **error)
+{
+       const gchar *desktop_id;
+       g_autoptr(GAppInfo) appinfo = NULL;
+
+       /* not us */
+       desktop_id = gs_app_get_id (app);
+       if (desktop_id == NULL)
+               return TRUE;
+
+       /* not found */
+       appinfo = G_APP_INFO (g_desktop_app_info_new (desktop_id));
+       if (appinfo == NULL) {
+               g_set_error (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_FAILED,
+                            "no such desktop file: %s", desktop_id);
+               return FALSE;
+       }
+
+       /* do this idle on the main thread */
+       g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
+                        gs_plugin_desktop_app_launch_cb,
+                        g_object_ref (appinfo),
+                        (GDestroyNotify) g_object_unref);
+       return TRUE;
+}
diff --git a/src/plugins/gs-plugin-steam.c b/src/plugins/gs-plugin-steam.c
index d922d03..3032377 100644
--- a/src/plugins/gs-plugin-steam.c
+++ b/src/plugins/gs-plugin-steam.c
@@ -954,3 +954,23 @@ gs_plugin_app_remove (GsPlugin *plugin, GsApp *app,
        cmdline = g_strdup_printf ("steam steam://uninstall/%s", gameid);
        return g_spawn_command_line_sync (cmdline, NULL, NULL, NULL, error);
 }
+
+/**
+ * gs_plugin_app_launch:
+ */
+gboolean
+gs_plugin_app_launch (GsPlugin *plugin, GsApp *app,
+                     GCancellable *cancellable, GError **error)
+{
+       const gchar *gameid;
+       g_autofree gchar *cmdline = NULL;
+
+       /* check is us */
+       gameid = gs_app_get_metadata_item (app, "X-Steam-GameID");
+       if (gameid == NULL)
+               return TRUE;
+
+       /* this is async as steam is a different process: FIXME: use D-Bus */
+       cmdline = g_strdup_printf ("steam steam://run/%s", gameid);
+       return g_spawn_command_line_sync (cmdline, NULL, NULL, NULL, error);
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]