wayland: Use the implicit grab serial for setting the clipboard/primary selection data

Use the implicit grab serial, which includes keyboard key, mouse button, touch, and tablet tool events, for setting the clipboard and primary selection data, as these are all considered valid originating event serials.
This commit is contained in:
Frank Praznik 2023-07-06 12:43:24 -04:00
parent badb7f1e8b
commit d28e9960ce
3 changed files with 28 additions and 35 deletions

View File

@ -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 */

View File

@ -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_ */

View File

@ -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,