diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index 2b547faf6..14a28430c 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -545,7 +545,7 @@ pointer_handle_button_common(struct SDL_WaylandInput *input, uint32_t serial, enum wl_pointer_button_state state = state_w; uint32_t sdl_button; - if (input->pointer_focus) { + if (window) { switch (button) { case BTN_LEFT: sdl_button = SDL_BUTTON_LEFT; @@ -569,6 +569,23 @@ pointer_handle_button_common(struct SDL_WaylandInput *input, uint32_t serial, return; } + /* Wayland won't let you "capture" the mouse, but it will + automatically track the mouse outside the window if you + drag outside of it, until you let go of all buttons (even + if you add or remove presses outside the window, as long + as any button is still down, the capture remains) */ + if (state) { /* update our mask of currently-pressed buttons */ + input->buttons_pressed |= SDL_BUTTON(sdl_button); + } else { + input->buttons_pressed &= ~(SDL_BUTTON(sdl_button)); + } + + if (input->buttons_pressed != 0) { + window->sdlwindow->flags |= SDL_WINDOW_MOUSE_CAPTURE; + } else { + window->sdlwindow->flags &= ~SDL_WINDOW_MOUSE_CAPTURE; + } + Wayland_data_device_set_serial(input->data_device, serial); SDL_SendMouseButton(window->sdlwindow, 0, @@ -913,11 +930,17 @@ keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface) { struct SDL_WaylandInput *input = data; + SDL_WindowData *window; if (!surface || !SDL_WAYLAND_own_surface(surface)) { return; } + window = wl_surface_get_user_data(surface); + if (window) { + window->sdlwindow->flags &= ~SDL_WINDOW_MOUSE_CAPTURE; + } + /* Stop key repeat before clearing keyboard focus */ keyboard_repeat_clear(&input->keyboard_repeat); diff --git a/src/video/wayland/SDL_waylandevents_c.h b/src/video/wayland/SDL_waylandevents_c.h index 59dc0c8af..9bcb2c9b1 100644 --- a/src/video/wayland/SDL_waylandevents_c.h +++ b/src/video/wayland/SDL_waylandevents_c.h @@ -88,6 +88,8 @@ struct SDL_WaylandInput { wl_fixed_t sx_w; wl_fixed_t sy_w; + uint32_t buttons_pressed; + double dx_frac; double dy_frac;