From cdbff3c043bb5863f487868b74891d558d7c38cd Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Tue, 11 Nov 2025 18:48:08 +0300 Subject: [PATCH] Started work on getting emscripten clipboard working with rich text --- .../emscripten_browser_clipboard.h | 16 +++++++------- src/InputManager.cpp | 22 ++++++++++++++++--- src/InputManager.hpp | 2 +- src/main.cpp | 1 + 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/include/EmscriptenHelpers/emscripten_browser_clipboard.h b/include/EmscriptenHelpers/emscripten_browser_clipboard.h index 77c42df..8674121 100644 --- a/include/EmscriptenHelpers/emscripten_browser_clipboard.h +++ b/include/EmscriptenHelpers/emscripten_browser_clipboard.h @@ -28,22 +28,22 @@ inline void copy(std::string const &content); namespace detail { -EM_JS_INLINE(void, paste_js, (paste_handler callback, void *callback_data), { +EM_JS_INLINE(void, paste_js, (paste_handler callback, const char* mimeType, void *callback_data), { /// Register the given callback to handle paste events. Callback data pointer is passed through to the callback. /// Paste handler callback signature is: /// void my_handler(std::string const &paste_data, void *callback_data = nullptr); document.addEventListener('paste', (event) => { - Module["ccall"]('emscripten_browser_clipboard_detail_paste_return', 'number', ['string', 'number', 'number'], [event.clipboardData.getData('text/plain'), callback, callback_data]); + Module["ccall"]('emscripten_browser_clipboard_detail_paste_return', 'number', ['string', 'number', 'number'], [event.clipboardData.getData(mimeType), callback, callback_data]); }); }); -EM_JS_INLINE(void, copy_js, (copy_handler callback, void *callback_data), { +EM_JS_INLINE(void, copy_js, (copy_handler callback, const char* mimeType, void *callback_data), { /// Register the given callback to handle copy events. Callback data pointer is passed through to the callback. /// Copy handler callback signature is: /// char const *my_handler(void *callback_data = nullptr); document.addEventListener('copy', (event) => { const content_ptr = Module["ccall"]('emscripten_browser_clipboard_detail_copy_return', 'number', ['number', 'number'], [callback, callback_data]); - event.clipboardData.setData('text/plain', UTF8ToString(content_ptr)); + event.clipboardData.setData(mimeType, UTF8ToString(content_ptr)); event.preventDefault(); }); }); @@ -55,14 +55,14 @@ EM_JS_INLINE(void, copy_async_js, (char const *content_ptr), { } // namespace detail -inline void paste(paste_handler callback, void *callback_data) { +inline void paste(paste_handler callback, const char* mimeType, void *callback_data) { /// C++ wrapper for javascript paste call - detail::paste_js(callback, callback_data); + detail::paste_js(callback, mimeType, callback_data); } -inline void copy(copy_handler callback, void *callback_data) { +inline void copy(copy_handler callback, const char* mimeType, void *callback_data) { /// C++ wrapper for javascript copy call - detail::copy_js(callback, callback_data); + detail::copy_js(callback, mimeType, callback_data); } inline void copy(std::string const &content) { diff --git a/src/InputManager.cpp b/src/InputManager.cpp index 4e176d9..357558c 100644 --- a/src/InputManager.cpp +++ b/src/InputManager.cpp @@ -62,8 +62,14 @@ InputManager::InputManager() { emscripten_browser_clipboard::paste([](std::string&& pasteData, void* callbackData){ InputManager* inMan = (InputManager*)callbackData; inMan->clipboardPasteEventHappened = true; - inMan->clipboardPasteEventData = pasteData; - }, this); + inMan->clipboardPasteEventData["text/plain"] = pasteData; + }, "text/plain", this); + + emscripten_browser_clipboard::paste([](std::string&& pasteData, void* callbackData){ + InputManager* inMan = (InputManager*)callbackData; + inMan->clipboardPasteEventHappened = true; + inMan->clipboardPasteEventData[inMan->get_infpnt_richtext_mimetype()] = pasteData; + }, get_infpnt_richtext_mimetype().c_str(), this); #endif keyAssignments = defaultKeyAssignments; @@ -109,7 +115,10 @@ bool InputManager::get_clipboard_paste_happened() { std::string InputManager::get_clipboard_str() { #ifdef __EMSCRIPTEN__ - return clipboardPasteEventData; + auto it = clipboardPasteEventData.find("text/plain"); + if(it == clipboardPasteEventData.end()) + return ""; + return it->second; #else char* data = SDL_GetClipboardText(); std::string toRet(data); @@ -119,11 +128,18 @@ std::string InputManager::get_clipboard_str() { } std::string InputManager::get_clipboard_data_for_mimetype(const std::string& mimeType) { +#ifdef __EMSCRIPTEN__ + auto it = clipboardPasteEventData.find(mimeType); + if(it == clipboardPasteEventData.end()) + return ""; + return it->second; +#else size_t datSize = 0; void* dat = SDL_GetClipboardData(mimeType.c_str(), &datSize); if(!dat) return ""; return std::string(static_cast(dat), datSize); +#endif } void InputManager::set_clipboard_str(std::string_view s) { diff --git a/src/InputManager.hpp b/src/InputManager.hpp index 8b821f8..550f327 100644 --- a/src/InputManager.hpp +++ b/src/InputManager.hpp @@ -207,7 +207,7 @@ struct InputManager { #ifdef __EMSCRIPTEN__ bool clipboardPasteEventHappened = false; - std::string clipboardPasteEventData; + std::unordered_map clipboardPasteEventData; #endif std::string key_assignment_to_str(const Vector2ui32& k); diff --git a/src/main.cpp b/src/main.cpp index 59cd2e5..8ad78a4 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -393,6 +393,7 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) { udata_setCommonData((void *) icudt.data(), &uerr); if (U_FAILURE(uerr)) { char* errorName = const_cast(u_errorName(uerr)); + std::cout << "Failed to load icudt77l.dat" << std::endl; std::cout << errorName << std::endl; }