[PATCH 2/2] Terminate grabs when the client that initiated them exits
Ander Conselvan de Oliveira
conselvan2 at gmail.com
Fri Mar 2 05:45:57 PST 2012
Add a client parameter to wl_input_device_start_pointer_focus(). If
it is non-nil, if that client terminates while the grab is still
active, the grab is ended and the current focus is set to NULL.
---
src/data-device.c | 3 ++-
src/wayland-server.c | 28 +++++++++++++++++++++++++++-
src/wayland-server.h | 4 +++-
3 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/src/data-device.c b/src/data-device.c
index be2360c..93ad4e7 100644
--- a/src/data-device.c
+++ b/src/data-device.c
@@ -326,7 +326,8 @@ data_device_start_drag(struct wl_client *client, struct wl_resource *resource,
&device->drag_icon_listener.link);
}
- wl_input_device_start_pointer_grab(device, &device->drag_grab, time);
+ wl_input_device_start_pointer_grab(device, &device->drag_grab, time,
+ source_resource->client);
}
static void
diff --git a/src/wayland-server.c b/src/wayland-server.c
index 6a8cbcb..6538a29 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -649,12 +649,38 @@ wl_input_device_end_keyboard_grab(struct wl_input_device *device, uint32_t time)
device->keyboard_grab = &device->default_keyboard_grab;
}
+static void
+destroy_grab_client(struct wl_listener *listener,
+ struct wl_resource *resource, uint32_t time)
+{
+ struct wl_input_device *device =
+ container_of(listener, struct wl_input_device,
+ grab_client_listener);
+
+ wl_input_device_end_pointer_grab(device, time);
+
+ /* if the client died, it is very likely the user is still holding a
+ * button that caused the grab to start and this probably happened
+ * when the focus was in one of the client's surfaces. Since the
+ * button down prevents the default grab from resetting the focus and
+ * the default grab will have the focus saved as that surfaces,
+ * set the focus to NULL here. */
+ wl_input_device_set_pointer_focus(device, NULL, time, 0, 0);
+}
+
WL_EXPORT void
wl_input_device_start_pointer_grab(struct wl_input_device *device,
- struct wl_pointer_grab *grab, uint32_t time)
+ struct wl_pointer_grab *grab, uint32_t time,
+ struct wl_client *client)
{
const struct wl_pointer_grab_interface *interface;
+ if (client) {
+ device->grab_client_listener.func = destroy_grab_client;
+ wl_list_insert(client->display_resource->destroy_listener_list.prev,
+ &device->grab_client_listener.link);
+ }
+
device->pointer_grab = grab;
interface = device->pointer_grab->interface;
grab->input_device = device;
diff --git a/src/wayland-server.h b/src/wayland-server.h
index a1ddc68..0ae4bce 100644
--- a/src/wayland-server.h
+++ b/src/wayland-server.h
@@ -224,6 +224,7 @@ struct wl_input_device {
uint32_t grab_button;
uint32_t grab_key;
struct wl_listener grab_listener;
+ struct wl_listener grab_client_listener;
struct wl_list drag_resource_list;
struct wl_data_source *drag_data_source;
@@ -309,7 +310,8 @@ wl_input_device_end_keyboard_grab(struct wl_input_device *device, uint32_t time)
void
wl_input_device_start_pointer_grab(struct wl_input_device *device,
- struct wl_pointer_grab *grab, uint32_t time);
+ struct wl_pointer_grab *grab, uint32_t time,
+ struct wl_client *client);
void
wl_input_device_end_pointer_grab(struct wl_input_device *device, uint32_t time);
--
1.7.5.4
More information about the wayland-devel
mailing list