summaryrefslogtreecommitdiff
path: root/gtk/gtklistitemwidget.c
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2019-11-03 03:34:56 +0100
committerMatthias Clasen <mclasen@redhat.com>2020-05-30 19:26:46 -0400
commit9d86020d4c0846dd55216d770ecff9d91f04b48d (patch)
tree3dbbd1e64309f08edbf98e3974102e2aa8b18619 /gtk/gtklistitemwidget.c
parent32eedec565937cbc42115680c86fc260f2755452 (diff)
downloadgtk+-9d86020d4c0846dd55216d770ecff9d91f04b48d.tar.gz
listitem: Move position/item/selected tracking to widget
This way, we can ensure it's always there when we need it (before the item gets created) and gone when we don't (if some GC language holds on to the item after we've destroyed the widget).
Diffstat (limited to 'gtk/gtklistitemwidget.c')
-rw-r--r--gtk/gtklistitemwidget.c67
1 files changed, 51 insertions, 16 deletions
diff --git a/gtk/gtklistitemwidget.c b/gtk/gtklistitemwidget.c
index 01cd0d28cd..1bda22fd1d 100644
--- a/gtk/gtklistitemwidget.c
+++ b/gtk/gtklistitemwidget.c
@@ -29,6 +29,7 @@
#include "gtklistitemfactoryprivate.h"
#include "gtklistitemprivate.h"
#include "gtkmain.h"
+#include "gtkselectionmodel.h"
#include "gtkwidget.h"
#include "gtkwidgetprivate.h"
@@ -37,6 +38,10 @@ struct _GtkListItemWidgetPrivate
{
GtkListItemFactory *factory;
GtkListItem *list_item;
+
+ GObject *item;
+ guint position;
+ gboolean selected;
};
enum
@@ -54,13 +59,13 @@ gtk_list_item_widget_activate_signal (GtkListItemWidget *self)
{
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
- if (!priv->list_item->activatable)
+ if (priv->list_item && !priv->list_item->activatable)
return;
gtk_widget_activate_action (GTK_WIDGET (self),
"list.activate-item",
"u",
- priv->list_item->position);
+ priv->position);
}
static gboolean
@@ -121,6 +126,7 @@ gtk_list_item_widget_dispose (GObject *object)
gtk_list_item_factory_teardown (priv->factory, self);
g_assert (priv->list_item == NULL);
}
+ g_clear_object (&priv->item);
g_clear_object (&priv->factory);
G_OBJECT_CLASS (gtk_list_item_widget_parent_class)->dispose (object);
@@ -135,7 +141,7 @@ gtk_list_item_widget_select_action (GtkWidget *widget,
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
gboolean modify, extend;
- if (!priv->list_item->selectable)
+ if (priv->list_item && !priv->list_item->selectable)
return;
g_variant_get (parameter, "(bb)", &modify, &extend);
@@ -143,7 +149,7 @@ gtk_list_item_widget_select_action (GtkWidget *widget,
gtk_widget_activate_action (GTK_WIDGET (self),
"list.select-item",
"(ubb)",
- priv->list_item->position, modify, extend);
+ priv->position, modify, extend);
}
static void
@@ -229,13 +235,13 @@ gtk_list_item_widget_click_gesture_pressed (GtkGestureClick *gesture,
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
GtkWidget *widget = GTK_WIDGET (self);
- if (!priv->list_item->selectable && !priv->list_item->activatable)
+ if (priv->list_item && !priv->list_item->selectable && !priv->list_item->activatable)
{
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
return;
}
- if (priv->list_item->selectable)
+ if (!priv->list_item || priv->list_item->selectable)
{
GdkModifierType state;
GdkEvent *event;
@@ -250,17 +256,17 @@ gtk_list_item_widget_click_gesture_pressed (GtkGestureClick *gesture,
gtk_widget_activate_action (GTK_WIDGET (self),
"list.select-item",
"(ubb)",
- priv->list_item->position, modify, extend);
+ priv->position, modify, extend);
}
- if (priv->list_item->activatable)
+ if (!priv->list_item || priv->list_item->activatable)
{
if (n_press == 2)
{
gtk_widget_activate_action (GTK_WIDGET (self),
"list.activate-item",
"u",
- priv->list_item->position);
+ priv->position);
}
}
@@ -280,7 +286,7 @@ gtk_list_item_widget_enter_cb (GtkEventControllerFocus *controller,
gtk_widget_activate_action (widget,
"list.scroll-to-item",
"u",
- priv->list_item->position);
+ priv->position);
}
static void
@@ -381,6 +387,13 @@ gtk_list_item_widget_default_setup (GtkListItemWidget *self,
if (list_item->child)
gtk_list_item_widget_add_child (self, list_item->child);
+
+ if (priv->item)
+ g_object_notify (G_OBJECT (list_item), "item");
+ if (priv->position != GTK_INVALID_LIST_POSITION)
+ g_object_notify (G_OBJECT (list_item), "position");
+ if (priv->selected)
+ g_object_notify (G_OBJECT (list_item), "selected");
}
void
@@ -396,6 +409,13 @@ gtk_list_item_widget_default_teardown (GtkListItemWidget *self,
if (list_item->child)
gtk_list_item_widget_remove_child (self, list_item->child);
+
+ if (priv->item)
+ g_object_notify (G_OBJECT (list_item), "item");
+ if (priv->position != GTK_INVALID_LIST_POSITION)
+ g_object_notify (G_OBJECT (list_item), "position");
+ if (priv->selected)
+ g_object_notify (G_OBJECT (list_item), "selected");
}
void
@@ -405,9 +425,24 @@ gtk_list_item_widget_default_update (GtkListItemWidget *self,
gpointer item,
gboolean selected)
{
- gtk_list_item_set_item (list_item, item);
- gtk_list_item_set_position (list_item, position);
- gtk_list_item_set_selected (list_item, selected);
+ GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
+
+ /* FIXME: It's kinda evil to notify external objects from here... */
+
+ if (g_set_object (&priv->item, item))
+ g_object_notify (G_OBJECT (list_item), "item");
+
+ if (priv->position != position)
+ {
+ priv->position = position;
+ g_object_notify (G_OBJECT (list_item), "position");
+ }
+
+ if (priv->selected != selected)
+ {
+ priv->selected = selected;
+ g_object_notify (G_OBJECT (list_item), "selected");
+ }
}
void
@@ -437,7 +472,7 @@ gtk_list_item_widget_get_position (GtkListItemWidget *self)
{
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
- return priv->list_item->position;
+ return priv->position;
}
gpointer
@@ -445,7 +480,7 @@ gtk_list_item_widget_get_item (GtkListItemWidget *self)
{
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
- return priv->list_item->item;
+ return priv->item;
}
gboolean
@@ -453,6 +488,6 @@ gtk_list_item_widget_get_selected (GtkListItemWidget *self)
{
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
- return priv->list_item->selected;
+ return priv->selected;
}