[PATCH weston 1/2] input: set the focus to NULL when the focus's resource is destroyed

Giulio Camuffo giuliocamuffo at gmail.com
Fri Nov 15 13:06:14 PST 2013


with the surface ref-count feature a surface may live on after its
resource was destroyed. so listen for the resource destroy signal
and set the focus to NULL.

Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>
---
 src/compositor.h |  3 +++
 src/input.c      | 50 +++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/src/compositor.h b/src/compositor.h
index c2de99f..610edd4 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -305,6 +305,7 @@ struct weston_pointer {
 	struct wl_list resource_list;
 	struct wl_list focus_resource_list;
 	struct weston_view *focus;
+	struct wl_listener focus_listener;
 	uint32_t focus_serial;
 	struct wl_signal focus_signal;
 
@@ -330,6 +331,7 @@ struct weston_touch {
 	struct wl_list resource_list;
 	struct wl_list focus_resource_list;
 	struct weston_view *focus;
+	struct wl_listener focus_listener;
 	uint32_t focus_serial;
 	struct wl_signal focus_signal;
 
@@ -425,6 +427,7 @@ struct weston_keyboard {
 	struct wl_list resource_list;
 	struct wl_list focus_resource_list;
 	struct weston_surface *focus;
+	struct wl_listener focus_listener;
 	uint32_t focus_serial;
 	struct wl_signal focus_signal;
 
diff --git a/src/input.c b/src/input.c
index 153bcb6..a678350 100644
--- a/src/input.c
+++ b/src/input.c
@@ -71,6 +71,33 @@ weston_compositor_idle_release(struct weston_compositor *compositor)
 }
 
 static void
+lose_pointer_focus(struct wl_listener *listener, void *data)
+{
+	struct weston_pointer *pointer =
+		container_of(listener, struct weston_pointer, focus_listener);
+
+	weston_pointer_set_focus(pointer, NULL, 0, 0);
+}
+
+static void
+lose_keyboard_focus(struct wl_listener *listener, void *data)
+{
+	struct weston_keyboard *keyboard =
+		container_of(listener, struct weston_keyboard, focus_listener);
+
+	weston_keyboard_set_focus(keyboard, NULL);
+}
+
+static void
+lose_touch_focus(struct wl_listener *listener, void *data)
+{
+	struct weston_touch *touch =
+		container_of(listener, struct weston_touch, focus_listener);
+
+	weston_touch_set_focus(touch->seat, NULL);
+}
+
+static void
 move_resources(struct wl_list *destination, struct wl_list *source)
 {
 	wl_list_insert_list(destination, source);
@@ -388,6 +415,8 @@ weston_pointer_create(void)
 
 	wl_list_init(&pointer->resource_list);
 	wl_list_init(&pointer->focus_resource_list);
+	wl_list_init(&pointer->focus_listener.link);
+	pointer->focus_listener.notify = lose_pointer_focus;
 	pointer->default_grab.interface = &default_pointer_grab_interface;
 	pointer->default_grab.pointer = pointer;
 	pointer->grab = &pointer->default_grab;
@@ -409,7 +438,7 @@ weston_pointer_destroy(struct weston_pointer *pointer)
 		pointer_unmap_sprite(pointer);
 
 	/* XXX: What about pointer->resource_list? */
-
+	wl_list_remove(&pointer->focus_listener.link);
 	free(pointer);
 }
 
@@ -424,6 +453,8 @@ weston_keyboard_create(void)
 
 	wl_list_init(&keyboard->resource_list);
 	wl_list_init(&keyboard->focus_resource_list);
+	wl_list_init(&keyboard->focus_listener.link);
+	keyboard->focus_listener.notify = lose_keyboard_focus;
 	wl_array_init(&keyboard->keys);
 	keyboard->default_grab.interface = &default_keyboard_grab_interface;
 	keyboard->default_grab.keyboard = keyboard;
@@ -439,6 +470,7 @@ weston_keyboard_destroy(struct weston_keyboard *keyboard)
 	/* XXX: What about keyboard->resource_list? */
 
 	wl_array_release(&keyboard->keys);
+	wl_list_remove(&keyboard->focus_listener.link);
 	free(keyboard);
 }
 
@@ -453,6 +485,8 @@ weston_touch_create(void)
 
 	wl_list_init(&touch->resource_list);
 	wl_list_init(&touch->focus_resource_list);
+	wl_list_init(&touch->focus_listener.link);
+	touch->focus_listener.notify = lose_touch_focus;
 	touch->default_grab.interface = &default_touch_grab_interface;
 	touch->default_grab.touch = touch;
 	touch->grab = &touch->default_grab;
@@ -466,6 +500,7 @@ weston_touch_destroy(struct weston_touch *touch)
 {
 	/* XXX: What about touch->resource_list? */
 
+	wl_list_remove(&touch->focus_listener.link);
 	free(touch);
 }
 
@@ -513,6 +548,8 @@ weston_pointer_set_focus(struct weston_pointer *pointer,
 					      pointer->focus->surface->resource);
 		}
 
+		wl_list_remove(&pointer->focus_listener.link);
+		wl_list_init(&pointer->focus_listener.link);
 		move_resources(&pointer->resource_list, focus_resource_list);
 	}
 
@@ -541,6 +578,8 @@ weston_pointer_set_focus(struct weston_pointer *pointer,
 		}
 
 		pointer->focus_serial = serial;
+		wl_resource_add_destroy_listener(view->surface->resource,
+						 &pointer->focus_listener);
 	}
 
 	pointer->focus = view;
@@ -580,6 +619,8 @@ weston_keyboard_set_focus(struct weston_keyboard *keyboard,
 			wl_keyboard_send_leave(resource, serial,
 					keyboard->focus->resource);
 		}
+		wl_list_remove(&keyboard->focus_listener.link);
+		wl_list_init(&keyboard->focus_listener.link);
 		move_resources(&keyboard->resource_list, focus_resource_list);
 	}
 
@@ -598,6 +639,8 @@ weston_keyboard_set_focus(struct weston_keyboard *keyboard,
 					    surface,
 					    serial);
 		keyboard->focus_serial = serial;
+		wl_resource_add_destroy_listener(surface->resource,
+						 &keyboard->focus_listener);
 	}
 
 	keyboard->focus = surface;
@@ -1192,6 +1235,9 @@ weston_touch_set_focus(struct weston_seat *seat, struct weston_view *view)
 		return;
 	}
 
+	wl_list_remove(&seat->touch->focus_listener.link);
+	wl_list_init(&seat->touch->focus_listener.link);
+
 	if (!wl_list_empty(focus_resource_list)) {
 		move_resources(&seat->touch->resource_list,
 			       focus_resource_list);
@@ -1203,6 +1249,8 @@ weston_touch_set_focus(struct weston_seat *seat, struct weston_view *view)
 		move_resources_for_client(focus_resource_list,
 					  &seat->touch->resource_list,
 					  surface_client);
+		wl_resource_add_destroy_listener(view->surface->resource,
+						 &seat->touch->focus_listener);
 	}
 	seat->touch->focus = view;
 }
-- 
1.8.4.2



More information about the wayland-devel mailing list