[gnome-software/1111-app-details-addons] gs-details-page: Tweak presentation of add-ons




commit 0d8d87b32e5f978ea2a52c44b5216b7c938181ba
Author: Phaedrus Leeds <mwleeds endlessos org>
Date:   Tue Jan 26 17:08:36 2021 -0800

    gs-details-page: Tweak presentation of add-ons
    
    Tweak the display of add-ons to more closely match the design mock-ups
    (see the ticket linked below). The mock-ups use a circular checkbox but
    I'm not sure how to do that so it's still a square one.
    
    Note, there is an assertion failure when the removal confirmation dialog
    is created:
    Gdk gdk_wayland_window_set_dbus_properties_libgtk_only: assertion 'GDK_IS_WAYLAND_WINDOW (window)' failed
    
    ...but this isn't unique to the removal of add-ons (it happens for apps
    too), and it doesn't prevent the confirmation dialog or the removal from
    happening.
    
    Helps: #1111

 src/gs-app-addon-row.c  | 147 +++++++++++++++++++++++++++++-------------------
 src/gs-app-addon-row.h  |  10 +++-
 src/gs-app-addon-row.ui |  42 ++++++++++----
 src/gs-details-page.c   |  13 +++++
 src/gs-details-page.ui  | 112 ++++++++++++++++++------------------
 src/gs-page.c           |   2 +-
 6 files changed, 200 insertions(+), 126 deletions(-)
---
diff --git a/src/gs-app-addon-row.c b/src/gs-app-addon-row.c
index 9763e22a..22e72808 100644
--- a/src/gs-app-addon-row.c
+++ b/src/gs-app-addon-row.c
@@ -14,30 +14,43 @@
 
 #include "gs-app-addon-row.h"
 
-struct _GsAppAddonRow
+typedef struct
 {
-       GtkListBoxRow    parent_instance;
-
        GsApp           *app;
        GtkWidget       *name_label;
        GtkWidget       *description_label;
        GtkWidget       *label;
+       GtkWidget       *button_remove;
        GtkWidget       *checkbox;
-};
+} GsAppAddonRowPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (GsAppAddonRow, gs_app_addon_row, GTK_TYPE_LIST_BOX_ROW)
 
-G_DEFINE_TYPE (GsAppAddonRow, gs_app_addon_row, GTK_TYPE_LIST_BOX_ROW)
+typedef enum {
+       PROP_SELECTED = 1,
+} GsAppAddonRowProperty;
+
+static GParamSpec *obj_props[PROP_SELECTED + 1] = { NULL, };
 
 enum {
-       PROP_ZERO,
-       PROP_SELECTED
+       SIGNAL_REMOVE_BUTTON_CLICKED,
+       SIGNAL_LAST
 };
 
+static guint signals [SIGNAL_LAST] = { 0 };
+
 static void
 checkbox_toggled (GtkWidget *widget, GsAppAddonRow *row)
 {
        g_object_notify (G_OBJECT (row), "selected");
 }
 
+static void
+app_addon_remove_button_cb (GtkWidget *widget, GsAppAddonRow *row)
+{
+       g_signal_emit (row, signals[SIGNAL_REMOVE_BUTTON_CLICKED], 0);
+}
+
 /**
  * gs_app_addon_row_get_summary:
  *
@@ -46,16 +59,17 @@ checkbox_toggled (GtkWidget *widget, GsAppAddonRow *row)
 static GString *
 gs_app_addon_row_get_summary (GsAppAddonRow *row)
 {
+       GsAppAddonRowPrivate *priv = gs_app_addon_row_get_instance_private (row);
        const gchar *tmp = NULL;
        g_autofree gchar *escaped = NULL;
 
        /* try all these things in order */
-       if (gs_app_get_state (row->app) == GS_APP_STATE_UNAVAILABLE)
-               tmp = gs_app_get_summary_missing (row->app);
+       if (gs_app_get_state (priv->app) == GS_APP_STATE_UNAVAILABLE)
+               tmp = gs_app_get_summary_missing (priv->app);
        if (tmp == NULL || (tmp != NULL && tmp[0] == '\0'))
