From 9c7c11f259ded394aaa71383d2d6cd185a239d94 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Wed, 5 Mar 2025 21:47:41 -0500 Subject: [PATCH] wayland: Roundtrip when receiving data offers Otherwise, the receive operation might not have completed, resulting in there being no data to read. --- src/video/wayland/SDL_waylanddatamanager.c | 22 ++++++++++++++-------- src/video/wayland/SDL_waylandsym.h | 1 + 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/video/wayland/SDL_waylanddatamanager.c b/src/video/wayland/SDL_waylanddatamanager.c index 6f5b32bbb3..b8f4078752 100644 --- a/src/video/wayland/SDL_waylanddatamanager.c +++ b/src/video/wayland/SDL_waylanddatamanager.c @@ -370,13 +370,16 @@ void *Wayland_data_offer_receive(SDL_WaylandDataOffer *offer, } else if (pipe2(pipefd, O_CLOEXEC | O_NONBLOCK) == -1) { SDL_SetError("Could not read pipe"); } else { + struct wl_event_queue *queue = WAYLAND_wl_display_create_queue(data_device->video_data->display); + WAYLAND_wl_proxy_set_queue((struct wl_proxy *)offer->offer, queue); + wl_data_offer_receive(offer->offer, mime_type, pipefd[1]); - - // TODO: Needs pump and flush? - WAYLAND_wl_display_flush(data_device->video_data->display); - close(pipefd[1]); + WAYLAND_wl_display_roundtrip_queue(data_device->video_data->display, queue); + WAYLAND_wl_proxy_set_queue((struct wl_proxy *)offer->offer, NULL); + WAYLAND_wl_event_queue_destroy(queue); + while (read_pipe(pipefd[0], &buffer, length) > 0) { } close(pipefd[0]); @@ -406,13 +409,16 @@ void *Wayland_primary_selection_offer_receive(SDL_WaylandPrimarySelectionOffer * } else if (pipe2(pipefd, O_CLOEXEC | O_NONBLOCK) == -1) { SDL_SetError("Could not read pipe"); } else { + struct wl_event_queue *queue = WAYLAND_wl_display_create_queue(primary_selection_device->video_data->display); + WAYLAND_wl_proxy_set_queue((struct wl_proxy *)offer->offer, queue); + zwp_primary_selection_offer_v1_receive(offer->offer, mime_type, pipefd[1]); - - // TODO: Needs pump and flush? - WAYLAND_wl_display_flush(primary_selection_device->video_data->display); - close(pipefd[1]); + WAYLAND_wl_display_roundtrip_queue(primary_selection_device->video_data->display, queue); + WAYLAND_wl_proxy_set_queue((struct wl_proxy *)offer->offer, NULL); + WAYLAND_wl_event_queue_destroy(queue); + while (read_pipe(pipefd[0], &buffer, length) > 0) { } close(pipefd[0]); diff --git a/src/video/wayland/SDL_waylandsym.h b/src/video/wayland/SDL_waylandsym.h index 846c876a87..a21659539c 100644 --- a/src/video/wayland/SDL_waylandsym.h +++ b/src/video/wayland/SDL_waylandsym.h @@ -65,6 +65,7 @@ SDL_WAYLAND_SYM(void, wl_display_cancel_read, (struct wl_display *)) SDL_WAYLAND_SYM(int, wl_display_get_error, (struct wl_display *)) SDL_WAYLAND_SYM(int, wl_display_flush, (struct wl_display *)) SDL_WAYLAND_SYM(int, wl_display_roundtrip, (struct wl_display *)) +SDL_WAYLAND_SYM(int, wl_display_roundtrip_queue, (struct wl_display *, struct wl_event_queue *)) SDL_WAYLAND_SYM(struct wl_event_queue *, wl_display_create_queue, (struct wl_display *)) SDL_WAYLAND_SYM(void, wl_event_queue_destroy, (struct wl_event_queue *)) SDL_WAYLAND_SYM(void, wl_log_set_handler_client, (wl_log_func_t))