<p dir="ltr">Perhaps a better long-term solution would be to have the pointer register a destroy listener on the surface's resource and use that to null out the focus.  Then we wouldn't have to worry about specifically flagging this strange intermediate state.<br>

--Jason Ekstrand</p>
<div class="gmail_quote">On Sep 13, 2013 9:36 AM, "Giulio Camuffo" <<a href="mailto:giuliocamuffo@gmail.com">giuliocamuffo@gmail.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
with the surface ref-count feature a surface may live on after its<br>
resource was destroyed. set it to NULL in that case, so that code<br>
like find_resource_for_surface() in input.c will act accordingly.<br>
Moreover, we don't send the wl_pointer/keyboard_leave events if the<br>
surface has a NULL resource.<br>
---<br>
<br>
Also fixed the silly write after free.<br>
<br>
 src/compositor.c |  4 ++++<br>
 src/input.c      | 16 ++++++++++------<br>
 2 files changed, 14 insertions(+), 6 deletions(-)<br>
<br>
diff --git a/src/compositor.c b/src/compositor.c<br>
index 67ac64e..a1c01fb 100644<br>
--- a/src/compositor.c<br>
+++ b/src/compositor.c<br>
@@ -1069,8 +1069,12 @@ static void<br>
 destroy_surface(struct wl_resource *resource)<br>
 {<br>
        struct weston_surface *surface = wl_resource_get_user_data(resource);<br>
+       int destroyed = surface->ref_count <= 1;<br>
<br>
        weston_surface_destroy(surface);<br>
+       if (!destroyed) {<br>
+               surface->resource = NULL;<br>
+       }<br>
 }<br>
<br>
 static void<br>
diff --git a/src/input.c b/src/input.c<br>
index 9c30460..d6a4740 100644<br>
--- a/src/input.c<br>
+++ b/src/input.c<br>
@@ -425,9 +425,11 @@ weston_pointer_set_focus(struct weston_pointer *pointer,<br>
<br>
        resource = pointer->focus_resource;<br>
        if (resource && pointer->focus != surface) {<br>
-               serial = wl_display_next_serial(display);<br>
-               wl_pointer_send_leave(resource, serial,<br>
-                                     pointer->focus->resource);<br>
+               if (pointer->focus->resource) {<br>
+                       serial = wl_display_next_serial(display);<br>
+                       wl_pointer_send_leave(resource, serial,<br>
+                                               pointer->focus->resource);<br>
+               }<br>
                wl_list_remove(&pointer->focus_listener.link);<br>
        }<br>
<br>
@@ -471,9 +473,11 @@ weston_keyboard_set_focus(struct weston_keyboard *keyboard,<br>
<br>
        if (keyboard->focus_resource && keyboard->focus != surface) {<br>
                resource = keyboard->focus_resource;<br>
-               serial = wl_display_next_serial(display);<br>
-               wl_keyboard_send_leave(resource, serial,<br>
-                                      keyboard->focus->resource);<br>
+               if (keyboard->focus->resource) {<br>
+                       serial = wl_display_next_serial(display);<br>
+                       wl_keyboard_send_leave(resource, serial,<br>
+                                               keyboard->focus->resource);<br>
+               }<br>
                wl_list_remove(&keyboard->focus_listener.link);<br>
        }<br>
<br>
--<br>
1.8.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>
</blockquote></div>