diff --git a/include/EmscriptenHelpers/emscripten_browser_clipboard.h b/include/EmscriptenHelpers/emscripten_browser_clipboard.h index 460e6b4..50e0560 100644 --- a/include/EmscriptenHelpers/emscripten_browser_clipboard.h +++ b/include/EmscriptenHelpers/emscripten_browser_clipboard.h @@ -20,7 +20,8 @@ namespace emscripten_browser_clipboard { using paste_handler = void(*)(std::string&&, void*); using copy_handler = char const*(*)(void*); -inline void paste(paste_handler callback, void *callback_data = nullptr); +inline void paste_event(paste_handler callback, void *callback_data = nullptr); +inline void paste_async(paste_handler callback, void *callback_data = nullptr); inline void copy(copy_handler callback, void *callback_data = nullptr); inline void copy(std::string const &content); @@ -28,7 +29,13 @@ 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_event_js, (paste_handler callback, void *callback_data), { + document.addEventListener('paste', (event) => { + Module["ccall"]('emscripten_browser_clipboard_detail_paste_return', 'number', ['string', 'number', 'number'], [event.clipboardData.getData('text/plain'), callback, callback_data]); + }); +}); + +EM_JS_INLINE(void, paste_async_js, (paste_handler callback, 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); @@ -59,9 +66,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_event(paste_handler callback, void *callback_data) { /// C++ wrapper for javascript paste call - detail::paste_js(callback, callback_data); + detail::paste_event_js(callback, callback_data); +} + +inline void paste_async(paste_handler callback, void *callback_data) { + /// C++ wrapper for javascript paste call + detail::paste_async_js(callback, callback_data); } inline void copy(copy_handler callback, void *callback_data) { diff --git a/src/InputManager.cpp b/src/InputManager.cpp index cdd9f1f..76281b0 100644 --- a/src/InputManager.cpp +++ b/src/InputManager.cpp @@ -47,6 +47,24 @@ InputManager::InputManager() { defaultKeyAssignments[{0, SDLK_F2}] = KEY_SHOW_PLAYER_LIST; defaultKeyAssignments[{0, SDLK_SPACE}] = KEY_HOLD_TO_PAN; +#ifdef __EMSCRIPTEN__ + // Without this, SDL eats the CTRL-V event that initiates the paste event + // https://github.com/pthom/hello_imgui/issues/3#issuecomment-1564536870 + EM_ASM({ + window.addEventListener('keydown', function(event) { + if((event.ctrlKey || event.metaKey) && (event.key == 'v' || event.code == 'KeyV')) { + if(Module["ccall"]('is_text_input_happening', 'number', [], []) === 1) + event.stopImmediatePropagation(); + } + }, true); + }); + emscripten_browser_clipboard::paste_event([](std::string&& pasteData, void* callbackData){ + InputManager* inMan = (InputManager*)callbackData; + inMan->text.isNextPasteRich = true; + std::string pData = pasteData; + inMan->process_text_paste(pData); + }, this); +#endif keyAssignments = defaultKeyAssignments; } @@ -357,7 +375,7 @@ void InputManager::backend_key_down_update(const SDL_KeyboardEvent& e) { void InputManager::call_text_paste(bool isRichTextPaste) { text.isNextPasteRich = isRichTextPaste; #ifdef __EMSCRIPTEN__ - emscripten_browser_clipboard::paste([](std::string&& pasteData, void* callbackData){ + emscripten_browser_clipboard::paste_async([](std::string&& pasteData, void* callbackData){ InputManager* inMan = (InputManager*)callbackData; std::string pData = pasteData; inMan->process_text_paste(pData); @@ -513,8 +531,6 @@ void InputManager::frame_reset(const Vector2i& windowSize) { hideCursor = false; #ifdef __EMSCRIPTEN__ - clipboardPasteEventHappened = false; - clipboardPasteEventData.clear(); isAcceptingInputEmscripten = text.acceptingInput ? 1 : 0; #endif }