Browse Source

Platform: add clipboard handling to Sdl2 and GlfwApplication.

Text only, SDL3 has support for arbitrary mime types so the API is named
clipboardText() and not just clipboar(). Wanted to add this for
Emscripten as well, but after looking around a bit, I don't think I want
to deal with that until someone actually wants clipboard support
somewhere.
pull/680/head
Vladimír Vondruš 11 months ago
parent
commit
c877983893
  1. 3
      doc/changelog.dox
  2. 6
      src/Magnum/Platform/EmscriptenApplication.h
  3. 8
      src/Magnum/Platform/GlfwApplication.cpp
  4. 23
      src/Magnum/Platform/GlfwApplication.h
  5. 12
      src/Magnum/Platform/Sdl2Application.cpp
  6. 24
      src/Magnum/Platform/Sdl2Application.h
  7. 7
      src/Magnum/Platform/Test/GlfwApplicationTest.cpp
  8. 7
      src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp

3
doc/changelog.dox

@ -382,6 +382,9 @@ See also:
@relativeref{Platform::Sdl2Application,blurEvent()} to @relativeref{Platform::Sdl2Application,blurEvent()} to
@ref Platform::Sdl2Application, @ref Platform::GlfwApplication, @ref Platform::Sdl2Application, @ref Platform::GlfwApplication,
@ref Platform::EmscriptenApplication and @ref Platform::AndroidApplication @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 @subsubsection changelog-latest-new-scenegraph SceneGraph library

6
src/Magnum/Platform/EmscriptenApplication.h

@ -1103,6 +1103,12 @@ class EmscriptenApplication {
*/ */
void setTextInputRect(const Range2Di& rect); 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: private:
/** /**
* @brief Text input event * @brief Text input event

8
src/Magnum/Platform/GlfwApplication.cpp

@ -1122,6 +1122,14 @@ void GlfwApplication::stopTextInput() {
_flags &= ~Flag::TextInputActive; _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 #ifdef MAGNUM_TARGET_GL
GlfwApplication::GLConfiguration::GLConfiguration(): GlfwApplication::GLConfiguration::GLConfiguration():
_colorBufferSize{8, 8, 8, 8}, _depthBufferSize{24}, _stencilBufferSize{0}, _colorBufferSize{8, 8, 8, 8}, _depthBufferSize{24}, _stencilBufferSize{0},

23
src/Magnum/Platform/GlfwApplication.h

@ -925,6 +925,29 @@ class GlfwApplication {
*/ */
void stopTextInput(); 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: private:
/** /**
* @brief Text input event * @brief Text input event

12
src/Magnum/Platform/Sdl2Application.cpp

@ -1454,6 +1454,18 @@ void Sdl2Application::setTextInputRect(const Range2Di& rect) {
SDL_SetTextInputRect(&r); 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) { void Sdl2Application::exitEvent(ExitEvent& event) {
event.setAccepted(); event.setAccepted();
} }

24
src/Magnum/Platform/Sdl2Application.h

@ -1466,6 +1466,30 @@ class Sdl2Application {
*/ */
void setTextInputRect(const Range2Di& rect); 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: private:
/** /**
* @brief Text input event * @brief Text input event

7
src/Magnum/Platform/Test/GlfwApplicationTest.cpp

@ -323,10 +323,15 @@ struct GlfwApplicationTest: Platform::Application {
_redraw = !_redraw; _redraw = !_redraw;
Debug{} << "redrawing" << (_redraw ? "enabled" : "disabled"); Debug{} << "redrawing" << (_redraw ? "enabled" : "disabled");
if(_redraw) redraw(); if(_redraw) redraw();
} else if(event.key() == Key::V) { } else if(event.key() == Key::V && !event.modifiers()) {
_vsync = !_vsync; _vsync = !_vsync;
Debug{} << "vsync" << (_vsync? "on" : "off"); Debug{} << "vsync" << (_vsync? "on" : "off");
setSwapInterval(_vsync ? 1 : 0); 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) { } else if(event.key() == Key::Esc) {
Debug{} << "stopping text input"; Debug{} << "stopping text input";
stopTextInput(); stopTextInput();

7
src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp

@ -408,10 +408,15 @@ struct Sdl2ApplicationTest: Platform::Application {
if(_redraw) redraw(); if(_redraw) redraw();
} }
#ifndef CORRADE_TARGET_EMSCRIPTEN #ifndef CORRADE_TARGET_EMSCRIPTEN
else if(event.key() == Key::V) { else if(event.key() == Key::V && !(event.modifiers() & ~(Modifier::CapsLock|Modifier::NumLock))) {
_vsync = !_vsync; _vsync = !_vsync;
Debug{} << "vsync" << (_vsync? "on" : "off"); Debug{} << "vsync" << (_vsync? "on" : "off");
setSwapInterval(_vsync ? 1 : 0); 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 #endif
else if(event.key() == Key::Esc) { else if(event.key() == Key::Esc) {

Loading…
Cancel
Save