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>
This commit is contained in:
parent
fa79b1d9dc
commit
493d979e57
@ -38,6 +38,7 @@
|
|||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
#include <sys/timerfd.h>
|
#include <sys/timerfd.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#ifdef HAVE_CAIRO_EGL
|
#ifdef HAVE_CAIRO_EGL
|
||||||
#include <wayland-egl.h>
|
#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 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
|
static void
|
||||||
pointer_surface_frame_callback(void *data, struct wl_callback *callback,
|
pointer_surface_frame_callback(void *data, struct wl_callback *callback,
|
||||||
uint32_t time)
|
uint32_t time)
|
||||||
@ -3541,15 +3558,9 @@ pointer_surface_frame_callback(void *data, struct wl_callback *callback,
|
|||||||
if (!input->pointer)
|
if (!input->pointer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (input->current_cursor == CURSOR_BLANK) {
|
if (input_set_pointer_special(input))
|
||||||
wl_pointer_set_cursor(input->pointer,
|
|
||||||
input->pointer_enter_serial,
|
|
||||||
NULL, 0, 0);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (input->current_cursor == CURSOR_UNSET)
|
|
||||||
return;
|
|
||||||
cursor = input->display->cursors[input->current_cursor];
|
cursor = input->display->cursors[input->current_cursor];
|
||||||
if (!cursor)
|
if (!cursor)
|
||||||
return;
|
return;
|
||||||
@ -3598,7 +3609,7 @@ input_set_pointer_image(struct input *input, int pointer)
|
|||||||
input->cursor_serial = input->pointer_enter_serial;
|
input->cursor_serial = input->pointer_enter_serial;
|
||||||
if (!input->cursor_frame_cb)
|
if (!input->cursor_frame_cb)
|
||||||
pointer_surface_frame_callback(input, NULL, 0);
|
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 current frame callback may be stuck if, for instance,
|
||||||
* the set cursor request was processed by the server after
|
* the set cursor request was processed by the server after
|
||||||
* this client lost the focus. In this case the cursor surface
|
* this client lost the focus. In this case the cursor surface
|
||||||
|
Loading…
Reference in New Issue
Block a user