From 9f68ae4f03892ff540129b88b64aaf3d33e893dc Mon Sep 17 00:00:00 2001 From: akallabeth Date: Mon, 3 Feb 2025 14:37:10 +0100 Subject: [PATCH] update clipboard on sdl thread --- client/SDL/SDL3/sdl_clip.cpp | 40 ++++++++++++++++++++++++----------- client/SDL/SDL3/sdl_clip.hpp | 1 + client/SDL/SDL3/sdl_utils.cpp | 1 + 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/client/SDL/SDL3/sdl_clip.cpp b/client/SDL/SDL3/sdl_clip.cpp index 28988f4d3..9a11a1b11 100644 --- a/client/SDL/SDL3/sdl_clip.cpp +++ b/client/SDL/SDL3/sdl_clip.cpp @@ -159,7 +159,15 @@ BOOL sdlClip::uninit(CliprdrClientContext* clip) bool sdlClip::handle_update(const SDL_ClipboardEvent& ev) { if (!_ctx || !_sync || ev.owner) + { + if (ev.owner) + { + return SDL_SetClipboardData(sdlClip::ClipDataCb, sdlClip::ClipCleanCb, this, + ev.mime_types, + WINPR_ASSERTING_INT_CAST(size_t, ev.num_mime_types)); + } return true; + } clearServerFormats(); @@ -273,8 +281,7 @@ UINT sdlClip::MonitorReady(CliprdrClientContext* context, const CLIPRDR_MONITOR_ return ret; clipboard->_sync = true; - SDL_ClipboardEvent ev = { SDL_EVENT_CLIPBOARD_UPDATE, 0, 0, false, 0, nullptr }; - if (!clipboard->handle_update(ev)) + if (!sdl_push_user_event(SDL_EVENT_CLIPBOARD_UPDATE)) return ERROR_INTERNAL_ERROR; return CHANNEL_RC_OK; @@ -475,29 +482,36 @@ UINT sdlClip::ReceiveServerFormatList(CliprdrClientContext* context, } } - std::vector mimetypes; + clipboard->_current_mimetypes.clear(); if (text) { - mimetypes.insert(mimetypes.end(), s_mime_text().begin(), s_mime_text().end()); + clipboard->_current_mimetypes.insert(clipboard->_current_mimetypes.end(), + s_mime_text().begin(), s_mime_text().end()); } if (image) { - mimetypes.insert(mimetypes.end(), s_mime_bitmap().begin(), s_mime_bitmap().end()); - mimetypes.insert(mimetypes.end(), s_mime_image().begin(), s_mime_image().end()); + clipboard->_current_mimetypes.insert(clipboard->_current_mimetypes.end(), + s_mime_bitmap().begin(), s_mime_bitmap().end()); + clipboard->_current_mimetypes.insert(clipboard->_current_mimetypes.end(), + s_mime_image().begin(), s_mime_image().end()); } if (html) { - mimetypes.push_back(s_mime_html); + clipboard->_current_mimetypes.push_back(s_mime_html); } if (file) { - mimetypes.push_back(s_mime_uri_list); - mimetypes.push_back(s_mime_gnome_copied_files); - mimetypes.push_back(s_mime_mate_copied_files); + clipboard->_current_mimetypes.push_back(s_mime_uri_list); + clipboard->_current_mimetypes.push_back(s_mime_gnome_copied_files); + clipboard->_current_mimetypes.push_back(s_mime_mate_copied_files); } - const bool rc = SDL_SetClipboardData(sdlClip::ClipDataCb, sdlClip::ClipCleanCb, clipboard, - mimetypes.data(), mimetypes.size()); + SDL_Event ev = { SDL_EVENT_CLIPBOARD_UPDATE }; + ev.clipboard.owner = true; + ev.clipboard.num_mime_types = + WINPR_ASSERTING_INT_CAST(Sint32, clipboard->_current_mimetypes.size()); + ev.clipboard.mime_types = clipboard->_current_mimetypes.data(); + auto rc = (SDL_PushEvent(&ev) == 1); return clipboard->SendFormatListResponse(rc); } @@ -741,6 +755,8 @@ const void* sdlClip::ClipDataCb(void* userdata, const char* mime_type, size_t* s } uint32_t formatID = clip->serverIdForMime(mime_type); + WLog_Print(clip->_log, WLOG_INFO, "requesting format %s [0x%08" PRIx32 "]", mime_type, + formatID); if (clip->SendDataRequest(formatID, mime_type)) return nullptr; } diff --git a/client/SDL/SDL3/sdl_clip.hpp b/client/SDL/SDL3/sdl_clip.hpp index cc59f2dee..dc18b3ded 100644 --- a/client/SDL/SDL3/sdl_clip.hpp +++ b/client/SDL/SDL3/sdl_clip.hpp @@ -153,4 +153,5 @@ class sdlClip std::shared_ptr ptr; }; std::map _cache_data; + std::vector _current_mimetypes; }; diff --git a/client/SDL/SDL3/sdl_utils.cpp b/client/SDL/SDL3/sdl_utils.cpp index 25c568edc..62a8d99b0 100644 --- a/client/SDL/SDL3/sdl_utils.cpp +++ b/client/SDL/SDL3/sdl_utils.cpp @@ -270,6 +270,7 @@ BOOL sdl_push_user_event(Uint32 type, ...) case SDL_EVENT_USER_QUIT: case SDL_EVENT_USER_POINTER_NULL: case SDL_EVENT_USER_POINTER_DEFAULT: + case SDL_EVENT_CLIPBOARD_UPDATE: break; default: va_end(ap);