diff --git a/demos/gtk-demo/listview_settings.ui b/demos/gtk-demo/listview_settings.ui index 35c3c79c98..15cbb67d9e 100644 --- a/demos/gtk-demo/listview_settings.ui +++ b/demos/gtk-demo/listview_settings.ui @@ -20,6 +20,7 @@ + item @@ -76,6 +77,7 @@ 1 + cell diff --git a/gtk/gtkgridview.c b/gtk/gtkgridview.c index b87792c7d9..9983d4153a 100644 --- a/gtk/gtkgridview.c +++ b/gtk/gtkgridview.c @@ -257,13 +257,58 @@ gtk_grid_view_split (GtkListBase *base, return split; } +/* We define the listview as **inert** when the factory isn't used. */ +static gboolean +gtk_grid_view_is_inert (GtkGridView *self) +{ + GtkWidget *widget = GTK_WIDGET (self); + + return !gtk_widget_get_visible (widget) || + gtk_widget_get_root (widget) == NULL || + self->factory == NULL; +} + +static void +gtk_grid_view_update_factories_with (GtkGridView *self, + GtkListItemFactory *factory) +{ + GtkListTile *tile; + + for (tile = gtk_list_item_manager_get_first (self->item_manager); + tile != NULL; + tile = gtk_rb_tree_node_get_next (tile)) + { + if (tile->widget) + gtk_list_factory_widget_set_factory (GTK_LIST_FACTORY_WIDGET (tile->widget), factory); + } +} + +static void +gtk_grid_view_update_factories (GtkGridView *self) +{ + gtk_grid_view_update_factories_with (self, + gtk_grid_view_is_inert (self) ? NULL : self->factory); +} + +static void +gtk_grid_view_clear_factories (GtkGridView *self) +{ + gtk_grid_view_update_factories_with (self, NULL); +} + static GtkListItemBase * gtk_grid_view_create_list_widget (GtkListBase *base) { GtkGridView *self = GTK_GRID_VIEW (base); + GtkListItemFactory *factory; GtkWidget *result; - result = gtk_list_item_widget_new (self->factory, + if (gtk_grid_view_is_inert (self)) + factory = NULL; + else + factory = self->factory; + + result = gtk_list_item_widget_new (factory, "child", GTK_ACCESSIBLE_ROLE_GRID_CELL); @@ -856,6 +901,50 @@ gtk_grid_view_size_allocate (GtkWidget *widget, gtk_list_base_allocate (GTK_LIST_BASE (self)); } +static void +gtk_grid_view_root (GtkWidget *widget) +{ + GtkGridView *self = GTK_GRID_VIEW (widget); + + GTK_WIDGET_CLASS (gtk_grid_view_parent_class)->root (widget); + + if (!gtk_grid_view_is_inert (self)) + gtk_grid_view_update_factories (self); +} + +static void +gtk_grid_view_unroot (GtkWidget *widget) +{ + GtkGridView *self = GTK_GRID_VIEW (widget); + + if (!gtk_grid_view_is_inert (self)) + gtk_grid_view_clear_factories (self); + + GTK_WIDGET_CLASS (gtk_grid_view_parent_class)->unroot (widget); +} + +static void +gtk_grid_view_show (GtkWidget *widget) +{ + GtkGridView *self = GTK_GRID_VIEW (widget); + + GTK_WIDGET_CLASS (gtk_grid_view_parent_class)->show (widget); + + if (!gtk_grid_view_is_inert (self)) + gtk_grid_view_update_factories (self); +} + +static void +gtk_grid_view_hide (GtkWidget *widget) +{ + GtkGridView *self = GTK_GRID_VIEW (widget); + + if (!gtk_grid_view_is_inert (self)) + gtk_grid_view_clear_factories (self); + + GTK_WIDGET_CLASS (gtk_grid_view_parent_class)->hide (widget); +} + static void gtk_grid_view_dispose (GObject *object) { @@ -989,6 +1078,10 @@ gtk_grid_view_class_init (GtkGridViewClass *klass) widget_class->measure = gtk_grid_view_measure; widget_class->size_allocate = gtk_grid_view_size_allocate; + widget_class->root = gtk_grid_view_root; + widget_class->unroot = gtk_grid_view_unroot; + widget_class->show = gtk_grid_view_show; + widget_class->hide = gtk_grid_view_hide; gobject_class->dispose = gtk_grid_view_dispose; gobject_class->get_property = gtk_grid_view_get_property; @@ -1237,22 +1330,18 @@ void gtk_grid_view_set_factory (GtkGridView *self, GtkListItemFactory *factory) { - GtkListTile *tile; + gboolean was_inert; g_return_if_fail (GTK_IS_GRID_VIEW (self)); g_return_if_fail (factory == NULL || GTK_IS_LIST_ITEM_FACTORY (factory)); + was_inert = gtk_grid_view_is_inert (self); + if (!g_set_object (&self->factory, factory)) return; - for (tile = gtk_list_item_manager_get_first (self->item_manager); - tile != NULL; - tile = gtk_rb_tree_node_get_next (tile)) - { - if (tile->widget) - gtk_list_factory_widget_set_factory (GTK_LIST_FACTORY_WIDGET (tile->widget), factory); - } - + if (!was_inert || !gtk_grid_view_is_inert (self)) + gtk_grid_view_update_factories (self); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FACTORY]); } diff --git a/gtk/gtklistfactorywidget.c b/gtk/gtklistfactorywidget.c index 684cefa3e6..dbe64442ca 100644 --- a/gtk/gtklistfactorywidget.c +++ b/gtk/gtklistfactorywidget.c @@ -204,30 +204,6 @@ gtk_list_factory_widget_update (GtkListItemBase *base, } } -static void -gtk_list_factory_widget_root (GtkWidget *widget) -{ - GtkListFactoryWidget *self = GTK_LIST_FACTORY_WIDGET (widget); - GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self); - - GTK_WIDGET_CLASS (gtk_list_factory_widget_parent_class)->root (widget); - - if (priv->factory) - gtk_list_factory_widget_setup_factory (self); -} - -static void -gtk_list_factory_widget_unroot (GtkWidget *widget) -{ - GtkListFactoryWidget *self = GTK_LIST_FACTORY_WIDGET (widget); - GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self); - - GTK_WIDGET_CLASS (gtk_list_factory_widget_parent_class)->unroot (widget); - - if (priv->object) - gtk_list_factory_widget_teardown_factory (self); -} - static void gtk_list_factory_widget_set_property (GObject *object, guint property_id, @@ -260,15 +236,25 @@ gtk_list_factory_widget_set_property (GObject *object, } } +static void +gtk_list_factory_widget_clear_factory (GtkListFactoryWidget *self) +{ + GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self); + + if (priv->factory == NULL) + return; + + if (priv->object) + gtk_list_factory_widget_teardown_factory (self); + + g_clear_object (&priv->factory); +} static void gtk_list_factory_widget_dispose (GObject *object) { GtkListFactoryWidget *self = GTK_LIST_FACTORY_WIDGET (object); - GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self); - g_assert (priv->object == NULL); - - g_clear_object (&priv->factory); + gtk_list_factory_widget_clear_factory (self); G_OBJECT_CLASS (gtk_list_factory_widget_parent_class)->dispose (object); } @@ -319,9 +305,6 @@ gtk_list_factory_widget_class_init (GtkListFactoryWidgetClass *klass) base_class->update = gtk_list_factory_widget_update; - widget_class->root = gtk_list_factory_widget_root; - widget_class->unroot = gtk_list_factory_widget_unroot; - gobject_class->set_property = gtk_list_factory_widget_set_property; gobject_class->dispose = gtk_list_factory_widget_dispose; @@ -553,19 +536,13 @@ gtk_list_factory_widget_set_factory (GtkListFactoryWidget *self, if (priv->factory == factory) return; - if (priv->factory) - { - if (priv->object) - gtk_list_factory_widget_teardown_factory (self); - g_clear_object (&priv->factory); - } + gtk_list_factory_widget_clear_factory (self); if (factory) { priv->factory = g_object_ref (factory); - if (gtk_widget_get_root (GTK_WIDGET (self))) - gtk_list_factory_widget_setup_factory (self); + gtk_list_factory_widget_setup_factory (self); } g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FACTORY]); diff --git a/gtk/gtklistview.c b/gtk/gtklistview.c index c7977119a8..74ace1d2d7 100644 --- a/gtk/gtklistview.c +++ b/gtk/gtklistview.c @@ -215,13 +215,58 @@ gtk_list_view_split (GtkListBase *base, return new_tile; } +/* We define the listview as **inert** when the factory isn't used. */ +static gboolean +gtk_list_view_is_inert (GtkListView *self) +{ + GtkWidget *widget = GTK_WIDGET (self); + + return !gtk_widget_get_visible (widget) || + gtk_widget_get_root (widget) == NULL || + self->factory == NULL; +} + +static void +gtk_list_view_update_factories_with (GtkListView *self, + GtkListItemFactory *factory) +{ + GtkListTile *tile; + + for (tile = gtk_list_item_manager_get_first (self->item_manager); + tile != NULL; + tile = gtk_rb_tree_node_get_next (tile)) + { + if (tile->widget) + gtk_list_factory_widget_set_factory (GTK_LIST_FACTORY_WIDGET (tile->widget), factory); + } +} + +static void +gtk_list_view_update_factories (GtkListView *self) +{ + gtk_list_view_update_factories_with (self, + gtk_list_view_is_inert (self) ? NULL : self->factory); +} + +static void +gtk_list_view_clear_factories (GtkListView *self) +{ + gtk_list_view_update_factories_with (self, NULL); +} + static GtkListItemBase * gtk_list_view_create_list_widget (GtkListBase *base) { GtkListView *self = GTK_LIST_VIEW (base); + GtkListItemFactory *factory; GtkWidget *result; - result = gtk_list_item_widget_new (self->factory, + if (gtk_list_view_is_inert (self)) + factory = NULL; + else + factory = self->factory; + + result = gtk_list_item_widget_new (factory, "row", GTK_ACCESSIBLE_ROLE_LIST_ITEM); @@ -606,6 +651,50 @@ gtk_list_view_size_allocate (GtkWidget *widget, gtk_list_base_allocate (GTK_LIST_BASE (self)); } +static void +gtk_list_view_root (GtkWidget *widget) +{ + GtkListView *self = GTK_LIST_VIEW (widget); + + GTK_WIDGET_CLASS (gtk_list_view_parent_class)->root (widget); + + if (!gtk_list_view_is_inert (self)) + gtk_list_view_update_factories (self); +} + +static void +gtk_list_view_unroot (GtkWidget *widget) +{ + GtkListView *self = GTK_LIST_VIEW (widget); + + if (!gtk_list_view_is_inert (self)) + gtk_list_view_clear_factories (self); + + GTK_WIDGET_CLASS (gtk_list_view_parent_class)->unroot (widget); +} + +static void +gtk_list_view_show (GtkWidget *widget) +{ + GtkListView *self = GTK_LIST_VIEW (widget); + + GTK_WIDGET_CLASS (gtk_list_view_parent_class)->show (widget); + + if (!gtk_list_view_is_inert (self)) + gtk_list_view_update_factories (self); +} + +static void +gtk_list_view_hide (GtkWidget *widget) +{ + GtkListView *self = GTK_LIST_VIEW (widget); + + if (!gtk_list_view_is_inert (self)) + gtk_list_view_clear_factories (self); + + GTK_WIDGET_CLASS (gtk_list_view_parent_class)->hide (widget); +} + static void gtk_list_view_dispose (GObject *object) { @@ -731,6 +820,10 @@ gtk_list_view_class_init (GtkListViewClass *klass) widget_class->measure = gtk_list_view_measure; widget_class->size_allocate = gtk_list_view_size_allocate; + widget_class->root = gtk_list_view_root; + widget_class->unroot = gtk_list_view_unroot; + widget_class->show = gtk_list_view_show; + widget_class->hide = gtk_list_view_hide; gobject_class->dispose = gtk_list_view_dispose; gobject_class->get_property = gtk_list_view_get_property; @@ -961,21 +1054,18 @@ void gtk_list_view_set_factory (GtkListView *self, GtkListItemFactory *factory) { - GtkListTile *tile; + gboolean was_inert; g_return_if_fail (GTK_IS_LIST_VIEW (self)); g_return_if_fail (factory == NULL || GTK_IS_LIST_ITEM_FACTORY (factory)); + was_inert = gtk_list_view_is_inert (self); + if (!g_set_object (&self->factory, factory)) return; - for (tile = gtk_list_item_manager_get_first (self->item_manager); - tile != NULL; - tile = gtk_rb_tree_node_get_next (tile)) - { - if (tile->widget) - gtk_list_factory_widget_set_factory (GTK_LIST_FACTORY_WIDGET (tile->widget), factory); - } + if (!was_inert || !gtk_list_view_is_inert (self)) + gtk_list_view_update_factories (self); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FACTORY]); } diff --git a/gtk/gtkmagnifier.c b/gtk/gtkmagnifier.c index bca4db6b8a..e606ae23e8 100644 --- a/gtk/gtkmagnifier.c +++ b/gtk/gtkmagnifier.c @@ -270,8 +270,7 @@ _gtk_magnifier_set_coords (GtkMagnifier *magnifier, magnifier->x = x; magnifier->y = y; - if (gtk_widget_is_visible (GTK_WIDGET (magnifier))) - gtk_widget_queue_draw (GTK_WIDGET (magnifier)); + gtk_widget_queue_draw (GTK_WIDGET (magnifier)); } void @@ -303,8 +302,7 @@ _gtk_magnifier_set_magnification (GtkMagnifier *magnifier, if (magnifier->resize) gtk_widget_queue_resize (GTK_WIDGET (magnifier)); - if (gtk_widget_is_visible (GTK_WIDGET (magnifier))) - gtk_widget_queue_draw (GTK_WIDGET (magnifier)); + gtk_widget_queue_draw (GTK_WIDGET (magnifier)); } double