diff --git a/doc/changelog.dox b/doc/changelog.dox index 624e1fb99..b7f865a69 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -382,6 +382,9 @@ See also: @relativeref{Platform::Sdl2Application,blurEvent()} to @ref Platform::Sdl2Application, @ref Platform::GlfwApplication, @ref Platform::EmscriptenApplication and @ref Platform::AndroidApplication +- Added @relativeref{Platform::Sdl2Application,clipboardText()} and + @relativeref{Platform::Sdl2Application,setClipboardText()} to + @ref Platform::Sdl2Application and @ref Platform::GlfwApplication @subsubsection changelog-latest-new-scenegraph SceneGraph library diff --git a/src/Magnum/Platform/EmscriptenApplication.h b/src/Magnum/Platform/EmscriptenApplication.h index f47af5ac1..ae618c8cc 100644 --- a/src/Magnum/Platform/EmscriptenApplication.h +++ b/src/Magnum/Platform/EmscriptenApplication.h @@ -1103,6 +1103,12 @@ class EmscriptenApplication { */ void setTextInputRect(const Range2Di& rect); + /* Unlike Sdl2Application and GlfwApplication, here's no clipboard + support, because due to security reasons, the browser API is + extremely convoluted: + https://github.com/pthom/hello_imgui/issues/3 + https://github.com/emscripten-core/emscripten/pull/19510 */ + private: /** * @brief Text input event diff --git a/src/Magnum/Platform/GlfwApplication.cpp b/src/Magnum/Platform/GlfwApplication.cpp index afb17e413..9b0357f9d 100644 --- a/src/Magnum/Platform/GlfwApplication.cpp +++ b/src/Magnum/Platform/GlfwApplication.cpp @@ -1122,6 +1122,14 @@ void GlfwApplication::stopTextInput() { _flags &= ~Flag::TextInputActive; } +Containers::StringView GlfwApplication::clipboardText() { + return glfwGetClipboardString(_window); +} + +void GlfwApplication::setClipboardText(const Containers::StringView text) { + glfwSetClipboardString(_window, Containers::String::nullTerminatedView(text).data()); +} + #ifdef MAGNUM_TARGET_GL GlfwApplication::GLConfiguration::GLConfiguration(): _colorBufferSize{8, 8, 8, 8}, _depthBufferSize{24}, _stencilBufferSize{0}, diff --git a/src/Magnum/Platform/GlfwApplication.h b/src/Magnum/Platform/GlfwApplication.h index 256d1fa6d..9fb49d95d 100644 --- a/src/Magnum/Platform/GlfwApplication.h +++ b/src/Magnum/Platform/GlfwApplication.h @@ -925,6 +925,29 @@ class GlfwApplication { */ void stopTextInput(); + /** + * @brief Current clipboard text + * @m_since_latest + * + * The returned view is in UTF-8, is always + * @relativeref{Corrade,Containers::StringViewFlag::NullTerminated} and + * is only guaranteed to be valid until the next call to + * @ref clipboardText() or @ref setClipboardText(). If the clipboard is + * empty or contains non-text data (such as an image), the returned + * view is empty. + */ + Containers::StringView clipboardText(); + + /** + * @brief Set current clipboard text + * @m_since_latest + * + * The @p text is expected to be in UTF-8. If it's not + * @relativeref{Corrade,Containers::StringViewFlag::NullTerminated}, a + * null-terminated copy is made before passing it to GLFW. + */ + void setClipboardText(Containers::StringView text); + private: /** * @brief Text input event diff --git a/src/Magnum/Platform/Sdl2Application.cpp b/src/Magnum/Platform/Sdl2Application.cpp index 7c4214de3..be7d1f11e 100644 --- a/src/Magnum/Platform/Sdl2Application.cpp +++ b/src/Magnum/Platform/Sdl2Application.cpp @@ -1454,6 +1454,18 @@ void Sdl2Application::setTextInputRect(const Range2Di& rect) { SDL_SetTextInputRect(&r); } +#ifndef CORRADE_TARGET_EMSCRIPTEN +Containers::String Sdl2Application::clipboardText() { + return Containers::String{SDL_GetClipboardText(), [](char* const data, std::size_t) { + SDL_free(data); + }}; +} + +void Sdl2Application::setClipboardText(const Containers::StringView text) { + SDL_SetClipboardText(Containers::String::nullTerminatedView(text).data()); +} +#endif + void Sdl2Application::exitEvent(ExitEvent& event) { event.setAccepted(); } diff --git a/src/Magnum/Platform/Sdl2Application.h b/src/Magnum/Platform/Sdl2Application.h index 87276554c..394804960 100644 --- a/src/Magnum/Platform/Sdl2Application.h +++ b/src/Magnum/Platform/Sdl2Application.h @@ -1466,6 +1466,30 @@ class Sdl2Application { */ void setTextInputRect(const Range2Di& rect); + #ifndef CORRADE_TARGET_EMSCRIPTEN + /** + * @brief Current clipboard text + * @m_since_latest + * + * The returned string is in UTF-8. If the clipboard is empty or + * contains non-text data (such as an image), the returned string is + * empty. + * @note Not available on @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten". + */ + Containers::String clipboardText(); + + /** + * @brief Set current clipboard text + * @m_since_latest + * + * The @p text is expected to be in UTF-8. If it's not + * @relativeref{Corrade,Containers::StringViewFlag::NullTerminated}, a + * null-terminated copy is made before passing it to SDL. + * @note Not available on @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten". + */ + void setClipboardText(Containers::StringView text); + #endif + private: /** * @brief Text input event diff --git a/src/Magnum/Platform/Test/GlfwApplicationTest.cpp b/src/Magnum/Platform/Test/GlfwApplicationTest.cpp index b78ae7bc7..c04ce9def 100644 --- a/src/Magnum/Platform/Test/GlfwApplicationTest.cpp +++ b/src/Magnum/Platform/Test/GlfwApplicationTest.cpp @@ -323,10 +323,15 @@ struct GlfwApplicationTest: Platform::Application { _redraw = !_redraw; Debug{} << "redrawing" << (_redraw ? "enabled" : "disabled"); if(_redraw) redraw(); - } else if(event.key() == Key::V) { + } else if(event.key() == Key::V && !event.modifiers()) { _vsync = !_vsync; Debug{} << "vsync" << (_vsync? "on" : "off"); setSwapInterval(_vsync ? 1 : 0); + } else if(event.key() == Key::C && event.modifiers() == Modifier::Ctrl) { + Debug{} << "Setting clipboard contents"; + setClipboardText("this text shouldn't have an exclamation at the end!!"_s.exceptSuffix(2)); + } else if(event.key() == Key::V && event.modifiers() == Modifier::Ctrl) { + Debug{} << "Clipboard contents:" << clipboardText(); } else if(event.key() == Key::Esc) { Debug{} << "stopping text input"; stopTextInput(); diff --git a/src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp b/src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp index abe3aefd4..3ea758f74 100644 --- a/src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp +++ b/src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp @@ -408,10 +408,15 @@ struct Sdl2ApplicationTest: Platform::Application { if(_redraw) redraw(); } #ifndef CORRADE_TARGET_EMSCRIPTEN - else if(event.key() == Key::V) { + else if(event.key() == Key::V && !(event.modifiers() & ~(Modifier::CapsLock|Modifier::NumLock))) { _vsync = !_vsync; Debug{} << "vsync" << (_vsync? "on" : "off"); setSwapInterval(_vsync ? 1 : 0); + } else if(event.key() == Key::C && (event.modifiers() & ~(Modifier::CapsLock|Modifier::NumLock)) == Modifier::Ctrl) { + Debug{} << "Setting clipboard contents"; + setClipboardText("this text shouldn't have an exclamation at the end!!"_s.exceptSuffix(2)); + } else if(event.key() == Key::V && (event.modifiers() & ~(Modifier::CapsLock|Modifier::NumLock)) == Modifier::Ctrl) { + Debug{} << "Clipboard contents:" << clipboardText(); } #endif else if(event.key() == Key::Esc) {