<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>