-               tmp = gs_app_get_summary (row->app);
+               tmp = gs_app_get_summary (priv->app);
        if (tmp == NULL || (tmp != NULL && tmp[0] == '\0'))
-               tmp = gs_app_get_description (row->app);
+               tmp = gs_app_get_description (priv->app);
 
        escaped = g_markup_escape_text (tmp, -1);
        return g_string_new (escaped);
@@ -64,81 +78,86 @@ gs_app_addon_row_get_summary (GsAppAddonRow *row)
 void
 gs_app_addon_row_refresh (GsAppAddonRow *row)
 {
+       GsAppAddonRowPrivate *priv = gs_app_addon_row_get_instance_private (row);
        g_autoptr(GString) str = NULL;
 
-       if (row->app == NULL)
+       if (priv->app == NULL)
                return;
 
        /* join the lines */
        str = gs_app_addon_row_get_summary (row);
        as_utils_string_replace (str, "\n", " ");
-       gtk_label_set_markup (GTK_LABEL (row->description_label), str->str);
-       gtk_label_set_label (GTK_LABEL (row->name_label),
-                            gs_app_get_name (row->app));
+       gtk_label_set_markup (GTK_LABEL (priv->description_label), str->str);
+       gtk_label_set_label (GTK_LABEL (priv->name_label),
+                            gs_app_get_name (priv->app));
 
        /* update the state label */
-       switch (gs_app_get_state (row->app)) {
+       switch (gs_app_get_state (priv->app)) {
        case GS_APP_STATE_QUEUED_FOR_INSTALL:
-               gtk_widget_set_visible (row->label, TRUE);
-               gtk_label_set_label (GTK_LABEL (row->label), _("Pending"));
+               gtk_widget_set_visible (priv->label, TRUE);
+               gtk_label_set_label (GTK_LABEL (priv->label), _("Pending"));
                break;
        case GS_APP_STATE_UPDATABLE:
        case GS_APP_STATE_UPDATABLE_LIVE:
        case GS_APP_STATE_INSTALLED:
-               gtk_widget_set_visible (row->label, TRUE);
-               gtk_label_set_label (GTK_LABEL (row->label), _("Installed"));
+               gtk_widget_set_visible (priv->label, TRUE);
+               gtk_label_set_label (GTK_LABEL (priv->label), _("Installed"));
                break;
        case GS_APP_STATE_INSTALLING:
-               gtk_widget_set_visible (row->label, TRUE);
-               gtk_label_set_label (GTK_LABEL (row->label), _("Installing"));
+               gtk_widget_set_visible (priv->label, TRUE);
+               gtk_label_set_label (GTK_LABEL (priv->label), _("Installing"));
                break;
        case GS_APP_STATE_REMOVING:
-               gtk_widget_set_visible (row->label, TRUE);
-               gtk_label_set_label (GTK_LABEL (row->label), _("Removing"));
+               gtk_widget_set_visible (priv->label, TRUE);
+               gtk_label_set_label (GTK_LABEL (priv->label), _("Removing"));
                break;
        default:
-               gtk_widget_set_visible (row->label, FALSE);
+               gtk_widget_set_visible (priv->label, FALSE);
                break;
        }
 
        /* update the checkbox */
-       g_signal_handlers_block_by_func (row->checkbox, checkbox_toggled, row);
-       switch (gs_app_get_state (row->app)) {
+       g_signal_handlers_block_by_func (priv->checkbox, checkbox_toggled, row);
+       switch (gs_app_get_state (priv->app)) {
        case GS_APP_STATE_QUEUED_FOR_INSTALL:
-               gtk_widget_set_sensitive (row->checkbox, TRUE);
-               gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (row->checkbox), TRUE);
+               gtk_widget_set_sensitive (priv->checkbox, TRUE);
+               gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->checkbox), TRUE);
                break;
        case GS_APP_STATE_AVAILABLE:
        case GS_APP_STATE_AVAILABLE_LOCAL:
-               gtk_widget_set_sensitive (row->checkbox, TRUE);
-               gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (row->checkbox), FALSE);
+               gtk_widget_set_sensitive (priv->checkbox, TRUE);
+               gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->checkbox), FALSE);
+               gtk_widget_set_visible (priv->button_remove, FALSE);
                break;
        case GS_APP_STATE_UPDATABLE:
        case GS_APP_STATE_INSTALLED:
