summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2018-03-08 23:14:06 +0100
committerCarlos Garnacho <carlosg@gnome.org>2018-04-26 17:59:41 +0200
commit9af03fa602b8b0cd72572c64e2e8ed3e63ede03f (patch)
treeec4a8e60311363c3314df11297b2368162fe676e
parent8ddba5ffcd13c34d4b617060c8ac0bbbdea44fc8 (diff)
downloadgtk+-9af03fa602b8b0cd72572c64e2e8ed3e63ede03f.tar.gz
widget: Expose gtk_widget_add_controller()
.. and gtk_widget_remove_controller().
-rw-r--r--docs/reference/gtk/gtk4-sections.txt2
-rw-r--r--gtk/gtkeventcontroller.c7
-rw-r--r--gtk/gtkwidget.c93
-rw-r--r--gtk/gtkwidget.h6
-rw-r--r--gtk/gtkwidgetprivate.h5
5 files changed, 70 insertions, 43 deletions
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index 90d886cbc6..83313d7c9f 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -4273,6 +4273,8 @@ gtk_widget_get_toplevel
gtk_widget_get_ancestor
gtk_widget_is_ancestor
gtk_widget_translate_coordinates
+gtk_widget_add_controller
+gtk_widget_remove_controller
gtk_widget_set_direction
GtkTextDirection
gtk_widget_get_direction
diff --git a/gtk/gtkeventcontroller.c b/gtk/gtkeventcontroller.c
index 31301b6106..d00f09ce36 100644
--- a/gtk/gtkeventcontroller.c
+++ b/gtk/gtkeventcontroller.c
@@ -87,7 +87,6 @@ gtk_event_controller_set_property (GObject *object,
GParamSpec *pspec)
{
GtkEventController *self = GTK_EVENT_CONTROLLER (object);
- GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self);
GtkWidget *widget;
switch (prop_id)
@@ -96,8 +95,7 @@ gtk_event_controller_set_property (GObject *object,
widget = g_value_get_object (value);
if (widget)
{
- _gtk_widget_add_controller (widget, self);
- g_object_add_weak_pointer (G_OBJECT (widget), (gpointer *) &priv->widget);
+ _gtk_widget_add_controller (widget, self, FALSE);
}
break;
case PROP_PROPAGATION_PHASE:
@@ -140,8 +138,7 @@ gtk_event_controller_dispose (GObject *object)
priv = gtk_event_controller_get_instance_private (controller);
if (priv->widget)
{
- g_object_remove_weak_pointer (G_OBJECT (priv->widget), (gpointer *) &priv->widget);
- _gtk_widget_remove_controller (priv->widget, controller);
+ gtk_widget_remove_controller (priv->widget, controller);
}
G_OBJECT_CLASS (gtk_event_controller_parent_class)->dispose (object);
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 09cabb6bac..b4361c65f7 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -459,6 +459,7 @@ typedef struct {
GtkEventController *controller;
guint grab_notify_id;
guint sequence_state_changed_id;
+ gboolean have_ref;
} EventControllerData;
struct _GtkWidgetClassPrivate
@@ -8583,7 +8584,9 @@ gtk_widget_finalize (GObject *object)
{
EventControllerData *data = l->data;
if (data->controller)
- _gtk_widget_remove_controller (widget, data->controller);
+ {
+ gtk_widget_remove_controller (widget, data->controller);
+ }
}
g_list_free_full (priv->event_controllers, g_free);
priv->event_controllers = NULL;
@@ -12866,44 +12869,20 @@ event_controller_sequence_state_changed (GtkGesture *gesture,
cancel_event_sequence_on_hierarchy (widget, event_widget, sequence);
}
-static EventControllerData *
-_gtk_widget_has_controller (GtkWidget *widget,
- GtkEventController *controller)
-{
- GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
- EventControllerData *data;
- GList *l;
-
- for (l = priv->event_controllers; l; l = l->next)
- {
- data = l->data;
-
- if (data->controller == controller)
- return data;
- }
-
- return NULL;
-}
-
void
_gtk_widget_add_controller (GtkWidget *widget,
- GtkEventController *controller)
+ GtkEventController *controller,
+ gboolean have_ref)
{
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
EventControllerData *data;
- g_return_if_fail (GTK_IS_WIDGET (widget));
- g_return_if_fail (GTK_IS_EVENT_CONTROLLER (controller));
- g_return_if_fail (gtk_event_controller_get_widget (controller) == NULL);
-
- data = _gtk_widget_has_controller (widget, controller);
-
- if (data)
- return;
+ priv = widget->priv;
GTK_EVENT_CONTROLLER_GET_CLASS (controller)->set_widget (controller, widget);
data = g_new0 (EventControllerData, 1);
+ data->have_ref = have_ref;
data->controller = controller;
data->grab_notify_id =
g_signal_connect (widget, "grab-notify",
@@ -12922,19 +12901,61 @@ _gtk_widget_add_controller (GtkWidget *widget,
priv->event_controllers = g_list_prepend (priv->event_controllers, data);
}
+/**
+ * gtk_widget_add_controller:
+ * @widget: a #GtkWidget
+ * @controller: (transfer full): a #GtkEventController that hasn't been
+ * added to a widget yet
+ *
+ * Adds @controller to @widget so that it will receive events. You will
+ * usually want to call this function right after creating any kind of
+ * #GtkEventController.
+ **/
void
-_gtk_widget_remove_controller (GtkWidget *widget,
- GtkEventController *controller)
+gtk_widget_add_controller (GtkWidget *widget,
+ GtkEventController *controller)
{
- EventControllerData *data;
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (GTK_IS_EVENT_CONTROLLER (controller));
+ g_return_if_fail (gtk_event_controller_get_widget (controller) == NULL);
+
+ _gtk_widget_add_controller (widget, controller, TRUE);
+}
+
+/**
+ * gtk_widget_remove_controller:
+ * @widget: a #GtkWidget
+ * @controller: (transfer none): a #GtkEventController
+ *
+ * Removes @controller from @widget, so that it doesn't process
+ * events anymore. It should not be used again.
+ *
+ * Widgets will remove all event controllers automatically when they
+ * are destroyed, there is normally no need to call this function.
+ **/
+void
+gtk_widget_remove_controller (GtkWidget *widget,
+ GtkEventController *controller)
+{
+ EventControllerData *data = NULL;
+ GtkWidgetPrivate *priv;
+ GList *l;
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (GTK_IS_EVENT_CONTROLLER (controller));
+ g_return_if_fail (gtk_event_controller_get_widget (controller) == widget);
- data = _gtk_widget_has_controller (widget, controller);
+ priv = widget->priv;
- if (!data)
- return;
+ for (l = priv->event_controllers; l; l = l->next)
+ {
+ data = l->data;
+
+ if (data->controller == controller)
+ break;
+ }
+
+ g_assert (data);
GTK_EVENT_CONTROLLER_GET_CLASS (controller)->unset_widget (controller);
@@ -12947,6 +12968,8 @@ _gtk_widget_remove_controller (GtkWidget *widget,
g_signal_handler_disconnect (data->controller, data->sequence_state_changed_id);
data->controller = NULL;
+ if (data->have_ref)
+ g_object_unref (controller);
}
GList *
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index dc2770327c..172ef44530 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -770,6 +770,12 @@ GtkWidget * gtk_widget_pick (GtkWidget *widget,
gdouble y);
GDK_AVAILABLE_IN_ALL
+void gtk_widget_add_controller (GtkWidget *widget,
+ GtkEventController *controller);
+GDK_AVAILABLE_IN_ALL
+void gtk_widget_remove_controller (GtkWidget *widget,
+ GtkEventController *controller);
+GDK_AVAILABLE_IN_ALL
void gtk_widget_reset_style (GtkWidget *widget);
GDK_AVAILABLE_IN_ALL
diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h
index f53b7659dc..2a3df8177b 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -259,9 +259,8 @@ GtkActionMuxer * _gtk_widget_get_action_muxer (GtkWidget *widget
gboolean create);
void _gtk_widget_add_controller (GtkWidget *widget,
- GtkEventController *controller);
-void _gtk_widget_remove_controller (GtkWidget *widget,
- GtkEventController *controller);
+ GtkEventController *controller,
+ gboolean take_ref);
GList * _gtk_widget_list_controllers (GtkWidget *widget,
GtkPropagationPhase phase);
gboolean _gtk_widget_consumes_motion (GtkWidget *widget,