From 25557c1c5d977acb5659e13394961524b67c2ec0 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 3 Aug 2015 17:22:29 +0200 Subject: [PATCH] gdkevent: Hold refs to device/source_device The extra reference will be held from GdkEventPrivate data, so there's a common place to all events. Without this, events queued after devices/ capabilities disappear (eg. on TTY switch) might hold invalid pointers. Windowing level operations on those devices (queries, grabs...) are expected to fail at that time, but we should hold meaningful data for the regular event handling paths. https://bugzilla.gnome.org/show_bug.cgi?id=753185 --- gdk/gdkevents.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c index 2b2c6f8eec..4052d54bd8 100644 --- a/gdk/gdkevents.c +++ b/gdk/gdkevents.c @@ -658,8 +658,8 @@ gdk_event_copy (const GdkEvent *event) GdkEventPrivate *private = (GdkEventPrivate *)event; new_private->screen = private->screen; - new_private->device = private->device; - new_private->source_device = private->source_device; + new_private->device = private->device ? g_object_ref (private->device) : NULL; + new_private->source_device = private->source_device ? g_object_ref (private->source_device) : NULL; } switch (event->any.type) @@ -754,10 +754,18 @@ gdk_event_copy (const GdkEvent *event) void gdk_event_free (GdkEvent *event) { + GdkEventPrivate *private; GdkDisplay *display; g_return_if_fail (event != NULL); + if (gdk_event_is_allocated (event)) + { + private = (GdkEventPrivate *) event; + g_clear_object (&private->device); + g_clear_object (&private->source_device); + } + switch (event->any.type) { case GDK_KEY_PRESS: @@ -1519,7 +1527,7 @@ gdk_event_set_device (GdkEvent *event, private = (GdkEventPrivate *) event; - private->device = device; + g_set_object (&private->device, device); switch (event->type) { @@ -1672,7 +1680,7 @@ gdk_event_set_source_device (GdkEvent *event, private = (GdkEventPrivate *) event; - private->source_device = device; + g_set_object (&private->source_device, device); } /**