-               gtk_widget_set_sensitive (row->checkbox, TRUE);
-               gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (row->checkbox), TRUE);
+               gtk_widget_set_visible (priv->checkbox, FALSE);
+               gtk_widget_set_visible (priv->button_remove, TRUE);
+               gtk_widget_set_sensitive (priv->button_remove, TRUE);
                break;
        case GS_APP_STATE_INSTALLING:
-               gtk_widget_set_sensitive (row->checkbox, FALSE);
-               gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (row->checkbox), TRUE);
+               gtk_widget_set_sensitive (priv->checkbox, FALSE);
+               gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->checkbox), TRUE);
                break;
        case GS_APP_STATE_REMOVING:
-               gtk_widget_set_sensitive (row->checkbox, FALSE);
-               gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (row->checkbox), FALSE);
+               gtk_widget_set_visible (priv->checkbox, FALSE);
+               gtk_widget_set_visible (priv->button_remove, TRUE);
+               gtk_widget_set_sensitive (priv->button_remove, FALSE);
                break;
        default:
-               gtk_widget_set_sensitive (row->checkbox, FALSE);
-               gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (row->checkbox), FALSE);
+               gtk_widget_set_sensitive (priv->checkbox, FALSE);
+               gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->checkbox), FALSE);
                break;
        }
-       g_signal_handlers_unblock_by_func (row->checkbox, checkbox_toggled, row);
+       g_signal_handlers_unblock_by_func (priv->checkbox, checkbox_toggled, row);
 }
 
 GsApp *
 gs_app_addon_row_get_addon (GsAppAddonRow *row)
 {
+       GsAppAddonRowPrivate *priv = gs_app_addon_row_get_instance_private (row);
        g_return_val_if_fail (GS_IS_APP_ADDON_ROW (row), NULL);
-       return row->app;
+       return priv->app;
 }
 
 static gboolean
