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;