diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index 0cbc0076d9..87b3c05863 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -675,12 +675,9 @@ static void pointer_handle_button_common(struct SDL_WaylandInput *input, uint32_ } if (state) { - input->button_press_serial = serial; + Wayland_UpdateImplicitGrabSerial(input, serial); } - Wayland_data_device_set_serial(input->data_device, serial); - Wayland_primary_selection_device_set_serial(input->primary_selection_device, serial); - SDL_SendMouseButton(Wayland_GetPointerTimestamp(input, time), window->sdlwindow, 0, state ? SDL_PRESSED : SDL_RELEASED, sdl_button); } @@ -926,7 +923,7 @@ static void touch_handler_down(void *data, struct wl_touch *touch, uint32_t seri } touch_add(id, fx, fy, surface); - input->touch_down_serial = serial; + Wayland_UpdateImplicitGrabSerial(input, serial); window_data = (SDL_WindowData *)wl_surface_get_user_data(surface); if (window_data) { @@ -1486,7 +1483,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard, SDL_bool handled_by_ime = SDL_FALSE; const Uint64 timestamp_raw_ns = Wayland_GetKeyboardTimestampRaw(input, time); - input->key_serial = serial; + Wayland_UpdateImplicitGrabSerial(input, serial); if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { has_text = keyboard_input_get_text(text, input, key, SDL_PRESSED, &handled_by_ime); @@ -1509,9 +1506,6 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard, SDL_SendKeyboardKeyIgnoreModifiers(Wayland_GetKeyboardTimestamp(input, time), state == WL_KEYBOARD_KEY_STATE_PRESSED ? SDL_PRESSED : SDL_RELEASED, scancode); } - Wayland_data_device_set_serial(input->data_device, serial); - Wayland_primary_selection_device_set_serial(input->primary_selection_device, serial); - if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { if (has_text && !(SDL_GetModState() & SDL_KMOD_CTRL)) { if (!handled_by_ime) { @@ -2397,7 +2391,7 @@ static void tablet_tool_handle_down(void *data, struct zwp_tablet_tool_v2 *tool, struct SDL_WaylandTabletInput *input = data; SDL_WindowData *window = input->tool_focus; input->is_down = SDL_TRUE; - input->press_serial = serial; + Wayland_UpdateImplicitGrabSerial(input->sdlWaylandInput, serial); if (window == NULL) { /* tablet_tool_handle_proximity_out gets called when moving over the libdecoration csd. * that sets input->tool_focus (window) to NULL, but handle_{down,up} events are still @@ -2458,14 +2452,14 @@ static void tablet_tool_handle_tilt(void *data, struct zwp_tablet_tool_v2 *tool, static void tablet_tool_handle_button(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t serial, uint32_t button, uint32_t state) { - struct SDL_WaylandTabletInput *input = data; + struct SDL_WaylandTabletInput *input = (struct SDL_WaylandTabletInput*)data; if (input->is_down) { tablet_tool_handle_up(data, tool); input->is_down = SDL_TRUE; } - input->press_serial = serial; + Wayland_UpdateImplicitGrabSerial(input->sdlWaylandInput, serial); switch (button) { /* see %{_includedir}/linux/input-event-codes.h */ @@ -2613,7 +2607,8 @@ void Wayland_input_add_tablet(struct SDL_WaylandInput *input, struct SDL_Wayland input->tablet = tablet_input; - tablet_input->seat = (struct SDL_WaylandTabletSeat *)zwp_tablet_manager_v2_get_tablet_seat((struct zwp_tablet_manager_v2 *)tablet_manager, input->seat); + tablet_input->sdlWaylandInput = input; + tablet_input->seat = zwp_tablet_manager_v2_get_tablet_seat((struct zwp_tablet_manager_v2 *)tablet_manager, input->seat); tablet_input->tablets = tablet_object_list_new_node(NULL); tablet_input->tools = tablet_object_list_new_node(NULL); @@ -2629,7 +2624,7 @@ void Wayland_input_destroy_tablet(struct SDL_WaylandInput *input) tablet_object_list_destroy(input->tablet->tools, TABLET_OBJECT_LIST_DELETER(zwp_tablet_tool_v2_destroy)); tablet_object_list_destroy(input->tablet->tablets, TABLET_OBJECT_LIST_DELETER(zwp_tablet_v2_destroy)); - zwp_tablet_seat_v2_destroy((struct zwp_tablet_seat_v2 *)input->tablet->seat); + zwp_tablet_seat_v2_destroy(input->tablet->seat); SDL_free(input->tablet); input->tablet = NULL; @@ -3084,21 +3079,13 @@ int Wayland_input_ungrab_keyboard(SDL_Window *window) return 0; } -Uint32 Wayland_GetLastImplicitGrabSerial(struct SDL_WaylandInput *input) +void Wayland_UpdateImplicitGrabSerial(struct SDL_WaylandInput *input, Uint32 serial) { - Uint32 serial = input->key_serial; - - if (serial < input->button_press_serial) { - serial = input->button_press_serial; + if (serial > input->last_implicit_grab_serial) { + input->last_implicit_grab_serial = serial; + Wayland_data_device_set_serial(input->data_device, serial); + Wayland_primary_selection_device_set_serial(input->primary_selection_device, serial); } - if (serial < input->touch_down_serial) { - serial = input->touch_down_serial; - } - if (input->tablet && serial < input->tablet->press_serial) { - serial = input->tablet->press_serial; - } - - return serial; } #endif /* SDL_VIDEO_DRIVER_WAYLAND */ diff --git a/src/video/wayland/SDL_waylandevents_c.h b/src/video/wayland/SDL_waylandevents_c.h index 4c36ab8bff..0a5189324b 100644 --- a/src/video/wayland/SDL_waylandevents_c.h +++ b/src/video/wayland/SDL_waylandevents_c.h @@ -48,7 +48,8 @@ struct SDL_WaylandTabletObjectListNode struct SDL_WaylandTabletInput { - struct SDL_WaylandTabletSeat *seat; + struct SDL_WaylandInput *sdlWaylandInput; + struct zwp_tablet_seat_v2 *seat; struct SDL_WaylandTabletObjectListNode *tablets; struct SDL_WaylandTabletObjectListNode *tools; @@ -56,7 +57,6 @@ struct SDL_WaylandTabletInput SDL_WindowData *tool_focus; uint32_t tool_prox_serial; - uint32_t press_serial; /* Last motion location */ wl_fixed_t sx_w; @@ -113,10 +113,8 @@ struct SDL_WaylandInput uint32_t buttons_pressed; - /* Implicit grab serial events */ - Uint32 key_serial; - Uint32 button_press_serial; - Uint32 touch_down_serial; + /* The serial of the last implicit grab event for window activation and selection data. */ + Uint32 last_implicit_grab_serial; struct { @@ -204,6 +202,13 @@ extern void Wayland_input_destroy_tablet(struct SDL_WaylandInput *input); extern void Wayland_RegisterTimestampListeners(struct SDL_WaylandInput *input); -extern Uint32 Wayland_GetLastImplicitGrabSerial(struct SDL_WaylandInput *input); +/* The implicit grab serial needs to be updated on: + * - Keyboard key down/up + * - Mouse button down + * - Touch event down + * - Tablet tool down + * - Tablet tool button down/up + */ +extern void Wayland_UpdateImplicitGrabSerial(struct SDL_WaylandInput *input, Uint32 serial); #endif /* SDL_waylandevents_h_ */ diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index 4193dbce8d..dbbf68c30b 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -1252,6 +1252,7 @@ static void handle_preferred_fractional_scale(void *data, struct wp_fractional_s { const float factor = scale / 120.; /* 120 is a magic number defined in the spec as a common denominator */ Wayland_HandlePreferredScaleChanged(data, factor); + SDL_Log("Scale reported"); } static const struct wp_fractional_scale_v1_listener fractional_scale_listener = { @@ -1734,7 +1735,7 @@ void Wayland_RaiseWindow(SDL_VideoDevice *_this, SDL_Window *window) */ if (input) { seat = input->seat; - serial = Wayland_GetLastImplicitGrabSerial(input); + serial = input->last_implicit_grab_serial; } Wayland_activate_window(_this->driverdata,