@@ -163,9 +182,10 @@ gs_app_addon_row_notify_props_changed_cb (GsApp *app,
 static void
 gs_app_addon_row_set_addon (GsAppAddonRow *row, GsApp *app)
 {
-       row->app = g_object_ref (app);
+       GsAppAddonRowPrivate *priv = gs_app_addon_row_get_instance_private (row);
+       priv->app = g_object_ref (app);
 
-       g_signal_connect_object (row->app, "notify::state",
+       g_signal_connect_object (priv->app, "notify::state",
                                 G_CALLBACK (gs_app_addon_row_notify_props_changed_cb),
                                 row, 0);
        gs_app_addon_row_refresh (row);
@@ -175,11 +195,12 @@ static void
 gs_app_addon_row_destroy (GtkWidget *object)
 {
        GsAppAddonRow *row = GS_APP_ADDON_ROW (object);
+       GsAppAddonRowPrivate *priv = gs_app_addon_row_get_instance_private (row);
 
-       if (row->app)
-               g_signal_handlers_disconnect_by_func (row->app, gs_app_addon_row_notify_props_changed_cb, 
row);
+       if (priv->app)
+               g_signal_handlers_disconnect_by_func (priv->app, gs_app_addon_row_notify_props_changed_cb, 
row);
 
-       g_clear_object (&row->app);
+       g_clear_object (&priv->app);
 
        GTK_WIDGET_CLASS (gs_app_addon_row_parent_class)->destroy (object);
 }
@@ -217,7 +238,6 @@ gs_app_addon_row_get_property (GObject *object, guint prop_id, GValue *value, GP
 static void
 gs_app_addon_row_class_init (GsAppAddonRowClass *klass)
 {
-       GParamSpec *pspec;
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
        GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
@@ -226,38 +246,51 @@ gs_app_addon_row_class_init (GsAppAddonRowClass *klass)
 
        widget_class->destroy = gs_app_addon_row_destroy;
 
-       pspec = g_param_spec_boolean ("selected", NULL, NULL,
-                                     FALSE, G_PARAM_READWRITE);
-       g_object_class_install_property (object_class, PROP_SELECTED, pspec);
+       obj_props[PROP_SELECTED] = g_param_spec_boolean ("selected", NULL, NULL,
+                                                        FALSE, G_PARAM_READWRITE);
+       g_object_class_install_properties (object_class, G_N_ELEMENTS (obj_props), obj_props);
+
+       signals [SIGNAL_REMOVE_BUTTON_CLICKED] =
+               g_signal_new ("remove-button-clicked",
+                             G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+                             G_STRUCT_OFFSET (GsAppAddonRowClass, remove_button_clicked),
+                             NULL, NULL, g_cclosure_marshal_VOID__VOID,
+                             G_TYPE_NONE, 0);
 
        gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/Software/gs-app-addon-row.ui");
 
-       gtk_widget_class_bind_template_child (widget_class, GsAppAddonRow, name_label);
-       gtk_widget_class_bind_template_child (widget_class, GsAppAddonRow, description_label);
-       gtk_widget_class_bind_template_child (widget_class, GsAppAddonRow, label);
-       gtk_widget_class_bind_template_child (widget_class, GsAppAddonRow, checkbox);
+       gtk_widget_class_bind_template_child_private (widget_class, GsAppAddonRow, name_label);
+       gtk_widget_class_bind_template_child_private (widget_class, GsAppAddonRow, description_label);
+       gtk_widget_class_bind_template_child_private (widget_class, GsAppAddonRow, label);
+       gtk_widget_class_bind_template_child_private (widget_class, GsAppAddonRow, checkbox);
+       gtk_widget_class_bind_template_child_private (widget_class, GsAppAddonRow, button_remove);
 }
 
 static void
 gs_app_addon_row_init (GsAppAddonRow *row)
 {
+       GsAppAddonRowPrivate *priv = gs_app_addon_row_get_instance_private (row);
        gtk_widget_set_has_window (GTK_WIDGET (row), FALSE);
        gtk_widget_init_template (GTK_WIDGET (row));
 
-       g_signal_connect (row->checkbox, "toggled",
+       g_signal_connect (priv->checkbox, "toggled",
                          G_CALLBACK (checkbox_toggled), row);
+       g_signal_connect (priv->button_remove, "clicked",
+                         G_CALLBACK (app_addon_remove_button_cb), row);
 }
 
 void
 gs_app_addon_row_set_selected (GsAppAddonRow *row, gboolean selected)
 {
-       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (row->checkbox), selected);
+       GsAppAddonRowPrivate *priv = gs_app_addon_row_get_instance_private (row);
+       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->checkbox), selected);
 }
 
 gboolean
 gs_app_addon_row_get_selected (GsAppAddonRow *row)
 {
-       return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (row->checkbox));
+       GsAppAddonRowPrivate *priv = gs_app_addon_row_get_instance_private (row);
+       return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->checkbox));
 }
 
 GtkWidget *
diff --git a/src/gs-app-addon-row.h b/src/gs-app-addon-row.h
index 257ef866..3bb8ab46 100644
--- a/src/gs-app-addon-row.h
+++ b/src/gs-app-addon-row.h
@@ -12,12 +12,20 @@
 #include <gtk/gtk.h>
 
 #include "gnome-software-private.h"
+#include "gs-details-page.h"
 
 G_BEGIN_DECLS
 
 #define GS_TYPE_APP_ADDON_ROW (gs_app_addon_row_get_type ())
 
-G_DECLARE_FINAL_TYPE (GsAppAddonRow, gs_app_addon_row, GS, APP_ADDON_ROW, GtkListBoxRow)
+G_DECLARE_DERIVABLE_TYPE (GsAppAddonRow, gs_app_addon_row, GS, APP_ADDON_ROW, GtkListBoxRow)
+
+struct _GsAppAddonRowClass
+{
+       GtkListBoxRowClass                       parent_class;
+
+       void (* remove_button_clicked)           (GsAppAddonRow *row);
+};
 
 GtkWidget      *gs_app_addon_row_new                   (GsApp          *app);
 void            gs_app_addon_row_refresh               (GsAppAddonRow  *row);
diff --git a/src/gs-app-addon-row.ui b/src/gs-app-addon-row.ui
index 471d373a..1e141a2e 100644
--- a/src/gs-app-addon-row.ui
+++ b/src/gs-app-addon-row.ui
@@ -11,12 +11,6 @@
         <property name="margin-start">18</property>
         <property name="margin-end">18</property>
         <property name="orientation">horizontal</property>
