[libgd] main-box, main-icon-box: Emit selection-changed with updated selection



commit a4928d0f5e7aebe7d0670fb65d5b6c1bcbe5dd60
Author: Debarshi Ray <debarshir gnome org>
Date:   Sat Mar 4 08:34:13 2017 +0100

    main-box, main-icon-box: Emit selection-changed with updated selection
    
    Sometimes, GdMainBox::selection-changed is emitted before the list of
    selected child widgets has been updated. This can happen when a
    selected GdMainBoxItem was removed from the GListModel.
    
    GdMainBox was monitoring removals from the GListModel in order to emit
    selection-changed. However, since it had connected to
    GListModel::items-changed before GdMainIconBox, it was emitting the
    signal before the list of selected children got updated. This can be
    problematic for an application.
    
    An application should be able to use gd_main_box_get_selection from
    its GdMainBox::selection-changed handler and have the updated list of
    selected child widgets.
    
    One option is to have GdMainBox connect to the GListModel after
    GdMainIconBox. However, it would be better to move this logic to
    GdMainIconBox which deals with all the other cases where
    selection-changed needs to be emitted. It is easier to ensure that the
    implementation of a single class stays consistent, as opposed to
    trying to keep two different classes in sync.
    
    GtkFlowBox, the parent of GdMainIconBox, uses the GtkContainer::removed
    virtual method to handle this case. Therefore, it is a natural choice
    for us to hook in and emit the signal.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=779589

 libgd/gd-main-box.c      |   26 +-------------------------
 libgd/gd-main-icon-box.c |   19 +++++++++++++++++++
 2 files changed, 20 insertions(+), 25 deletions(-)
---
diff --git a/libgd/gd-main-box.c b/libgd/gd-main-box.c
index fcbd62a..bb2377e 100644
--- a/libgd/gd-main-box.c
+++ b/libgd/gd-main-box.c
@@ -108,15 +108,6 @@ gd_main_box_item_activated_cb (GdMainBox *self, GdMainBoxChild *child)
 }
 
 static void
-gd_main_box_model_items_changed_cb (GdMainBox *self, guint position, guint removed, guint added)
-{
-  if (removed == 0)
-    return;
-
-  g_signal_emit (self, signals[SELECTION_CHANGED], 0);
-}
-
-static void
 gd_main_box_selection_changed_cb (GdMainBox *self)
 {
   g_signal_emit (self, signals[SELECTION_CHANGED], 0);
@@ -486,24 +477,9 @@ gd_main_box_set_model (GdMainBox *self, GListModel *model)
 
   priv = gd_main_box_get_instance_private (self);
 
-  if (model == priv->model)
+  if (!g_set_object (&priv->model, model))
     return;
 
-  if (priv->model)
-    g_signal_handlers_disconnect_by_func (priv->model, gd_main_box_model_items_changed_cb, self);
-
-  g_clear_object (&priv->model);
-
-  if (model != NULL)
-    {
-      priv->model = g_object_ref (model);
-      g_signal_connect_object (priv->model,
-                               "items-changed",
-                               G_CALLBACK (gd_main_box_model_items_changed_cb),
-                               self,
-                               G_CONNECT_SWAPPED);
-    }
-
   gd_main_box_generic_set_model (GD_MAIN_BOX_GENERIC (priv->current_box), priv->model);
   g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]);
 }
diff --git a/libgd/gd-main-icon-box.c b/libgd/gd-main-icon-box.c
index c84e848..96717ac 100644
--- a/libgd/gd-main-icon-box.c
+++ b/libgd/gd-main-icon-box.c
@@ -766,6 +766,23 @@ gd_main_icon_box_move_cursor (GtkFlowBox *flow_box, GtkMovementStep step, gint c
 }
 
 static void
+gd_main_icon_box_remove (GtkContainer *container, GtkWidget *widget)
+{
+  GdMainIconBox *self = GD_MAIN_ICON_BOX (container);
+  GdMainIconBoxPrivate *priv;
+
+  priv = gd_main_icon_box_get_instance_private (self);
+
+  GTK_CONTAINER_CLASS (gd_main_icon_box_parent_class)->remove (container, widget);
+
+  if (priv->selection_changed)
+    {
+      g_signal_emit_by_name (self, "selection-changed");
+      priv->selection_changed = FALSE;
+    }
+}
+
+static void
 gd_main_icon_box_select_all_flow_box (GtkFlowBox *flow_box)
 {
   GdMainIconBox *self = GD_MAIN_ICON_BOX (flow_box);
@@ -945,6 +962,7 @@ static void
 gd_main_icon_box_class_init (GdMainIconBoxClass *klass)
 {
   GObjectClass *oclass = G_OBJECT_CLASS (klass);
+  GtkContainerClass *cclass = GTK_CONTAINER_CLASS (klass);
   GtkFlowBoxClass *fbclass = GTK_FLOW_BOX_CLASS (klass);
   GtkWidgetClass *wclass = GTK_WIDGET_CLASS (klass);
   GtkBindingSet *binding_set;
@@ -966,6 +984,7 @@ gd_main_icon_box_class_init (GdMainIconBoxClass *klass)
   wclass->drag_data_get = gd_main_icon_box_drag_data_get;
   wclass->focus = gd_main_icon_box_focus;
   wclass->motion_notify_event = gd_main_icon_box_motion_notify_event;
+  cclass->remove = gd_main_icon_box_remove;
   fbclass->activate_cursor_child = gd_main_icon_box_activate_cursor_child;
   fbclass->child_activated = gd_main_icon_box_child_activated;
   fbclass->move_cursor = gd_main_icon_box_move_cursor;


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