[gnome-software/wip/jrocha/shortcut-support] Add support for app shortcut addition/removal
- From: Joaquim Manuel Pereira Rocha <jrocha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/wip/jrocha/shortcut-support] Add support for app shortcut addition/removal
- Date: Thu, 21 Apr 2016 09:52:49 +0000 (UTC)
commit 2cf05addd44ebdf679d207c8ab38980823f56e60
Author: Joaquim Rocha <jrocha endlessm com>
Date: Wed Apr 13 13:36:05 2016 +0200
Add support for app shortcut addition/removal
Some desktops where GNOME Software is used allow to have shortcuts to
apps and it's useful for users to be able to add/remove a shortcut from
the place where they are install applications. Hence, these changes
implement the support for adding or removing shortcuts from the app
details page.
The shortcut integration in the desktop is done using the plugin's
methods gs_plugin_add_shortcut/gs_plugin_remove_shortcut and the actual
shortcut buttons are only displayed if these methods are actually implemented.
Shortcuts can mean e.g. an icon in the desktop or in a favorites area.
src/gs-app.h | 4 ++
src/gs-page.c | 50 +++++++++++++++++++++++++++
src/gs-page.h | 4 ++
src/gs-plugin-loader.c | 6 +++
src/gs-plugin-loader.h | 2 +
src/gs-plugin.h | 8 ++++
src/gs-shell-details.c | 86 +++++++++++++++++++++++++++++++++++++++++++++-
src/gs-shell-details.ui | 29 ++++++++++++++++
8 files changed, 187 insertions(+), 2 deletions(-)
---
diff --git a/src/gs-app.h b/src/gs-app.h
index a868b58..a74bdb7 100644
--- a/src/gs-app.h
+++ b/src/gs-app.h
@@ -82,6 +82,10 @@ typedef enum {
#define AS_APP_QUIRK_NOT_REVIEWABLE (1 << 5)
#endif
+#if !AS_CHECK_VERSION(0,5,15)
+#define AS_APP_QUIRK_HAS_SHORTCUT (1 << 6)
+#endif
+
GQuark gs_app_error_quark (void);
GsApp *gs_app_new (const gchar *id);
diff --git a/src/gs-page.c b/src/gs-page.c
index b7dd9da..7be141a 100644
--- a/src/gs-page.c
+++ b/src/gs-page.c
@@ -380,6 +380,56 @@ gs_page_launch_app (GsPage *page, GsApp *app)
NULL);
}
+static void
+gs_page_app_shortcut_added_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (source);
+ g_autoptr(GError) error = NULL;
+ if (!gs_plugin_loader_app_action_finish (plugin_loader, res, &error)) {
+ g_warning ("failed to add a shortcut to GsApp: %s", error->message);
+ return;
+ }
+}
+
+void
+gs_page_shortcut_add (GsPage *page, GsApp *app)
+{
+ GsPagePrivate *priv = gs_page_get_instance_private (page);
+ gs_plugin_loader_app_action_async (priv->plugin_loader,
+ app,
+ GS_PLUGIN_LOADER_ACTION_ADD_SHORTCUT,
+ priv->cancellable,
+ gs_page_app_shortcut_added_cb,
+ NULL);
+}
+
+static void
+gs_page_app_shortcut_removed_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (source);
+ g_autoptr(GError) error = NULL;
+ if (!gs_plugin_loader_app_action_finish (plugin_loader, res, &error)) {
+ g_warning ("failed to remove the shortcut to GsApp: %s", error->message);
+ return;
+ }
+}
+
+void
+gs_page_shortcut_remove (GsPage *page, GsApp *app)
+{
+ GsPagePrivate *priv = gs_page_get_instance_private (page);
+ gs_plugin_loader_app_action_async (priv->plugin_loader,
+ app,
+ GS_PLUGIN_LOADER_ACTION_REMOVE_SHORTCUT,
+ priv->cancellable,
+ gs_page_app_shortcut_removed_cb,
+ NULL);
+}
+
/**
* gs_page_switch_to:
*
diff --git a/src/gs-page.h b/src/gs-page.h
index a06505b..b63bd8e 100644
--- a/src/gs-page.h
+++ b/src/gs-page.h
@@ -61,6 +61,10 @@ void gs_page_update_app (GsPage *page,
GsApp *app);
void gs_page_launch_app (GsPage *page,
GsApp *app);
+void gs_page_shortcut_add (GsPage *page,
+ GsApp *app);
+void gs_page_shortcut_remove (GsPage *page,
+ GsApp *app);
void gs_page_switch_to (GsPage *page,
gboolean scroll_up);
void gs_page_setup (GsPage *page,
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index 74dfe55..ca72920 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -2885,6 +2885,12 @@ gs_plugin_loader_app_action_async (GsPluginLoader *plugin_loader,
case GS_PLUGIN_LOADER_ACTION_UPDATE_CANCEL:
state->function_name = "gs_plugin_update_cancel";
break;
+ case GS_PLUGIN_LOADER_ACTION_ADD_SHORTCUT:
+ state->function_name = "gs_plugin_add_shortcut";
+ break;
+ case GS_PLUGIN_LOADER_ACTION_REMOVE_SHORTCUT:
+ state->function_name = "gs_plugin_remove_shortcut";
+ break;
default:
g_assert_not_reached ();
break;
diff --git a/src/gs-plugin-loader.h b/src/gs-plugin-loader.h
index 2957079..4842e23 100644
--- a/src/gs-plugin-loader.h
+++ b/src/gs-plugin-loader.h
@@ -61,6 +61,8 @@ typedef enum {
GS_PLUGIN_LOADER_ACTION_UPGRADE_TRIGGER,
GS_PLUGIN_LOADER_ACTION_LAUNCH,
GS_PLUGIN_LOADER_ACTION_UPDATE_CANCEL,
+ GS_PLUGIN_LOADER_ACTION_ADD_SHORTCUT,
+ GS_PLUGIN_LOADER_ACTION_REMOVE_SHORTCUT,
GS_PLUGIN_LOADER_ACTION_LAST
} GsPluginLoaderAction;
diff --git a/src/gs-plugin.h b/src/gs-plugin.h
index a5b25f3..1171d12 100644
--- a/src/gs-plugin.h
+++ b/src/gs-plugin.h
@@ -266,6 +266,14 @@ gboolean gs_plugin_launch (GsPlugin *plugin,
GsApp *app,
GCancellable *cancellable,
GError **error);
+gboolean gs_plugin_add_shortcut (GsPlugin *plugin,
+ GsApp *app,
+ GCancellable *cancellable,
+ GError **error);
+gboolean gs_plugin_remove_shortcut (GsPlugin *plugin,
+ GsApp *app,
+ GCancellable *cancellable,
+ GError **error);
gboolean gs_plugin_update_cancel (GsPlugin *plugin,
GsApp *app,
GCancellable *cancellable,
diff --git a/src/gs-shell-details.c b/src/gs-shell-details.c
index f0b3d07..9d38f5a 100644
--- a/src/gs-shell-details.c
+++ b/src/gs-shell-details.c
@@ -70,6 +70,8 @@ struct _GsShellDetails
GtkWidget *box_details_screenshot_main;
GtkWidget *box_details_screenshot_thumbnails;
GtkWidget *button_details_launch;
+ GtkWidget *button_details_add_shortcut;
+ GtkWidget *button_details_remove_shortcut;
GtkWidget *button_details_website;
GtkWidget *button_install;
GtkWidget *button_remove;
@@ -154,6 +156,55 @@ gs_shell_details_set_state (GsShellDetails *self,
}
}
+static void
+gs_shell_details_update_shortcut_button (GsShellDetails *self)
+{
+ gboolean add_shortcut_func;
+ gboolean remove_shortcut_func;
+ gboolean has_shortcut;
+
+ gtk_widget_set_visible (self->button_details_add_shortcut,
+ FALSE);
+ gtk_widget_set_visible (self->button_details_remove_shortcut,
+ FALSE);
+
+ if (gs_app_get_kind (self->app) != AS_APP_KIND_DESKTOP)
+ return;
+
+ /* only consider the shortcut button if the app is installed */
+ switch (gs_app_get_state (self->app)) {
+ case AS_APP_STATE_INSTALLED:
+ case AS_APP_STATE_UPDATABLE:
+ case AS_APP_STATE_UPDATABLE_LIVE:
+ break;
+ default:
+ return;
+ }
+
+ add_shortcut_func =
+ gs_plugin_loader_get_plugin_supported (self->plugin_loader,
+ "gs_plugin_add_shortcut");
+ remove_shortcut_func =
+ gs_plugin_loader_get_plugin_supported (self->plugin_loader,
+ "gs_plugin_remove_shortcut");
+
+ has_shortcut = gs_app_has_quirk (self->app, AS_APP_QUIRK_HAS_SHORTCUT);
+
+ if (add_shortcut_func) {
+ gtk_widget_set_visible (self->button_details_add_shortcut,
+ !has_shortcut || !remove_shortcut_func);
+ gtk_widget_set_sensitive (self->button_details_add_shortcut,
+ !has_shortcut);
+ }
+
+ if (remove_shortcut_func) {
+ gtk_widget_set_visible (self->button_details_remove_shortcut,
+ has_shortcut || !add_shortcut_func);
+ gtk_widget_set_sensitive (self->button_details_remove_shortcut,
+ has_shortcut);
+ }
+}
+
/**
* gs_shell_details_switch_to:
**/
@@ -270,9 +321,10 @@ gs_shell_details_switch_to (GsPage *page, gboolean scroll_up)
break;
}
- /* don't show the launch button if the app doesn't have a desktop ID */
- if (gs_app_get_id (self->app) == NULL)
+ /* don't show the launch and shortcut buttons if the app doesn't have a desktop ID */
+ if (gs_app_get_id (self->app) == NULL) {
gtk_widget_set_visible (self->button_details_launch, FALSE);
+ }
/* remove button */
if (gs_app_has_quirk (self->app, AS_APP_QUIRK_COMPULSORY) ||
@@ -915,6 +967,8 @@ gs_shell_details_refresh_all (GsShellDetails *self)
break;
}
+ gs_shell_details_update_shortcut_button (self);
+
addons = gtk_container_get_children (GTK_CONTAINER (self->list_box_addons));
gtk_widget_set_visible (self->box_addons, addons != NULL);
g_list_free (addons);
@@ -1433,6 +1487,26 @@ gs_shell_details_app_launch_button_cb (GtkWidget *widget, GsShellDetails *self)
}
/**
+ * gs_shell_details_app_add_shortcut_button_cb:
+ **/
+static void
+gs_shell_details_app_add_shortcut_button_cb (GtkWidget *widget,
+ GsShellDetails *self)
+{
+ gs_page_shortcut_add (GS_PAGE (self), self->app);
+}
+
+/**
+ * gs_shell_details_app_remove_shortcut_button_cb:
+ **/
+static void
+gs_shell_details_app_remove_shortcut_button_cb (GtkWidget *widget,
+ GsShellDetails *self)
+{
+ gs_page_shortcut_remove (GS_PAGE (self), self->app);
+}
+
+/**
* gs_shell_details_review_response_cb:
**/
static void
@@ -1535,6 +1609,12 @@ gs_shell_details_setup (GsShellDetails *self,
g_signal_connect (self->button_details_launch, "clicked",
G_CALLBACK (gs_shell_details_app_launch_button_cb),
self);
+ g_signal_connect (self->button_details_add_shortcut, "clicked",
+ G_CALLBACK (gs_shell_details_app_add_shortcut_button_cb),
+ self);
+ g_signal_connect (self->button_details_remove_shortcut, "clicked",
+ G_CALLBACK (gs_shell_details_app_remove_shortcut_button_cb),
+ self);
g_signal_connect (self->button_details_website, "clicked",
G_CALLBACK (gs_shell_details_website_cb),
self);
@@ -1599,6 +1679,8 @@ gs_shell_details_class_init (GsShellDetailsClass *klass)
gtk_widget_class_bind_template_child (widget_class, GsShellDetails, box_details_screenshot_main);
gtk_widget_class_bind_template_child (widget_class, GsShellDetails,
box_details_screenshot_thumbnails);
gtk_widget_class_bind_template_child (widget_class, GsShellDetails, button_details_launch);
+ gtk_widget_class_bind_template_child (widget_class, GsShellDetails, button_details_add_shortcut);
+ gtk_widget_class_bind_template_child (widget_class, GsShellDetails, button_details_remove_shortcut);
gtk_widget_class_bind_template_child (widget_class, GsShellDetails, button_details_website);
gtk_widget_class_bind_template_child (widget_class, GsShellDetails, button_install);
gtk_widget_class_bind_template_child (widget_class, GsShellDetails, button_remove);
diff --git a/src/gs-shell-details.ui b/src/gs-shell-details.ui
index c5f87f6..63080b4 100644
--- a/src/gs-shell-details.ui
+++ b/src/gs-shell-details.ui
@@ -213,6 +213,35 @@
<property name="position">4</property>
</packing>
</child>
+ <child>
+ <object class="GtkLinkButton" id="button_details_add_shortcut">
+ <property name="visible">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="label" translatable="yes" comments="Translators: A label
for a button to add a shortcut to the selected application.">_Add shortcut</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">5</property>
+ <property name="pack-type">end</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLinkButton" id="button_details_remove_shortcut">
+ <property name="visible">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="label" translatable="yes" comments="Translators: A label
for a button to remove a shortcut to the selected application.">Re_move shortcut</property></object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">6</property>
+ <property name="pack-type">end</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="expand">False</property>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]