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.
This commit is contained in:
Emmanuele Bassi 2020-05-19 12:18:24 +01:00
parent 7fc2d9adc0
commit dd4d6930b5

View File

@ -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 (&param_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: