From 01997ebebde6a57af1506956764732554c2b85b0 Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Tue, 21 Jul 2026 19:51:04 -0400
Subject: [PATCH] wayland: Don't clear the clipboard when a nil selection is
ignored
If the previous selection offering was recursive, a nil selection should be ignored, or clearing the clipboard may clear the backing memory of the client's selection offering as well.
(cherry picked from commit cc2713c0477118d3074b625abe8df7de7118fe2e)
---
src/video/wayland/SDL_waylanddatamanager.c | 5 +++++
src/video/wayland/SDL_waylandevents.c | 12 +++++++-----
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/src/video/wayland/SDL_waylanddatamanager.c b/src/video/wayland/SDL_waylanddatamanager.c
index 4501efaa1a606..717611bfb4922 100644
--- a/src/video/wayland/SDL_waylanddatamanager.c
+++ b/src/video/wayland/SDL_waylanddatamanager.c
@@ -422,6 +422,11 @@ static void offer_source_done_handler(void *data, struct wl_callback *callback,
SDL_free(id);
if (source_is_external) {
Wayland_data_offer_notify_from_mimes(offer, false);
+ } else {
+ // Recursive data offer; just destroy it.
+ SDL_WaylandDataDevice *data_device = offer->data_device;
+ Wayland_data_offer_destroy(offer);
+ data_device->selection_offer = NULL;
}
}
}
diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c
index 231fd70dbb07a..d6cd31d3c95d7 100644
--- a/src/video/wayland/SDL_waylandevents.c
+++ b/src/video/wayland/SDL_waylandevents.c
@@ -2990,12 +2990,14 @@ static void data_device_handle_selection(void *data, struct wl_data_device *wl_d
SDL_LogTrace(SDL_LOG_CATEGORY_INPUT,
". In data_device_listener . data_device_handle_selection on data_offer 0x%08x",
(id ? WAYLAND_wl_proxy_get_id((struct wl_proxy *)id) : -1));
- if (data_device->selection_offer != offer) {
- Wayland_data_offer_destroy(data_device->selection_offer);
- data_device->selection_offer = offer;
- }
- Wayland_data_offer_notify_from_mimes(offer, true);
+ // Don't notify when clearing the old selection offer if doing so will inadvertently clear the selection source.
+ const bool notify = offer || (!offer && data_device->selection_offer && (!data_device->selection_offer->callback || !data_device->selection_source));
+ Wayland_data_offer_destroy(data_device->selection_offer);
+ data_device->selection_offer = offer;
+ if (notify) {
+ Wayland_data_offer_notify_from_mimes(offer, true);
+ }
}
static const struct wl_data_device_listener data_device_listener = {