summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2010-12-06 16:43:16 -0500
committerKristian Høgsberg <krh@bitplanet.net>2010-12-06 16:43:16 -0500
commitc551bd2ae8bbb4cec52fd9576a217ae5e2cef43a (patch)
tree3be6a69eb2c3a5ec1bc40ff1d1f77b85386b2b08
parent7d564d93eb28ae64998c17ac2fc92aef5ab07b75 (diff)
downloadweston-c551bd2ae8bbb4cec52fd9576a217ae5e2cef43a.tar.gz
Add a surface destroy callback and use it for focus tracking
-rw-r--r--compositor/compositor.c70
-rw-r--r--compositor/compositor.h8
-rw-r--r--wayland/wayland-server.c19
-rw-r--r--wayland/wayland-server.h9
4 files changed, 71 insertions, 35 deletions
diff --git a/compositor/compositor.c b/compositor/compositor.c
index d0cdcf24..7b1adec9 100644
--- a/compositor/compositor.c
+++ b/compositor/compositor.c
@@ -129,6 +129,8 @@ wlsc_surface_create(struct wlsc_compositor *compositor,
if (surface == NULL)
return NULL;
+ wl_list_init(&surface->surface.destroy_listener_list);
+
glGenTextures(1, &surface->texture);
glBindTexture(GL_TEXTURE_2D, surface->texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@@ -159,13 +161,17 @@ destroy_surface(struct wl_resource *resource, struct wl_client *client)
struct wlsc_surface *surface =
container_of(resource, struct wlsc_surface, surface.resource);
struct wlsc_compositor *compositor = surface->compositor;
- struct wlsc_listener *l;
+ struct wl_listener *l, *next;
wl_list_remove(&surface->link);
glDeleteTextures(1, &surface->texture);
wl_list_for_each(l, &compositor->surface_destroy_listener_list, link)
- l->func(l, surface);
+ l->func(l, &surface->surface);
+
+ wl_list_for_each_safe(l, next,
+ &surface->surface.destroy_listener_list, link)
+ l->func(l, &surface->surface);
free(surface);
@@ -574,7 +580,7 @@ get_time(void)
struct wlsc_drag {
struct wl_drag drag;
- struct wlsc_listener listener;
+ struct wl_listener listener;
};
static void
@@ -596,14 +602,14 @@ destroy_drag(struct wl_resource *resource, struct wl_client *client)
const static struct wl_drag_interface drag_interface;
static void
-drag_handle_surface_destroy(struct wlsc_listener *listener,
- struct wlsc_surface *surface)
+drag_handle_surface_destroy(struct wl_listener *listener,
+ struct wl_surface *surface)
{
struct wlsc_drag *drag =
container_of(listener, struct wlsc_drag, listener);
uint32_t time = get_time();
- if (drag->drag.pointer_focus == &surface->surface)
+ if (drag->drag.pointer_focus == surface)
wl_drag_set_pointer_focus(&drag->drag, NULL, time, 0, 0, 0, 0);
}
@@ -984,24 +990,6 @@ const static struct wl_input_device_interface input_device_interface = {
input_device_attach,
};
-static void
-handle_surface_destroy(struct wlsc_listener *listener,
- struct wlsc_surface *surface)
-{
- struct wlsc_input_device *device =
- container_of(listener, struct wlsc_input_device, listener);
- uint32_t time = get_time();
-
- if (device->input_device.keyboard_focus == &surface->surface)
- wl_input_device_set_keyboard_focus(&device->input_device, NULL, time);
- if (device->input_device.pointer_focus == &surface->surface)
- wl_input_device_set_pointer_focus(&device->input_device, NULL, time,
- 0, 0, 0, 0);
- if (device->input_device.pointer_focus == &surface->surface ||
- (device->input_device.pointer_focus == &wl_grab_surface &&
- device->grab_surface == surface))
- wlsc_input_device_end_grab(device, time);
-}
static void
wl_drag_set_pointer_focus(struct wl_drag *drag,
@@ -1165,6 +1153,32 @@ static const struct wl_drag_interface drag_interface = {
drag_cancel,
};
+static void
+lose_pointer_focus(struct wl_listener *listener,
+ struct wl_surface *surface)
+{
+ uint32_t time = get_time();
+ struct wlsc_input_device *device =
+ container_of(listener, struct wlsc_input_device,
+ input_device.pointer_focus_listener);
+
+ wl_input_device_set_pointer_focus(&device->input_device,
+ NULL, time, 0, 0, 0, 0);
+ wlsc_input_device_end_grab(device, time);
+}
+
+static void
+lose_keyboard_focus(struct wl_listener *listener,
+ struct wl_surface *surface)
+{
+ uint32_t time = get_time();
+ struct wlsc_input_device *device =
+ container_of(listener, struct wlsc_input_device,
+ input_device.keyboard_focus_listener);
+
+ wl_input_device_set_keyboard_focus(&device->input_device, NULL, time);
+}
+
void
wlsc_input_device_init(struct wlsc_input_device *device,
struct wlsc_compositor *ec)
@@ -1183,9 +1197,11 @@ wlsc_input_device_init(struct wlsc_input_device *device,
device->hotspot_x = 16;
device->hotspot_y = 16;
- device->listener.func = handle_surface_destroy;
- wl_list_insert(ec->surface_destroy_listener_list.prev,
- &device->listener.link);
+ wl_list_init(&device->input_device.pointer_focus_listener.link);
+ device->input_device.pointer_focus_listener.func = lose_pointer_focus;
+ wl_list_init(&device->input_device.keyboard_focus_listener.link);
+ device->input_device.keyboard_focus_listener.func = lose_keyboard_focus;
+
wl_list_insert(ec->input_device_list.prev, &device->link);
wlsc_input_device_set_pointer_image(device, WLSC_POINTER_LEFT_PTR);
diff --git a/compositor/compositor.h b/compositor/compositor.h
index 6502c589..16d01a78 100644
--- a/compositor/compositor.h
+++ b/compositor/compositor.h
@@ -41,12 +41,6 @@ struct wlsc_matrix {
struct wlsc_surface;
-struct wlsc_listener {
- struct wl_list link;
- void (*func)(struct wlsc_listener *listener,
- struct wlsc_surface *surface);
-};
-
struct wlsc_output {
struct wl_object object;
struct wl_list link;
@@ -106,7 +100,7 @@ struct wlsc_input_device {
uint32_t grab_button;
struct wl_drag *drag;
- struct wlsc_listener listener;
+ struct wl_listener listener;
};
struct wlsc_drm {
diff --git a/wayland/wayland-server.c b/wayland/wayland-server.c
index 57599faa..487bddc5 100644
--- a/wayland/wayland-server.c
+++ b/wayland/wayland-server.c
@@ -79,7 +79,14 @@ struct wl_global {
struct wl_list link;
};
-WL_EXPORT struct wl_surface wl_grab_surface;
+WL_EXPORT struct wl_surface wl_grab_surface = {
+ {},
+ NULL,
+ {
+ &wl_grab_surface.destroy_listener_list,
+ &wl_grab_surface.destroy_listener_list
+ }
+};
static int wl_debug = 0;
@@ -333,6 +340,11 @@ wl_input_device_set_pointer_focus(struct wl_input_device *device,
device->pointer_focus = surface;
device->pointer_focus_time = time;
+
+ wl_list_remove(&device->pointer_focus_listener.link);
+ if (surface)
+ wl_list_insert(surface->destroy_listener_list.prev,
+ &device->pointer_focus_listener.link);
}
WL_EXPORT void
@@ -358,6 +370,11 @@ wl_input_device_set_keyboard_focus(struct wl_input_device *device,
device->keyboard_focus = surface;
device->keyboard_focus_time = time;
+
+ wl_list_remove(&device->keyboard_focus_listener.link);
+ if (surface)
+ wl_list_insert(surface->destroy_listener_list.prev,
+ &device->keyboard_focus_listener.link);
}
static void
diff --git a/wayland/wayland-server.h b/wayland/wayland-server.h
index 8b22b42c..15a02a4f 100644
--- a/wayland/wayland-server.h
+++ b/wayland/wayland-server.h
@@ -119,9 +119,16 @@ struct wl_buffer {
int32_t x, int32_t y, int32_t width, int32_t height);
};
+struct wl_listener {
+ struct wl_list link;
+ void (*func)(struct wl_listener *listener,
+ struct wl_surface *surface);
+};
+
struct wl_surface {
struct wl_resource resource;
struct wl_client *client;
+ struct wl_list destroy_listener_list;
};
struct wl_shell {
@@ -135,6 +142,8 @@ struct wl_input_device {
struct wl_array keys;
uint32_t pointer_focus_time;
uint32_t keyboard_focus_time;
+ struct wl_listener pointer_focus_listener;
+ struct wl_listener keyboard_focus_listener;
};
struct wl_visual {