From 493d979e57adddcc3b5d15b1766b6ab382f20767 Mon Sep 17 00:00:00 2001 From: Derek Foreman Date: Wed, 4 Mar 2015 16:26:25 -0600 Subject: [PATCH] window: Fix crash in input_set_pointer_image when cursor is special Certain circumstances may lead to the "force" clause in input_set_pointer_image() being reached when the current cursor is blank or unset. These are special cursors that don't have images, and they need to be handled differently than image cursors. This patch puts the special cursor handling in its own function and calls it from both places that need it. Previously only the frame callback handler did this correctly. Signed-off-by: Derek Foreman Reviewed-by: Pekka Paalanen --- clients/window.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/clients/window.c b/clients/window.c index a04cef9c..1399fa40 100644 --- a/clients/window.c +++ b/clients/window.c @@ -38,6 +38,7 @@ #include #include #include +#include #ifdef HAVE_CAIRO_EGL #include @@ -3524,6 +3525,22 @@ input_set_pointer_image_index(struct input *input, int index) static const struct wl_callback_listener pointer_surface_listener; +static bool +input_set_pointer_special(struct input *input) +{ + if (input->current_cursor == CURSOR_BLANK) { + wl_pointer_set_cursor(input->pointer, + input->pointer_enter_serial, + NULL, 0, 0); + return true; + } + + if (input->current_cursor == CURSOR_UNSET) + return true; + + return false; +} + static void pointer_surface_frame_callback(void *data, struct wl_callback *callback, uint32_t time) @@ -3541,15 +3558,9 @@ pointer_surface_frame_callback(void *data, struct wl_callback *callback, if (!input->pointer) return; - if (input->current_cursor == CURSOR_BLANK) { - wl_pointer_set_cursor(input->pointer, - input->pointer_enter_serial, - NULL, 0, 0); + if (input_set_pointer_special(input)) return; - } - if (input->current_cursor == CURSOR_UNSET) - return; cursor = input->display->cursors[input->current_cursor]; if (!cursor) return; @@ -3598,7 +3609,7 @@ input_set_pointer_image(struct input *input, int pointer) input->cursor_serial = input->pointer_enter_serial; if (!input->cursor_frame_cb) pointer_surface_frame_callback(input, NULL, 0); - else if (force) { + else if (force && !input_set_pointer_special(input)) { /* 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