summaryrefslogtreecommitdiff
path: root/clients
diff options
context:
space:
mode:
authorDerek Foreman <derekf@osg.samsung.com>2015-03-04 16:26:25 -0600
committerPekka Paalanen <pekka.paalanen@collabora.co.uk>2015-03-05 10:14:25 +0200
commit493d979e57adddcc3b5d15b1766b6ab382f20767 (patch)
treed4b8b645a2b49482f08fae3efb1d30fb655446fe /clients
parentfa79b1d9dcef87d06ce11cc254ef27d79ba7db57 (diff)
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 <derekf@osg.samsung.com> Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Diffstat (limited to 'clients')
-rw-r--r--clients/window.c27
1 files 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 <sys/mman.h>
#include <sys/epoll.h>
#include <sys/timerfd.h>
+#include <stdbool.h>
#ifdef HAVE_CAIRO_EGL
#include <wayland-egl.h>
@@ -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