Wayland: Fix mouse pointer hiding on Plasma Wayland

Unlike Mutter and Sway, KWin actually checks the serial passed in
wl_pointer_set_cursor(). The serial provided is supposed to be the
serial of the pointer enter event, but We were always passing 0.
This caused KWin to drop our requests to hide the cursor.

Thanks to the KDE folks for spotting this in my debug logs.

Fixes #3576
This commit is contained in:
Cameron Gutman 2021-02-25 19:30:47 -06:00 committed by Sam Lantinga
parent d2d834b990
commit 8c5b7af2d2
3 changed files with 55 additions and 52 deletions

View file

@ -61,55 +61,6 @@
/* Weston uses a ratio of 10 units per scroll tick */
#define WAYLAND_WHEEL_AXIS_UNIT 10
typedef struct {
// repeat_rate in range of [1, 1000]
int32_t repeat_rate;
int32_t repeat_delay;
SDL_bool is_initialized;
SDL_bool is_key_down;
uint32_t next_repeat_ms;
uint32_t scancode;
char text[8];
} SDL_WaylandKeyboardRepeat;
struct SDL_WaylandInput {
SDL_VideoData *display;
struct wl_seat *seat;
struct wl_pointer *pointer;
struct wl_touch *touch;
struct wl_keyboard *keyboard;
SDL_WaylandDataDevice *data_device;
struct zwp_relative_pointer_v1 *relative_pointer;
struct zwp_confined_pointer_v1 *confined_pointer;
SDL_Window *confined_pointer_window;
SDL_WindowData *pointer_focus;
SDL_WindowData *keyboard_focus;
/* Last motion location */
wl_fixed_t sx_w;
wl_fixed_t sy_w;
double dx_frac;
double dy_frac;
struct {
struct xkb_keymap *keymap;
struct xkb_state *state;
} xkb;
/* information about axis events on current frame */
struct {
SDL_bool is_x_discrete;
float x;
SDL_bool is_y_discrete;
float y;
} pointer_curr_axis_info;
SDL_WaylandKeyboardRepeat keyboard_repeat;
};
struct SDL_WaylandTouchPoint {
SDL_TouchID id;
float x;
@ -324,6 +275,7 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer,
if (window) {
input->pointer_focus = window;
input->pointer_enter_serial = serial;
SDL_SetMouseFocus(window->sdlwindow);
/* In the case of e.g. a pointer confine warp, we may receive an enter
* event with no following motion event, but with the new coordinates

View file

@ -28,7 +28,55 @@
#include "SDL_waylandwindow.h"
#include "SDL_waylanddatamanager.h"
struct SDL_WaylandInput;
typedef struct {
// repeat_rate in range of [1, 1000]
int32_t repeat_rate;
int32_t repeat_delay;
SDL_bool is_initialized;
SDL_bool is_key_down;
uint32_t next_repeat_ms;
uint32_t scancode;
char text[8];
} SDL_WaylandKeyboardRepeat;
struct SDL_WaylandInput {
SDL_VideoData *display;
struct wl_seat *seat;
struct wl_pointer *pointer;
struct wl_touch *touch;
struct wl_keyboard *keyboard;
SDL_WaylandDataDevice *data_device;
struct zwp_relative_pointer_v1 *relative_pointer;
struct zwp_confined_pointer_v1 *confined_pointer;
SDL_Window *confined_pointer_window;
SDL_WindowData *pointer_focus;
SDL_WindowData *keyboard_focus;
uint32_t pointer_enter_serial;
/* Last motion location */
wl_fixed_t sx_w;
wl_fixed_t sy_w;
double dx_frac;
double dy_frac;
struct {
struct xkb_keymap *keymap;
struct xkb_state *state;
} xkb;
/* information about axis events on current frame */
struct {
SDL_bool is_x_discrete;
float x;
SDL_bool is_y_discrete;
float y;
} pointer_curr_axis_info;
SDL_WaylandKeyboardRepeat keyboard_repeat;
};
extern void Wayland_PumpEvents(_THIS);

View file

@ -318,6 +318,7 @@ Wayland_ShowCursor(SDL_Cursor *cursor)
{
SDL_VideoDevice *vd = SDL_GetVideoDevice();
SDL_VideoData *d = vd->driverdata;
struct SDL_WaylandInput *input = d->input;
struct wl_pointer *pointer = d->pointer;
@ -328,7 +329,8 @@ Wayland_ShowCursor(SDL_Cursor *cursor)
{
Wayland_CursorData *data = cursor->driverdata;
wl_pointer_set_cursor (pointer, 0,
wl_pointer_set_cursor (pointer,
input->pointer_enter_serial,
data->surface,
data->hot_x,
data->hot_y);
@ -338,7 +340,8 @@ Wayland_ShowCursor(SDL_Cursor *cursor)
}
else
{
wl_pointer_set_cursor (pointer, 0,
wl_pointer_set_cursor (pointer,
input->pointer_enter_serial,
NULL,
0,
0);