summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDebarshi Ray <debarshir@gnome.org>2017-03-04 08:34:13 +0100
committerDebarshi Ray <debarshir@gnome.org>2017-03-06 01:05:07 +0100
commita4928d0f5e7aebe7d0670fb65d5b6c1bcbe5dd60 (patch)
treebc966e5dce61393af355cfd67c2ffb6e23839ea0
parent8bb1aebf7f2488fb81052732224a8ec79c36fcfa (diff)
downloadlibgd-a4928d0f5e7aebe7d0670fb65d5b6c1bcbe5dd60.tar.gz
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
-rw-r--r--libgd/gd-main-box.c26
-rw-r--r--libgd/gd-main-icon-box.c19
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;