diff options
author | Debarshi Ray <debarshir@gnome.org> | 2017-03-04 08:34:13 +0100 |
---|---|---|
committer | Debarshi Ray <debarshir@gnome.org> | 2017-03-06 01:05:07 +0100 |
commit | a4928d0f5e7aebe7d0670fb65d5b6c1bcbe5dd60 (patch) | |
tree | bc966e5dce61393af355cfd67c2ffb6e23839ea0 | |
parent | 8bb1aebf7f2488fb81052732224a8ec79c36fcfa (diff) | |
download | libgd-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.c | 26 | ||||
-rw-r--r-- | 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; |