-        <child>
-          <object class="GtkCheckButton" id="checkbox">
-            <property name="visible">True</property>
-            <property name="valign">center</property>
-          </object>
-        </child>
         <child>
           <object class="GtkBox" id="name_box">
             <property name="visible">True</property>
@@ -31,6 +25,9 @@
                 <property name="max_width_chars">20</property>
                 <property name="xalign">0.0</property>
                 <property name="yalign">0.5</property>
+                <attributes>
+                  <attribute name="weight" value="bold"/>
+                </attributes>
               </object>
             </child>
             <child>
@@ -49,11 +46,34 @@
           </object>
         </child>
         <child>
-          <object class="GtkLabel" id="label">
-            <property name="visible">False</property>
-            <property name="margin_start">12</property>
-            <property name="width_request">100</property>
-            <property name="xalign">1</property>
+          <object class="GtkBox">
+            <property name="visible">True</property>
+            <property name="orientation">horizontal</property>
+            <property name="valign">center</property>
+            <property name="hexpand">False</property>
+            <child>
+              <object class="GtkLabel" id="label">
+                <property name="visible">False</property>
+                <property name="margin_start">12</property>
+                <property name="margin_end">12</property>
+                <property name="width_request">100</property>
+                <property name="xalign">1</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkButton" id="button_remove">
+                <property name="visible">False</property>
+                <property name="use_underline">True</property>
+                <property name="label" translatable="yes">_Uninstall</property>
+                <property name="width_request">105</property>
+                <property name="can_focus">True</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkCheckButton" id="checkbox">
+                <property name="visible">True</property>
+              </object>
+            </child>
           </object>
           <packing>
             <property name="pack_type">end</property>
diff --git a/src/gs-details-page.c b/src/gs-details-page.c
index 4123ed98..eb831f27 100644
--- a/src/gs-details-page.c
+++ b/src/gs-details-page.c
@@ -1467,6 +1467,7 @@ list_sort_func (GtkListBoxRow *a,
 }
 
 static void gs_details_page_addon_selected_cb (GsAppAddonRow *row, GParamSpec *pspec, GsDetailsPage *self);
+static void gs_details_page_addon_remove_cb (GsAppAddonRow *row, gpointer user_data);
 
 static void
 gs_details_page_refresh_addons (GsDetailsPage *self)
@@ -1494,6 +1495,9 @@ gs_details_page_refresh_addons (GsDetailsPage *self)
                g_signal_connect (row, "notify::selected",
                                  G_CALLBACK (gs_details_page_addon_selected_cb),
                                  self);
+               g_signal_connect (row, "remove-button-clicked",
+                                 G_CALLBACK (gs_details_page_addon_remove_cb),
+                                 self);
        }
 }
 
@@ -2242,6 +2246,15 @@ gs_details_page_addon_selected_cb (GsAppAddonRow *row,
        }
 }
 
