clients/window: Fix animated cursors
Since commit 992ee045f1b we create a new surface when we update the cursor image. This broke animated cursors by discarding any existing frame callback used for timing, and moving the setup for frame callbacks to after the commit on the pointer surface. To fix this we need another surface commit for the frame callbacks, but this alone is not enough to fix the regression, as a lingering kludge intended to fix problems when reusing the pointer surface is no longer working as intended. Since we no longer re-use the same surface, we can delete the old surface on pointer exit, along with any callbacks set on it. Then a frame callback will be recreated naturally. This lets us remove the now broken kludge from the past and restore animated cursor functionality. Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
This commit is contained in:
parent
3759ad1538
commit
f079f43658
@ -353,7 +353,6 @@ struct input {
|
||||
struct wl_surface *pointer_surface;
|
||||
uint32_t modifiers;
|
||||
uint32_t pointer_enter_serial;
|
||||
uint32_t cursor_serial;
|
||||
float sx, sy;
|
||||
struct wl_list link;
|
||||
|
||||
@ -2747,6 +2746,12 @@ input_remove_pointer_focus(struct input *input)
|
||||
input->pointer_focus = NULL;
|
||||
input->current_cursor = CURSOR_UNSET;
|
||||
cancel_pointer_image_update(input);
|
||||
wl_surface_destroy(input->pointer_surface);
|
||||
input->pointer_surface = NULL;
|
||||
if (input->cursor_frame_cb) {
|
||||
wl_callback_destroy(input->cursor_frame_cb);
|
||||
input->cursor_frame_cb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3876,6 +3881,7 @@ schedule_pointer_image_update(struct input *input,
|
||||
wl_callback_add_listener(input->cursor_frame_cb,
|
||||
&pointer_surface_listener, input);
|
||||
|
||||
wl_surface_commit(input->pointer_surface);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3959,30 +3965,15 @@ static const struct wl_callback_listener pointer_surface_listener = {
|
||||
void
|
||||
input_set_pointer_image(struct input *input, int pointer)
|
||||
{
|
||||
int force = 0;
|
||||
|
||||
if (!input->pointer)
|
||||
return;
|
||||
|
||||
if (input->pointer_enter_serial > input->cursor_serial)
|
||||
force = 1;
|
||||
|
||||
if (!force && pointer == input->current_cursor)
|
||||
if (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 && !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
|
||||
* 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 *
|
||||
|
Loading…
x
Reference in New Issue
Block a user