<div dir="ltr">Looks good to me.</div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/4/3 Rob Bradford <span dir="ltr"><<a href="mailto:robert.bradford@intel.com" target="_blank">robert.bradford@intel.com</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Rob Bradford <<a href="mailto:rob@linux.intel.com">rob@linux.intel.com</a>><br>
<br>
Add a destroy listener so that when the current surface associated with the<br>
pointer is destroyed we can reset the pointer to the current surface. In order<br>
to achieve this add a wl_pointer_set_current() which handles assigning the<br>
surface and creating the listener.<br>
<br>
This resolves a use-after-free error triggered with nested popup surfaces<br>
<br>
Fixes: <a href="https://bugzilla.gnome.org/show_bug.cgi?id=696946" target="_blank">https://bugzilla.gnome.org/show_bug.cgi?id=696946</a><br>
---<br>
 src/wayland-server.c | 22 ++++++++++++++++++++++<br>
 src/wayland-server.h |  3 +++<br>
 2 files changed, 25 insertions(+)<br>
<br>
diff --git a/src/wayland-server.c b/src/wayland-server.c<br>
index 384b465..3710d8b 100644<br>
--- a/src/wayland-server.c<br>
+++ b/src/wayland-server.c<br>
@@ -946,6 +946,28 @@ wl_pointer_end_grab(struct wl_pointer *pointer)<br>
                         pointer->current_x, pointer->current_y);<br>
 }<br>
<br>
+static void<br>
+current_surface_destroy(struct wl_listener *listener, void *data)<br>
+{<br>
+       struct wl_pointer *pointer =<br>
+               container_of(listener, struct wl_pointer, current_listener);<br>
+<br>
+       pointer->current = NULL;<br>
+}<br>
+<br>
+WL_EXPORT void<br>
+wl_pointer_set_current(struct wl_pointer *pointer, struct wl_surface *surface)<br>
+{<br>
+       pointer->current = surface;<br>
+<br>
+       if (!surface)<br>
+               return;<br>
+<br>
+       wl_signal_add(&surface->resource.destroy_signal,<br>
+                     &pointer->current_listener);<br>
+       pointer->current_listener.notify = current_surface_destroy;<br>
+}<br>
+<br>
 WL_EXPORT void<br>
 wl_touch_start_grab(struct wl_touch *touch, struct wl_touch_grab *grab)<br>
 {<br>
diff --git a/src/wayland-server.h b/src/wayland-server.h<br>
index e5a862a..af2be62 100644<br>
--- a/src/wayland-server.h<br>
+++ b/src/wayland-server.h<br>
@@ -312,6 +312,7 @@ struct wl_pointer {<br>
<br>
        wl_fixed_t x, y;<br>
        struct wl_surface *current;<br>
+       struct wl_listener current_listener;<br>
        wl_fixed_t current_x, current_y;<br>
<br>
        uint32_t button_count;<br>
@@ -450,6 +451,8 @@ wl_pointer_start_grab(struct wl_pointer *pointer,<br>
                      struct wl_pointer_grab *grab);<br>
 void<br>
 wl_pointer_end_grab(struct wl_pointer *pointer);<br>
+void<br>
+wl_pointer_set_current(struct wl_pointer *pointer, struct wl_surface *surface);<br>
<br>
 void<br>
 wl_keyboard_init(struct wl_keyboard *keyboard);<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.8.1.4<br>
<br>
_______________________________________________<br>
wayland-devel mailing list<br>
<a href="mailto:wayland-devel@lists.freedesktop.org">wayland-devel@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/wayland-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/wayland-devel</a><br>
</font></span></blockquote></div><br></div>