From c36685bf60f72b264f574a936255a9b5bd0966b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20=22sp1rit=22=E2=80=8B?= Date: Sun, 8 May 2022 15:53:41 +0200 Subject: [PATCH 1/4] gdk: gdkevents: added NULL check to `gdk_event_get_axes` this is to prevent gdk from causing a segfault, when getting event axes for events that don't have them (i.e. attempting to get pressure from a mice input device). --- gdk/gdkevents.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c index e63c54fcb4..6bb9c91a74 100644 --- a/gdk/gdkevents.c +++ b/gdk/gdkevents.c @@ -1174,9 +1174,16 @@ gdk_event_get_axes (GdkEvent *event, double **axes, guint *n_axes) { + gboolean ret; + g_return_val_if_fail (GDK_IS_EVENT (event), FALSE); - return GDK_EVENT_GET_CLASS (event)->get_axes (event, axes, n_axes); + ret = GDK_EVENT_GET_CLASS (event)->get_axes (event, axes, n_axes); + + if (*axes == NULL) + return FALSE; + + return ret; } double * From 789778105d4bb4eb16b10291dffeac543090672a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20=22sp1rit=22=E2=80=8B?= Date: Sun, 8 May 2022 16:31:43 +0200 Subject: [PATCH 2/4] gtk: gtkgesturestylus: implemented `stylus-only` property this allows setting a Gtk.GestureStylus to a state, where it can be used to handle non-stylus devices (e.g. mice). This might be useful for applications that handle stylus input, but want to allow falling back to a mice, if the user is unable to provide stylus input. --- gtk/gtkgesturestylus.c | 115 ++++++++++++++++++++++++++++++++++++++++- gtk/gtkgesturestylus.h | 6 +++ 2 files changed, 119 insertions(+), 2 deletions(-) diff --git a/gtk/gtkgesturestylus.c b/gtk/gtkgesturestylus.c index d10dfe1a05..8e187c2545 100644 --- a/gtk/gtkgesturestylus.c +++ b/gtk/gtkgesturestylus.c @@ -34,7 +34,16 @@ #include "gtkmain.h" #include "gtknative.h" -G_DEFINE_TYPE (GtkGestureStylus, gtk_gesture_stylus, GTK_TYPE_GESTURE_SINGLE) +typedef struct { + gboolean stylus_only; +} GtkGestureStylusPrivate; + +G_DEFINE_TYPE_WITH_PRIVATE (GtkGestureStylus, gtk_gesture_stylus, GTK_TYPE_GESTURE_SINGLE) + +enum { + PROP_STYLUS_ONLY = 1, + N_PROPERTIES +}; enum { PROXIMITY, @@ -44,20 +53,55 @@ enum { N_SIGNALS }; +static GParamSpec* obj_properties[N_PROPERTIES] = { NULL, }; static guint signals[N_SIGNALS] = { 0, }; +static void gtk_gesture_stylus_get_property (GObject* object, + guint prop_id, + GValue* value, + GParamSpec* pspec) +{ + GtkGestureStylus* gesture = GTK_GESTURE_STYLUS(object); + + switch (prop_id) { + case PROP_STYLUS_ONLY: + g_value_set_boolean(value, gtk_gesture_stylus_get_stylus_only(gesture)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void gtk_gesture_stylus_set_property (GObject* object, + guint prop_id, + const GValue* value, + GParamSpec* pspec) +{ + GtkGestureStylus* gesture = GTK_GESTURE_STYLUS(object); + + switch (prop_id) { + case PROP_STYLUS_ONLY: + gtk_gesture_stylus_set_stylus_only(gesture, g_value_get_boolean(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + static gboolean gtk_gesture_stylus_handle_event (GtkEventController *controller, GdkEvent *event, double x, double y) { + GtkGestureStylusPrivate* priv; GdkModifierType modifiers; guint n_signal; + priv = gtk_gesture_stylus_get_instance_private(GTK_GESTURE_STYLUS(controller)); GTK_EVENT_CONTROLLER_CLASS (gtk_gesture_stylus_parent_class)->handle_event (controller, event, x, y); - if (!gdk_event_get_device_tool (event)) + if (!(priv->stylus_only || gdk_event_get_device_tool (event))) return FALSE; switch ((guint) gdk_event_get_event_type (event)) @@ -88,8 +132,25 @@ gtk_gesture_stylus_handle_event (GtkEventController *controller, static void gtk_gesture_stylus_class_init (GtkGestureStylusClass *klass) { + GObjectClass* object_class; GtkEventControllerClass *event_controller_class; + object_class = G_OBJECT_CLASS (klass); + object_class->get_property = gtk_gesture_stylus_get_property; + object_class->set_property = gtk_gesture_stylus_set_property; + + /** + * GtkGestureStylus:stylus-only: (attributes org.gtk.Property.get=gtk_gesture_stylus_get_stylus_only org.gtk.Property.set=gtk_gesture_stylus_set_stylus_only) + * + * If this gesture should exclusively react to stylus input devices. + */ + obj_properties[PROP_STYLUS_ONLY] = g_param_spec_boolean("stylus-only", + P_("Stylus only"), + P_("Should this gesture exclusively react to stylus input devices."), + TRUE, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_CONSTRUCT); + g_object_class_install_properties(object_class, N_PROPERTIES, obj_properties); + event_controller_class = GTK_EVENT_CONTROLLER_CLASS (klass); event_controller_class->handle_event = gtk_gesture_stylus_handle_event; @@ -177,6 +238,9 @@ gtk_gesture_stylus_class_init (GtkGestureStylusClass *klass) static void gtk_gesture_stylus_init (GtkGestureStylus *gesture) { + GtkGestureStylusPrivate* priv = gtk_gesture_stylus_get_instance_private(gesture); + + priv->stylus_only = TRUE; } /** @@ -193,6 +257,53 @@ gtk_gesture_stylus_new (void) NULL); } +/** + * gtk_gesture_stylus_get_stylus_only: (attributes org.gtk.Method.get_property=stylus-only) + * @gesture: A `GtkGestureStylus` + * + * gets the state of stylus-only, based on which the gesture will + * either exclusively signal events from stylus input devices or + * for any input devices (e.g. mice). + * + * Returns: The state of stylus-only set via [method@Gtk.GestureStylus.set_stylus_only] + */ +gboolean +gtk_gesture_stylus_get_stylus_only(GtkGestureStylus* gesture) { + GtkGestureStylusPrivate* priv; + + g_return_val_if_fail(GTK_IS_GESTURE_STYLUS(gesture), FALSE); + + priv = gtk_gesture_stylus_get_instance_private(gesture); + + return priv->stylus_only; +} + +/** + * gtk_gesture_stylus_set_stylus_only: (attributes org.gtk.Method.set_property=stylus-only) + * @gesture: A `GtkGestureStylus` + * @stylus_only: %TRUE if the gesture should process exclusivly handle events from styluses + * + * sets the state of stylus-only + * + * If true, the gesture will exclusivly handle events from stylus input deivces, + * otherwise it'll handle events from any pointing device. + */ +void +gtk_gesture_stylus_set_stylus_only(GtkGestureStylus* gesture, gboolean stylus_only) { + GtkGestureStylusPrivate* priv; + + g_return_if_fail(GTK_IS_GESTURE_STYLUS(gesture)); + + priv = gtk_gesture_stylus_get_instance_private(gesture); + + if (priv->stylus_only == stylus_only) + return; + + priv->stylus_only = stylus_only; + + g_object_notify_by_pspec (G_OBJECT (gesture), obj_properties[PROP_STYLUS_ONLY]); +} + /** * gtk_gesture_stylus_get_axis: * @gesture: a `GtkGestureStylus` diff --git a/gtk/gtkgesturestylus.h b/gtk/gtkgesturestylus.h index df31f5277a..4bd06128d9 100644 --- a/gtk/gtkgesturestylus.h +++ b/gtk/gtkgesturestylus.h @@ -43,6 +43,12 @@ GType gtk_gesture_stylus_get_type (void) G_GNUC_CONST; GDK_AVAILABLE_IN_ALL GtkGesture * gtk_gesture_stylus_new (void); +GDK_AVAILABLE_IN_4_8 +gboolean gtk_gesture_stylus_get_stylus_only (GtkGestureStylus* gesture); +GDK_AVAILABLE_IN_4_8 +void gtk_gesture_stylus_set_stylus_only (GtkGestureStylus* gesture, + gboolean stylus_only); + GDK_AVAILABLE_IN_ALL gboolean gtk_gesture_stylus_get_axis (GtkGestureStylus *gesture, GdkAxisUse axis, From c85fbcea5583cd84dcadecebcd155912eece808f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20=22sp1rit=22=E2=80=8B?= Date: Mon, 21 Nov 2022 16:30:56 +0100 Subject: [PATCH 3/4] adjusted stylus-only code to fit gtk code conventions --- gtk/gtkgesturestylus.c | 78 ++++++++++++++++++++++-------------------- gtk/gtkgesturestylus.h | 10 +++--- 2 files changed, 45 insertions(+), 43 deletions(-) diff --git a/gtk/gtkgesturestylus.c b/gtk/gtkgesturestylus.c index 8e187c2545..eef9519754 100644 --- a/gtk/gtkgesturestylus.c +++ b/gtk/gtkgesturestylus.c @@ -53,39 +53,41 @@ enum { N_SIGNALS }; -static GParamSpec* obj_properties[N_PROPERTIES] = { NULL, }; +static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, }; static guint signals[N_SIGNALS] = { 0, }; -static void gtk_gesture_stylus_get_property (GObject* object, - guint prop_id, - GValue* value, - GParamSpec* pspec) +static void gtk_gesture_stylus_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) { - GtkGestureStylus* gesture = GTK_GESTURE_STYLUS(object); + GtkGestureStylus *gesture = GTK_GESTURE_STYLUS (object); - switch (prop_id) { - case PROP_STYLUS_ONLY: - g_value_set_boolean(value, gtk_gesture_stylus_get_stylus_only(gesture)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } + switch (prop_id) + { + case PROP_STYLUS_ONLY: + g_value_set_boolean (value, gtk_gesture_stylus_get_stylus_only (gesture)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } } -static void gtk_gesture_stylus_set_property (GObject* object, - guint prop_id, - const GValue* value, - GParamSpec* pspec) +static void gtk_gesture_stylus_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - GtkGestureStylus* gesture = GTK_GESTURE_STYLUS(object); + GtkGestureStylus *gesture = GTK_GESTURE_STYLUS (object); - switch (prop_id) { - case PROP_STYLUS_ONLY: - gtk_gesture_stylus_set_stylus_only(gesture, g_value_get_boolean(value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } + switch (prop_id) + { + case PROP_STYLUS_ONLY: + gtk_gesture_stylus_set_stylus_only (gesture, g_value_get_boolean (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } } static gboolean @@ -98,7 +100,7 @@ gtk_gesture_stylus_handle_event (GtkEventController *controller, GdkModifierType modifiers; guint n_signal; - priv = gtk_gesture_stylus_get_instance_private(GTK_GESTURE_STYLUS(controller)); + priv = gtk_gesture_stylus_get_instance_private (GTK_GESTURE_STYLUS (controller)); GTK_EVENT_CONTROLLER_CLASS (gtk_gesture_stylus_parent_class)->handle_event (controller, event, x, y); if (!(priv->stylus_only || gdk_event_get_device_tool (event))) @@ -144,12 +146,10 @@ gtk_gesture_stylus_class_init (GtkGestureStylusClass *klass) * * If this gesture should exclusively react to stylus input devices. */ - obj_properties[PROP_STYLUS_ONLY] = g_param_spec_boolean("stylus-only", - P_("Stylus only"), - P_("Should this gesture exclusively react to stylus input devices."), + obj_properties[PROP_STYLUS_ONLY] = g_param_spec_boolean ("stylus-only", NULL, NULL, TRUE, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_CONSTRUCT); - g_object_class_install_properties(object_class, N_PROPERTIES, obj_properties); + g_object_class_install_properties (object_class, N_PROPERTIES, obj_properties); event_controller_class = GTK_EVENT_CONTROLLER_CLASS (klass); event_controller_class->handle_event = gtk_gesture_stylus_handle_event; @@ -268,12 +268,13 @@ gtk_gesture_stylus_new (void) * Returns: The state of stylus-only set via [method@Gtk.GestureStylus.set_stylus_only] */ gboolean -gtk_gesture_stylus_get_stylus_only(GtkGestureStylus* gesture) { - GtkGestureStylusPrivate* priv; +gtk_gesture_stylus_get_stylus_only (GtkGestureStylus *gesture) +{ + GtkGestureStylusPrivate *priv; - g_return_val_if_fail(GTK_IS_GESTURE_STYLUS(gesture), FALSE); + g_return_val_if_fail (GTK_IS_GESTURE_STYLUS (gesture), FALSE); - priv = gtk_gesture_stylus_get_instance_private(gesture); + priv = gtk_gesture_stylus_get_instance_private (gesture); return priv->stylus_only; } @@ -289,12 +290,13 @@ gtk_gesture_stylus_get_stylus_only(GtkGestureStylus* gesture) { * otherwise it'll handle events from any pointing device. */ void -gtk_gesture_stylus_set_stylus_only(GtkGestureStylus* gesture, gboolean stylus_only) { - GtkGestureStylusPrivate* priv; +gtk_gesture_stylus_set_stylus_only (GtkGestureStylus *gesture, gboolean stylus_only) +{ + GtkGestureStylusPrivate *priv; - g_return_if_fail(GTK_IS_GESTURE_STYLUS(gesture)); + g_return_if_fail (GTK_IS_GESTURE_STYLUS (gesture)); - priv = gtk_gesture_stylus_get_instance_private(gesture); + priv = gtk_gesture_stylus_get_instance_private (gesture); if (priv->stylus_only == stylus_only) return; diff --git a/gtk/gtkgesturestylus.h b/gtk/gtkgesturestylus.h index 4bd06128d9..ea7784d249 100644 --- a/gtk/gtkgesturestylus.h +++ b/gtk/gtkgesturestylus.h @@ -43,11 +43,11 @@ GType gtk_gesture_stylus_get_type (void) G_GNUC_CONST; GDK_AVAILABLE_IN_ALL GtkGesture * gtk_gesture_stylus_new (void); -GDK_AVAILABLE_IN_4_8 -gboolean gtk_gesture_stylus_get_stylus_only (GtkGestureStylus* gesture); -GDK_AVAILABLE_IN_4_8 -void gtk_gesture_stylus_set_stylus_only (GtkGestureStylus* gesture, - gboolean stylus_only); +GDK_AVAILABLE_IN_4_10 +gboolean gtk_gesture_stylus_get_stylus_only (GtkGestureStylus *gesture); +GDK_AVAILABLE_IN_4_10 +void gtk_gesture_stylus_set_stylus_only (GtkGestureStylus *gesture, + gboolean stylus_only); GDK_AVAILABLE_IN_ALL gboolean gtk_gesture_stylus_get_axis (GtkGestureStylus *gesture, From 6dd939f13eb90e647b568bde8fadeef9a057a00d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20=22sp1rit=22=E2=80=8B?= Date: Wed, 23 Nov 2022 09:09:50 +0100 Subject: [PATCH 4/4] improved docs of Gtk.GestureStylus --- gtk/gtkgesturestylus.c | 69 ++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/gtk/gtkgesturestylus.c b/gtk/gtkgesturestylus.c index eef9519754..bc3da9351d 100644 --- a/gtk/gtkgesturestylus.c +++ b/gtk/gtkgesturestylus.c @@ -63,14 +63,14 @@ static void gtk_gesture_stylus_get_property (GObject *object, { GtkGestureStylus *gesture = GTK_GESTURE_STYLUS (object); - switch (prop_id) - { - case PROP_STYLUS_ONLY: - g_value_set_boolean (value, gtk_gesture_stylus_get_stylus_only (gesture)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } + switch (prop_id) + { + case PROP_STYLUS_ONLY: + g_value_set_boolean (value, gtk_gesture_stylus_get_stylus_only (gesture)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } } static void gtk_gesture_stylus_set_property (GObject *object, @@ -78,16 +78,16 @@ static void gtk_gesture_stylus_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { - GtkGestureStylus *gesture = GTK_GESTURE_STYLUS (object); + GtkGestureStylus *gesture = GTK_GESTURE_STYLUS (object); - switch (prop_id) - { - case PROP_STYLUS_ONLY: - gtk_gesture_stylus_set_stylus_only (gesture, g_value_get_boolean (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } + switch (prop_id) + { + case PROP_STYLUS_ONLY: + gtk_gesture_stylus_set_stylus_only (gesture, g_value_get_boolean (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } } static gboolean @@ -145,10 +145,14 @@ gtk_gesture_stylus_class_init (GtkGestureStylusClass *klass) * GtkGestureStylus:stylus-only: (attributes org.gtk.Property.get=gtk_gesture_stylus_get_stylus_only org.gtk.Property.set=gtk_gesture_stylus_set_stylus_only) * * If this gesture should exclusively react to stylus input devices. + * + * Since: 4.10 */ obj_properties[PROP_STYLUS_ONLY] = g_param_spec_boolean ("stylus-only", NULL, NULL, TRUE, - G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_CONSTRUCT); + G_PARAM_READWRITE | + G_PARAM_EXPLICIT_NOTIFY | + G_PARAM_CONSTRUCT); g_object_class_install_properties (object_class, N_PROPERTIES, obj_properties); event_controller_class = GTK_EVENT_CONTROLLER_CLASS (klass); @@ -259,45 +263,46 @@ gtk_gesture_stylus_new (void) /** * gtk_gesture_stylus_get_stylus_only: (attributes org.gtk.Method.get_property=stylus-only) - * @gesture: A `GtkGestureStylus` + * @gesture: the gesture * - * gets the state of stylus-only, based on which the gesture will - * either exclusively signal events from stylus input devices or - * for any input devices (e.g. mice). + * Checks whether the gesture is for styluses only. * - * Returns: The state of stylus-only set via [method@Gtk.GestureStylus.set_stylus_only] + * Stylus-only gestures will signal events exclusively from stylus + * input devices. + * + * Returns: %TRUE if the gesture is only for stylus events + * + * Since: 4.10 */ gboolean gtk_gesture_stylus_get_stylus_only (GtkGestureStylus *gesture) { - GtkGestureStylusPrivate *priv; + GtkGestureStylusPrivate *priv = gtk_gesture_stylus_get_instance_private (gesture); g_return_val_if_fail (GTK_IS_GESTURE_STYLUS (gesture), FALSE); - priv = gtk_gesture_stylus_get_instance_private (gesture); - return priv->stylus_only; } /** * gtk_gesture_stylus_set_stylus_only: (attributes org.gtk.Method.set_property=stylus-only) - * @gesture: A `GtkGestureStylus` - * @stylus_only: %TRUE if the gesture should process exclusivly handle events from styluses + * @gesture: the gesture + * @stylus_only: whether the gesture is used exclusivly for stylus events * - * sets the state of stylus-only + * Sets the state of stylus-only * * If true, the gesture will exclusivly handle events from stylus input deivces, * otherwise it'll handle events from any pointing device. + * + * Since: 4.10 */ void gtk_gesture_stylus_set_stylus_only (GtkGestureStylus *gesture, gboolean stylus_only) { - GtkGestureStylusPrivate *priv; + GtkGestureStylusPrivate *priv = gtk_gesture_stylus_get_instance_private (gesture); g_return_if_fail (GTK_IS_GESTURE_STYLUS (gesture)); - priv = gtk_gesture_stylus_get_instance_private (gesture); - if (priv->stylus_only == stylus_only) return;