From 384fd5c36330c14176ab6ae2df46a4f34493e31e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 16 Jul 2019 14:57:44 +0200 Subject: [PATCH] Platform: fix EmscriptenApp::setContainerCssClass() to fire viewport event. The code was taken straight from Sdl2Application where it assumed the main render loop polls for canvas size changes and so it would pick it up automagically. Not the case here, so the viewport event was never fired after this. --- src/Magnum/Platform/EmscriptenApplication.cpp | 38 ++++++++++++------- src/Magnum/Platform/EmscriptenApplication.h | 15 ++++++-- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/Magnum/Platform/EmscriptenApplication.cpp b/src/Magnum/Platform/EmscriptenApplication.cpp index cefbc8c5f..f38e6525d 100644 --- a/src/Magnum/Platform/EmscriptenApplication.cpp +++ b/src/Magnum/Platform/EmscriptenApplication.cpp @@ -389,12 +389,35 @@ void EmscriptenApplication::setContainerCssClass(const std::string& cssClass) { #pragma GCC diagnostic ignored "-Wdollar-in-identifier-extension" EM_ASM_({document.getElementById('container').className = AsciiToString($0);}, cssClass.data()); #pragma GCC diagnostic pop + + /* Trigger a potential viewport event -- we don't poll the canvas size like + Sdl2Application does, so it needs to be done explicitly */ + handleCanvasResize(nullptr); } void EmscriptenApplication::swapBuffers() { emscripten_webgl_commit_frame(); } +/* Called from window resize event but also explicitly from + setContainerCssClass() */ +void EmscriptenApplication::handleCanvasResize(const EmscriptenUiEvent* event) { + /* See windowSize() for why we hardcode "#canvas" here */ + const Vector2i canvasSize{windowSize()}; + if(canvasSize != _lastKnownCanvasSize) { + _lastKnownCanvasSize = canvasSize; + const Vector2i size = canvasSize*_dpiScaling*_devicePixelRatio; + emscripten_set_canvas_element_size("#canvas", size.x(), size.y()); + ViewportEvent e{event, canvasSize, + #ifdef MAGNUM_TARGET_GL + framebufferSize(), + #endif + _dpiScaling, _devicePixelRatio}; + viewportEvent(e); + _flags |= Flag::Redraw; + } +} + void EmscriptenApplication::setupCallbacks(bool resizable) { /* Since 1.38.17 all emscripten_set_*_callback() are macros. Play it safe and wrap all lambdas in () to avoid the preprocessor getting upset when @@ -413,20 +436,7 @@ void EmscriptenApplication::setupCallbacks(bool resizable) { #endif auto cb = [](int, const EmscriptenUiEvent* event, void* userData) -> Int { EmscriptenApplication& app = *static_cast(userData); - /* See windowSize() for why we hardcode "#canvas" here */ - const Vector2i canvasSize{app.windowSize()}; - if(canvasSize != app._lastKnownCanvasSize) { - app._lastKnownCanvasSize = canvasSize; - const Vector2i size = canvasSize*app._dpiScaling*app._devicePixelRatio; - emscripten_set_canvas_element_size("#canvas", size.x(), size.y()); - ViewportEvent e{*event, canvasSize, - #ifdef MAGNUM_TARGET_GL - app.framebufferSize(), - #endif - app._dpiScaling, app._devicePixelRatio}; - app.viewportEvent(e); - app._flags |= Flag::Redraw; - } + app.handleCanvasResize(event); return false; /** @todo what does ignoring a resize event mean? */ }; emscripten_set_resize_callback(target, this, false, cb); diff --git a/src/Magnum/Platform/EmscriptenApplication.h b/src/Magnum/Platform/EmscriptenApplication.h index 9aa595c23..4f2fc142e 100644 --- a/src/Magnum/Platform/EmscriptenApplication.h +++ b/src/Magnum/Platform/EmscriptenApplication.h @@ -624,6 +624,7 @@ class EmscriptenApplication { CORRADE_ENUMSET_FRIEND_OPERATORS(Flags) + void handleCanvasResize(const EmscriptenUiEvent* event); /* Sorry, but can't use Configuration::WindowFlags here :( */ void setupCallbacks(bool resizable); void setupAnimationFrame(bool ForceAnimationFrame); @@ -1050,13 +1051,19 @@ class EmscriptenApplication::ViewportEvent { */ Vector2 devicePixelRatio() const { return _devicePixelRatio; } - /** @brief Underlying Emscripten event */ - const EmscriptenUiEvent& event() const { return _event; } + /** + * @brief Underlying Emscripten event + * + * If the viewport event doesn't come from a browser event (for example + * when the canvas was resized programatically and not as a consequence + * of window size change), the function returns @cpp nullptr @ce. + */ + const EmscriptenUiEvent* event() const { return _event; } private: friend EmscriptenApplication; - explicit ViewportEvent(const EmscriptenUiEvent& event, + explicit ViewportEvent(const EmscriptenUiEvent* event, const Vector2i& windowSize, #ifdef MAGNUM_TARGET_GL const Vector2i& framebufferSize, @@ -1069,7 +1076,7 @@ class EmscriptenApplication::ViewportEvent { #endif _dpiScaling{dpiScaling}, _devicePixelRatio{devicePixelRatio} {} - const EmscriptenUiEvent& _event; + const EmscriptenUiEvent* _event; const Vector2i _windowSize; #ifdef MAGNUM_TARGET_GL const Vector2i _framebufferSize;