[gtk/ebassi/surface-event] Use the right types for the GdkSurface::event arguments
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/ebassi/surface-event] Use the right types for the GdkSurface::event arguments
- Date: Tue, 19 May 2020 11:22:21 +0000 (UTC)
commit dd4d6930b5cbd2e63f9b875477f1311780ce5c08
Author: Emmanuele Bassi <ebassi gnome org>
Date: Tue May 19 12:18:24 2020 +0100
Use the right types for the GdkSurface::event arguments
We pass the GdkEvent as a pointer, because the autogenerated marshallers
don't know how to handle GTypeInstance-derived classes.
Since the GValue box that we use in the marshaller passes the GdkEvent
instance as is, we also need to acquire a reference before invoking the
closure, and release it afterwards, to ensure that the GdkEvent instance
survices the invocation.
gdk/gdksurface.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 61 insertions(+), 3 deletions(-)
---
diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c
index 31fcf9659f..5fcb20de9a 100644
--- a/gdk/gdksurface.c
+++ b/gdk/gdksurface.c
@@ -380,6 +380,64 @@ gdk_surface_layout_popup_helper (GdkSurface *surface,
*out_final_rect = final_rect;
}
+/* Since GdkEvent is a GTypeInstance, GValue can only store it as a pointer,
+ * and GClosure does not know how to handle its memory management. To avoid
+ * the event going away in the middle of the signal emission, we provide a
+ * marshaller that keeps the event alive for the duration of the closure.
+ */
+static void
+gdk_surface_event_marshaller (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data)
+{
+ GdkEvent *event = g_value_get_pointer (¶m_values[1]);
+
+ gdk_event_ref (event);
+
+ _gdk_marshal_BOOLEAN__POINTER (closure,
+ return_value,
+ n_param_values,
+ param_values,
+ invocation_hint,
+ marshal_data);
+
+
+ gdk_event_unref (event);
+}
+
+static void
+gdk_surface_event_marshallerv (GClosure *closure,
+ GValue *return_value,
+ gpointer instance,
+ va_list args,
+ gpointer marshal_data,
+ int n_params,
+ GType *param_types)
+{
+ va_list args_copy;
+ GdkEvent *event;
+
+ G_VA_COPY (args_copy, args);
+ event = va_arg (args_copy, gpointer);
+
+ gdk_event_ref (event);
+
+ _gdk_marshal_BOOLEAN__POINTERv (closure,
+ return_value,
+ instance,
+ args,
+ marshal_data,
+ n_params,
+ param_types);
+
+ gdk_event_unref (event);
+
+ va_end (args_copy);
+}
+
static void
gdk_surface_init (GdkSurface *surface)
{
@@ -533,13 +591,13 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
0,
g_signal_accumulator_true_handled,
NULL,
- _gdk_marshal_BOOLEAN__POINTER,
+ gdk_surface_event_marshaller,
G_TYPE_BOOLEAN,
1,
- GDK_TYPE_EVENT);
+ G_TYPE_POINTER);
g_signal_set_va_marshaller (signals[EVENT],
G_OBJECT_CLASS_TYPE (object_class),
- _gdk_marshal_BOOLEAN__POINTERv);
+ gdk_surface_event_marshallerv);
/**
* GdkSurface::enter-montor:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]