+static void
+gs_details_page_addon_remove_cb (GsAppAddonRow *row, gpointer user_data)
+{
+       GsApp *addon;
+       addon = gs_app_addon_row_get_addon (row);
+       GsDetailsPage *self = GS_DETAILS_PAGE (user_data);
+       gs_page_remove_app (GS_PAGE (self), addon, NULL);
+}
+
 static void
 gs_details_page_app_launch_button_cb (GtkWidget *widget, GsDetailsPage *self)
 {
diff --git a/src/gs-details-page.ui b/src/gs-details-page.ui
index 2afc50ea..456c3e54 100644
--- a/src/gs-details-page.ui
+++ b/src/gs-details-page.ui
@@ -388,6 +388,62 @@
                             <property name="margin_bottom">14</property>
                           </object>
                         </child>
+                        <child>
+                          <object class="GtkBox" id="box_addons">
+                            <property name="visible">True</property>
+                            <property name="orientation">vertical</property>
+                            <property name="margin_bottom">26</property>
+
+                            <child>
+                              <object class="GtkBox" id="box_addons_title">
+                                <property name="visible">True</property>
+                                <property name="orientation">vertical</property>
+                                <property name="margin_bottom">18</property>
+                                <child>
+                                  <object class="GtkLabel" id="label_addons_title">
+                                    <property name="visible">True</property>
+                                    <property name="halign">start</property>
+                                    <property name="valign">start</property>
+                                    <property name="hexpand">True</property>
+                                    <property name="xalign">0</property>
+                                    <property name="label" translatable="yes">Add-ons</property>
+                                    <style>
+                                      <class name="application-details-title"/>
+                                    </style>
+                                  </object>
+                                </child>
+                                <child>
+                                  <object class="GtkLabel" id="label_addons_uninstalled_app">
+                                    <property name="visible">True</property>
+                                    <property name="xalign">0</property>
+                                    <property name="wrap">True</property>
+                                    <property name="max-width-chars">40</property>
+                                    <property name="label" translatable="yes">Selected add-ons will be 
installed with the application.</property>
+                                  </object>
+                                </child>
+                              </object>
+                            </child>
+
+                            <child>
+                              <object class="GtkFrame" id="box_addons_frame">
+                                <property name="visible">True</property>
+                                <property name="shadow_type">in</property>
+                                <property name="halign">fill</property>
+                                <property name="valign">start</property>
+                                <style>
+                                  <class name="view"/>
+                                </style>
+                                <child>
+                                  <object class="GtkListBox" id="list_box_addons">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="selection_mode">none</property>
+                                  </object>
+                                </child>
+                              </object>
+                            </child>
+                          </object>
+                        </child>
                         <child>
                           <object class="GtkLabel" id="label_webapp_warning">
                             <property name="visible">False</property>
@@ -1080,62 +1136,6 @@
                             </child>
                           </object>
                         </child>
-                        <child>
-                          <object class="GtkBox" id="box_addons">
-                            <property name="visible">True</property>
-                            <property name="orientation">vertical</property>
-                            <property name="margin_bottom">26</property>
-
-                            <child>
-                              <object class="GtkBox" id="box_addons_title">
-                                <property name="visible">True</property>
-                                <property name="orientation">vertical</property>
-                                <property name="margin_bottom">18</property>
-                                <child>
-                                  <object class="GtkLabel" id="label_addons_title">
-                                    <property name="visible">True</property>
-                                    <property name="halign">start</property>
-                                    <property name="valign">start</property>
-                                    <property name="hexpand">True</property>
-                                    <property name="xalign">0</property>
-                                    <property name="label" translatable="yes">Add-ons</property>
-                                    <style>
-                                      <class name="application-details-title"/>
-                                    </style>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkLabel" id="label_addons_uninstalled_app">
-                                    <property name="visible">True</property>
-                                    <property name="xalign">0</property>
-                                    <property name="wrap">True</property>
-                                    <property name="max-width-chars">40</property>
-                                    <property name="label" translatable="yes">Selected add-ons will be 
installed with the application.</property>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-
-                            <child>
-                              <object class="GtkFrame" id="box_addons_frame">
-                                <property name="visible">True</property>
-                                <property name="shadow_type">in</property>
-                                <property name="halign">fill</property>
-                                <property name="valign">start</property>
-                                <style>
-                                  <class name="view"/>
-                                </style>
-                                <child>
-                                  <object class="GtkListBox" id="list_box_addons">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="selection_mode">none</property>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                          </object>
-                        </child>
                         <child>
                           <object class="GtkBox" id="box_reviews">
                             <property name="visible">False</property>
diff --git a/src/gs-page.c b/src/gs-page.c
index d76db20f..9815623a 100644
--- a/src/gs-page.c
+++ b/src/gs-page.c
@@ -442,7 +442,7 @@ gs_page_remove_app (GsPage *page, GsApp *app, GCancellable *cancellable)
        helper->action = GS_PLUGIN_ACTION_REMOVE;
        helper->app = g_object_ref (app);
        helper->page = g_object_ref (page);
-       helper->cancellable = g_object_ref (cancellable);
+       helper->cancellable = cancellable != NULL ? g_object_ref (cancellable) : NULL;
        if (gs_app_get_state (app) == GS_APP_STATE_QUEUED_FOR_INSTALL) {
                g_autoptr(GsPluginJob) plugin_job = NULL;
                plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_REMOVE,


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