From ddca49600f2400dd04af1795f135b29d0cd02279 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Mon, 16 Jul 2012 14:15:49 +0300 Subject: [PATCH] window: Workaround a stuck frame callback on the cursor surface It is possible that a client loses the focus between receiving a pointer.enter event and sending a pointer.set_cursor request. In that case, the cursor surface might not be mapped and the frame callback requested on it will never trigger. Work around this by trying to remap the cursor surface whenever there is a frame callback and the serial for the enter event is higher than the cursor serial. --- clients/window.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/clients/window.c b/clients/window.c index ab9d1553b..93299e176 100644 --- a/clients/window.c +++ b/clients/window.c @@ -2437,14 +2437,27 @@ static const struct wl_callback_listener pointer_surface_listener = { void input_set_pointer_image(struct input *input, int pointer) { - if (pointer == input->current_cursor && - input->pointer_enter_serial == input->cursor_serial) + int force = 0; + + if (input->pointer_enter_serial > input->cursor_serial) + force = 1; + + if (!force && pointer == input->current_cursor) return; input->current_cursor = pointer; input->cursor_serial = input->pointer_enter_serial; if (!input->cursor_frame_cb) pointer_surface_frame_callback(input, NULL, 0); + else if (force) { + /* The current frame callback may be stuck if, for instance, + * the set cursor request was processed by the server after + * this client lost the focus. In this case the cursor surface + * might not be mapped and the frame callback wouldn't ever + * complete. Send a set_cursor and attach to try to map the + * cursor surface again so that the callback will finish */ + input_set_pointer_image_index(input, 0); + } } struct wl_data_device *