Просмотр исходного кода

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.
Frank Praznik 1 месяц назад
Родитель
Сommit
cc2713c047
2 измененных файлов с 12 добавлено и 5 удалено
  1. 5 0
      src/video/wayland/SDL_waylanddatamanager.c
  2. 7 5
      src/video/wayland/SDL_waylandevents.c

+ 5 - 0
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);
         SDL_free(id);
         if (source_is_external) {
         if (source_is_external) {
             Wayland_data_offer_notify_from_mimes(offer, false);
             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;
         }
         }
     }
     }
 }
 }

+ 7 - 5
src/video/wayland/SDL_waylandevents.c

@@ -3065,12 +3065,14 @@ static void data_device_handle_selection(void *data, struct wl_data_device *wl_d
     SDL_LogTrace(SDL_LOG_CATEGORY_INPUT,
     SDL_LogTrace(SDL_LOG_CATEGORY_INPUT,
                  ". In data_device_listener . data_device_handle_selection on data_offer 0x%08x",
                  ". In data_device_listener . data_device_handle_selection on data_offer 0x%08x",
                  (id ? WAYLAND_wl_proxy_get_id((struct wl_proxy *)id) : -1));
                  (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 = {
 static const struct wl_data_device_listener data_device_listener = {