[gtk/wip/matthiasc/popup4: 121/140] Introduce event controller propagation limits
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/matthiasc/popup4: 121/140] Introduce event controller propagation limits
- Date: Mon, 29 Apr 2019 02:51:52 +0000 (UTC)
commit 06aefb8237d5254cc70567b9e4a798982c08de97
Author: Matthias Clasen <mclasen redhat com>
Date: Mon Apr 29 02:19:44 2019 +0000
Introduce event controller propagation limits
Limit event handlers by default to only handle
events targeting the same surface as their widget.
docs/reference/gtk/gtk4-sections.txt | 3 ++
gtk/gtkenums.h | 17 +++++++
gtk/gtkeventcontroller.c | 93 +++++++++++++++++++++++++++++++++++-
gtk/gtkeventcontroller.h | 6 +++
gtk/gtkgesture.c | 3 ++
5 files changed, 121 insertions(+), 1 deletion(-)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index df2e305f71..68dff2c47d 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -6516,6 +6516,9 @@ GtkEventController
GtkPropagationPhase
gtk_event_controller_get_propagation_phase
gtk_event_controller_set_propagation_phase
+GtkPropagationLimit
+gtk_event_controller_get_propagation_limit
+gtk_event_controller_set_propagation_limit
gtk_event_controller_handle_event
gtk_event_controller_get_widget
gtk_event_controller_reset
diff --git a/gtk/gtkenums.h b/gtk/gtkenums.h
index d18f3f995d..3de47a5565 100644
--- a/gtk/gtkenums.h
+++ b/gtk/gtkenums.h
@@ -967,6 +967,23 @@ typedef enum
GTK_PHASE_TARGET
} GtkPropagationPhase;
+/**
+ * GtkPropagationLimit:
+ * @GTK_LIMIT_NONE: Events are handled regardless of what their
+ * target is.
+ * @GTK_LIMIT_SAME_BUD: Events are only handled if their target
+ * is on the same #GtkBud as the event controllers widget. Note
+ * that some event types have two targets (origin and destination).
+ *
+ * Describes limits of a #GtkEventController for handling events
+ * targeting other widgets.
+ */
+typedef enum
+{
+ GTK_LIMIT_NONE,
+ GTK_LIMIT_SAME_BUD
+} GtkPropagationLimit;
+
/**
* GtkEventSequenceState:
* @GTK_EVENT_SEQUENCE_NONE: The sequence is handled, but not grabbed.
diff --git a/gtk/gtkeventcontroller.c b/gtk/gtkeventcontroller.c
index aed43c3d5e..333fa1aa33 100644
--- a/gtk/gtkeventcontroller.c
+++ b/gtk/gtkeventcontroller.c
@@ -32,17 +32,20 @@
#include "config.h"
#include "gtkeventcontroller.h"
#include "gtkeventcontrollerprivate.h"
+
#include "gtkwidgetprivate.h"
#include "gtktypebuiltins.h"
#include "gtkmarshalers.h"
#include "gtkprivate.h"
#include "gtkintl.h"
+#include "gtkbud.h"
typedef struct _GtkEventControllerPrivate GtkEventControllerPrivate;
enum {
PROP_WIDGET = 1,
PROP_PROPAGATION_PHASE,
+ PROP_PROPAGATION_LIMIT,
LAST_PROP
};
@@ -52,6 +55,7 @@ struct _GtkEventControllerPrivate
{
GtkWidget *widget;
GtkPropagationPhase phase;
+ GtkPropagationLimit limit;
};
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GtkEventController, gtk_event_controller, G_TYPE_OBJECT)
@@ -73,6 +77,42 @@ gtk_event_controller_unset_widget (GtkEventController *self)
priv->widget = NULL;
}
+static gboolean
+gtk_event_controller_filter_event_default (GtkEventController *self,
+ const GdkEvent *event)
+{
+ GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self);
+
+ if (priv->limit == GTK_LIMIT_SAME_BUD)
+ {
+ GtkWidget *bud;
+ GtkWidget *bud2;
+ GtkWidget *target;
+
+ bud = gtk_widget_get_ancestor (priv->widget, GTK_TYPE_BUD);
+
+ target = GTK_WIDGET (gdk_event_get_target (event));
+ if (target)
+ {
+ bud2 = gtk_widget_get_ancestor (target, GTK_TYPE_BUD);
+ if (bud == bud2)
+ return FALSE;
+ }
+
+ target = GTK_WIDGET (gdk_event_get_related_target (event));
+ if (target)
+ {
+ bud2 = gtk_widget_get_ancestor (target, GTK_TYPE_BUD);
+ if (bud == bud2)
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static gboolean
gtk_event_controller_handle_event_default (GtkEventController *self,
const GdkEvent *event)
@@ -94,6 +134,10 @@ gtk_event_controller_set_property (GObject *object,
gtk_event_controller_set_propagation_phase (self,
g_value_get_enum (value));
break;
+ case PROP_PROPAGATION_LIMIT:
+ gtk_event_controller_set_propagation_limit (self,
+ g_value_get_enum (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -116,6 +160,9 @@ gtk_event_controller_get_property (GObject *object,
case PROP_PROPAGATION_PHASE:
g_value_set_enum (value, priv->phase);
break;
+ case PROP_PROPAGATION_LIMIT:
+ g_value_set_enum (value, priv->limit);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -128,7 +175,7 @@ gtk_event_controller_class_init (GtkEventControllerClass *klass)
klass->set_widget = gtk_event_controller_set_widget;
klass->unset_widget = gtk_event_controller_unset_widget;
- klass->filter_event = gtk_event_controller_handle_event_default;
+ klass->filter_event = gtk_event_controller_filter_event_default;
klass->handle_event = gtk_event_controller_handle_event_default;
object_class->set_property = gtk_event_controller_set_property;
@@ -145,6 +192,7 @@ gtk_event_controller_class_init (GtkEventControllerClass *klass)
P_("Widget the gesture relates to"),
GTK_TYPE_WIDGET,
GTK_PARAM_READABLE);
+
/**
* GtkEventController:propagation-phase:
*
@@ -158,6 +206,19 @@ gtk_event_controller_class_init (GtkEventControllerClass *klass)
GTK_PHASE_BUBBLE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+ /**
+ * GtkEventController:propagation-limit:
+ *
+ * The limit for which events this controller will handle.
+ */
+ properties[PROP_PROPAGATION_LIMIT] =
+ g_param_spec_enum ("propagation-limit",
+ P_("Propagation limit"),
+ P_("Propagation limit for events handled by this controller"),
+ GTK_TYPE_PROPAGATION_LIMIT,
+ GTK_LIMIT_SAME_BUD,
+ GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+
g_object_class_install_properties (object_class, LAST_PROP, properties);
}
@@ -168,6 +229,7 @@ gtk_event_controller_init (GtkEventController *controller)
priv = gtk_event_controller_get_instance_private (controller);
priv->phase = GTK_PHASE_BUBBLE;
+ priv->limit = GTK_LIMIT_SAME_BUD;
}
/**
@@ -299,3 +361,32 @@ gtk_event_controller_set_propagation_phase (GtkEventController *controller,
g_object_notify_by_pspec (G_OBJECT (controller), properties[PROP_PROPAGATION_PHASE]);
}
+
+GtkPropagationLimit
+gtk_event_controller_get_propagation_limit (GtkEventController *controller)
+{
+ GtkEventControllerPrivate *priv;
+
+ g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER (controller), GTK_LIMIT_SAME_BUD);
+
+ priv = gtk_event_controller_get_instance_private (controller);
+
+ return priv->limit;
+}
+void
+gtk_event_controller_set_propagation_limit (GtkEventController *controller,
+ GtkPropagationLimit limit)
+{
+ GtkEventControllerPrivate *priv;
+
+ g_return_if_fail (GTK_IS_EVENT_CONTROLLER (controller));
+
+ priv = gtk_event_controller_get_instance_private (controller);
+
+ if (priv->limit == limit)
+ return;
+
+ priv->limit = limit;
+
+ g_object_notify_by_pspec (G_OBJECT (controller), properties[PROP_PROPAGATION_LIMIT]);
+}
diff --git a/gtk/gtkeventcontroller.h b/gtk/gtkeventcontroller.h
index f2f2b6a2b0..963f440e6a 100644
--- a/gtk/gtkeventcontroller.h
+++ b/gtk/gtkeventcontroller.h
@@ -59,6 +59,12 @@ GDK_AVAILABLE_IN_ALL
void gtk_event_controller_set_propagation_phase (GtkEventController *controller,
GtkPropagationPhase phase);
+GDK_AVAILABLE_IN_ALL
+GtkPropagationLimit gtk_event_controller_get_propagation_limit (GtkEventController *controller);
+
+GDK_AVAILABLE_IN_ALL
+void gtk_event_controller_set_propagation_limit (GtkEventController *controller,
+ GtkPropagationLimit limit);
G_END_DECLS
#endif /* __GTK_EVENT_CONTROLLER_H__ */
diff --git a/gtk/gtkgesture.c b/gtk/gtkgesture.c
index 2125af2bf1..f875242a45 100644
--- a/gtk/gtkgesture.c
+++ b/gtk/gtkgesture.c
@@ -617,6 +617,9 @@ gtk_gesture_filter_event (GtkEventController *controller,
* subclasses which punch the holes in for the events
* they can possibly handle.
*/
+ if (GTK_EVENT_CONTROLLER_CLASS (gtk_gesture_parent_class)->filter_event (controller, event))
+ return TRUE;
+
return EVENT_IS_TOUCHPAD_GESTURE (event);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]