[gtk/wip/otte/listmodel: 5/10] widget: Add gtk_widget_observe_controllers()
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/listmodel: 5/10] widget: Add gtk_widget_observe_controllers()
- Date: Wed, 12 Sep 2018 11:54:28 +0000 (UTC)
commit 9bf27f6c7e6b976707b781096d945cde5394e810
Author: Benjamin Otte <otte redhat com>
Date: Wed Sep 5 03:00:18 2018 +0200
widget: Add gtk_widget_observe_controllers()
This mirrors gtk_widget_observe_children() - just that it observes the
controllers, not the children.
docs/reference/gtk/gtk4-sections.txt | 1 +
gtk/gtkwidget.c | 92 ++++++++++++++++++++++++++++++++++--
gtk/gtkwidget.h | 2 +
3 files changed, 91 insertions(+), 4 deletions(-)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index 5fa44b0201..f27d1be57e 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -4626,6 +4626,7 @@ gtk_window_set_interactive_debugging
<SUBSECTION>
gtk_widget_observe_children
+gtk_widget_observe_controllers
<SUBSECTION Standard>
GTK_WINDOW
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index c684d51b33..5b174a7a62 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -8275,6 +8275,11 @@ gtk_widget_dispose (GObject *object)
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
GSList *sizegroups;
+ if (priv->children_observer)
+ gtk_list_list_model_clear (priv->children_observer);
+ if (priv->controller_observer)
+ gtk_list_list_model_clear (priv->controller_observer);
+
if (priv->parent && GTK_IS_CONTAINER (priv->parent))
gtk_container_remove (GTK_CONTAINER (priv->parent), widget);
else if (priv->parent)
@@ -8285,9 +8290,6 @@ gtk_widget_dispose (GObject *object)
while (priv->paintables)
gtk_widget_paintable_set_widget (priv->paintables->data, NULL);
- if (priv->children_observer)
- gtk_list_list_model_clear (priv->children_observer);
-
priv->visible = FALSE;
if (_gtk_widget_get_realized (widget))
gtk_widget_unrealize (widget);
@@ -12920,6 +12922,9 @@ gtk_widget_add_controller (GtkWidget *widget,
GTK_EVENT_CONTROLLER_GET_CLASS (controller)->set_widget (controller, widget);
priv->event_controllers = g_list_prepend (priv->event_controllers, controller);
+
+ if (priv->controller_observer)
+ gtk_list_list_model_item_added_at (priv->controller_observer, 0);
}
/**
@@ -12938,6 +12943,7 @@ gtk_widget_remove_controller (GtkWidget *widget,
GtkEventController *controller)
{
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
+ GList *before, *list;
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (GTK_IS_EVENT_CONTROLLER (controller));
@@ -12945,8 +12951,13 @@ gtk_widget_remove_controller (GtkWidget *widget,
GTK_EVENT_CONTROLLER_GET_CLASS (controller)->unset_widget (controller);
- priv->event_controllers = g_list_remove (priv->event_controllers, controller);
+ list = g_list_find (priv->event_controllers, controller);
+ before = list->prev;
+ priv->event_controllers = g_list_delete_link (priv->event_controllers, list);
g_object_unref (controller);
+
+ if (priv->controller_observer)
+ gtk_list_list_model_item_removed (priv->controller_observer, before);
}
GList *
@@ -13225,6 +13236,7 @@ gtk_widget_child_observer_destroyed (gpointer widget)
priv->children_observer = NULL;
}
+
/**
* gtk_widget_observe_children:
* @widget: a #GtkWidget
@@ -13262,6 +13274,78 @@ gtk_widget_observe_children (GtkWidget *widget)
return G_LIST_MODEL (priv->children_observer);
}
+static void
+gtk_widget_controller_observer_destroyed (gpointer widget)
+{
+ GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
+
+ priv->controller_observer = NULL;
+}
+
+static gpointer
+gtk_widget_controller_list_get_first (gpointer widget)
+{
+ return GTK_WIDGET (widget)->priv->event_controllers;
+}
+
+static gpointer
+gtk_widget_controller_list_get_next (gpointer item,
+ gpointer widget)
+{
+ return g_list_next (item);
+}
+
+static gpointer
+gtk_widget_controller_list_get_prev (gpointer item,
+ gpointer widget)
+{
+ return g_list_previous (item);
+}
+
+static gpointer
+gtk_widget_controller_list_get_item (gpointer item,
+ gpointer widget)
+{
+ return g_object_ref (((GList *) item)->data);
+}
+
+/**
+ * gtk_widget_observe_controllers:
+ * @widget: a #GtkWidget
+ *
+ * Returns a #GListModel to track the #GtkEventControllers of @widget.
+ *
+ * Calling this function will enable extra internal bookkeeping to track
+ * controllers and emit signals on the returned listmodel. It may slow down
+ * operations a lot.
+ *
+ * Applications should try hard to avoid calling this function because of
+ * the slowdowns.
+ *
+ * Returns: (transfer full): a #GListModel tracking @widget's controllers
+ **/
+GListModel *
+gtk_widget_observe_controllers (GtkWidget *widget)
+{
+ GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
+
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+
+ if (priv->controller_observer)
+ return g_object_ref (G_LIST_MODEL (priv->controller_observer));
+
+ priv->controller_observer = gtk_list_list_model_new (GTK_TYPE_EVENT_CONTROLLER,
+ gtk_widget_controller_list_get_first,
+ gtk_widget_controller_list_get_next,
+ gtk_widget_controller_list_get_prev,
+ NULL,
+ gtk_widget_controller_list_get_item,
+ widget,
+ gtk_widget_controller_observer_destroyed);
+
+ return G_LIST_MODEL (priv->controller_observer);
+}
+
/**
* gtk_widget_get_first_child:
* @widget: a #GtkWidget
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index e00f832bcb..b92ba1229d 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -1033,6 +1033,8 @@ GtkWidget * gtk_widget_get_prev_sibling (GtkWidget *widget);
GDK_AVAILABLE_IN_ALL
GListModel * gtk_widget_observe_children (GtkWidget *widget);
GDK_AVAILABLE_IN_ALL
+GListModel * gtk_widget_observe_controllers (GtkWidget *widget);
+GDK_AVAILABLE_IN_ALL
void gtk_widget_insert_after (GtkWidget *widget,
GtkWidget *parent,
GtkWidget *previous_sibling);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]