diff --git a/doc/changelog.dox b/doc/changelog.dox index 22bf69bd0..29d3b4159 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -91,6 +91,8 @@ See also: well, see @ref opengl-workarounds for more information. - @ref Platform::GlfwApplication no longer stores a needless global window pointer +- @ref Platform::GlfwApplication now loads modifiers for mouse move and mouse + scroll events lazily, only when needed @subsubsection changelog-latest-changes-shaders Shaders library @@ -129,6 +131,9 @@ See also: @ref GL::Framebuffer::clearColor(), @ref GL::Framebuffer::clearDepth(), @ref GL::Framebuffer::clearStencil() and @ref GL::Framebuffer::clearDepthStencil() were binding the framebuffer for drawing, which was completely unnecessary +- @ref Platform::GlfwApplication::InputEvent::Modifier::Super is properly + reported for both left and right modifier (Windows/⌘) key instead of just + the right one @subsection changelog-latest-docs Documentation diff --git a/src/Magnum/Platform/GlfwApplication.cpp b/src/Magnum/Platform/GlfwApplication.cpp index f31236f9a..809edbdce 100644 --- a/src/Magnum/Platform/GlfwApplication.cpp +++ b/src/Magnum/Platform/GlfwApplication.cpp @@ -148,6 +148,31 @@ bool GlfwApplication::tryCreate(const Configuration& configuration) { return true; } +namespace { + +GlfwApplication::InputEvent::Modifiers currentGlfwModifiers(GLFWwindow* window) { + static_assert(GLFW_PRESS == true && GLFW_RELEASE == false, + "GLFW press and release constants do not correspond to bool values"); + + GlfwApplication::InputEvent::Modifiers mods; + if(glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) || + glfwGetKey(window, GLFW_KEY_RIGHT_SHIFT)) + mods |= GlfwApplication::InputEvent::Modifier::Shift; + if(glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) || + glfwGetKey(window, GLFW_KEY_RIGHT_CONTROL)) + mods |= GlfwApplication::InputEvent::Modifier::Ctrl; + if(glfwGetKey(window, GLFW_KEY_LEFT_ALT) || + glfwGetKey(window, GLFW_KEY_RIGHT_ALT)) + mods |= GlfwApplication::InputEvent::Modifier::Alt; + if(glfwGetKey(window, GLFW_KEY_LEFT_SUPER) || + glfwGetKey(window, GLFW_KEY_RIGHT_SUPER)) + mods |= GlfwApplication::InputEvent::Modifier::Super; + + return mods; +} + +} + #ifdef MAGNUM_TARGET_GL bool GlfwApplication::tryCreate(const Configuration& configuration, const GLConfiguration& #ifndef MAGNUM_BUILD_DEPRECATED @@ -370,9 +395,14 @@ void GlfwApplication::staticKeyEvent(GLFWwindow* const window, const int key, in } } -void GlfwApplication::staticMouseMoveEvent(GLFWwindow* window, double x, double y) { - MouseMoveEvent e{Vector2i{Int(x), Int(y)}, KeyEvent::getCurrentGlfwModifiers(window)}; - static_cast(glfwGetWindowUserPointer(window))->mouseMoveEvent(e); +auto GlfwApplication::MouseMoveEvent::modifiers() -> Modifiers { + if(!_modifiers) _modifiers = currentGlfwModifiers(_window); + return *_modifiers; +} + +auto GlfwApplication::MouseScrollEvent::modifiers() -> Modifiers { + if(!_modifiers) _modifiers = currentGlfwModifiers(_window); + return *_modifiers; } void GlfwApplication::staticMouseEvent(GLFWwindow* window, int button, int action, int mods) { @@ -389,10 +419,15 @@ void GlfwApplication::staticMouseEvent(GLFWwindow* window, int button, int actio } /* we don't handle GLFW_REPEAT */ } +void GlfwApplication::staticMouseMoveEvent(GLFWwindow* window, double x, double y) { + MouseMoveEvent e{window, Vector2i{Int(x), Int(y)}}; + static_cast(glfwGetWindowUserPointer(window))->mouseMoveEvent(e); +} + void GlfwApplication::staticMouseScrollEvent(GLFWwindow* window, double xoffset, double yoffset) { const auto instance = static_cast(glfwGetWindowUserPointer(window)); - MouseScrollEvent e(Vector2{Float(xoffset), Float(yoffset)}, KeyEvent::getCurrentGlfwModifiers(window)); + MouseScrollEvent e(window, Vector2{Float(xoffset), Float(yoffset)}); instance->mouseScrollEvent(e); #ifdef MAGNUM_BUILD_DEPRECATED @@ -401,7 +436,7 @@ void GlfwApplication::staticMouseScrollEvent(GLFWwindow* window, double xoffset, #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif - MouseEvent e1((yoffset > 0.0) ? MouseEvent::Button::WheelUp : MouseEvent::Button::WheelDown, {}, KeyEvent::getCurrentGlfwModifiers(window)); + MouseEvent e1((yoffset > 0.0) ? MouseEvent::Button::WheelUp : MouseEvent::Button::WheelDown, {}, currentGlfwModifiers(window)); #ifdef __GNUC__ #pragma GCC diagnostic pop #endif @@ -425,23 +460,6 @@ void GlfwApplication::staticErrorCallback(int, const char* description) { Error() << description; } -auto GlfwApplication::KeyEvent::getCurrentGlfwModifiers(GLFWwindow* window) -> Modifiers { - static_assert(GLFW_PRESS == true && GLFW_RELEASE == false, - "GLFW press and release constants do not correspond to bool values"); - - Modifiers mods; - if(glfwGetKey(window, Int(Key::LeftShift)) || glfwGetKey(window, Int(Key::RightShift))) - mods |= Modifier::Shift; - if(glfwGetKey(window, Int(Key::LeftAlt)) || glfwGetKey(window, Int(Key::RightAlt))) - mods |= Modifier::Alt; - if(glfwGetKey(window, Int(Key::LeftCtrl)) || glfwGetKey(window, Int(Key::RightCtrl))) - mods |= Modifier::Ctrl; - if(glfwGetKey(window, Int(Key::RightSuper))) - mods |= Modifier::Super; - - return mods; -} - void GlfwApplication::viewportEvent(const Vector2i&) {} void GlfwApplication::keyPressEvent(KeyEvent&) {} void GlfwApplication::keyReleaseEvent(KeyEvent&) {} diff --git a/src/Magnum/Platform/GlfwApplication.h b/src/Magnum/Platform/GlfwApplication.h index 7b89de6af..49df1dd44 100644 --- a/src/Magnum/Platform/GlfwApplication.h +++ b/src/Magnum/Platform/GlfwApplication.h @@ -33,6 +33,7 @@ #include #include #include +#include #include "Magnum/Magnum.h" #include "Magnum/Tags.h" @@ -1116,8 +1117,6 @@ class GlfwApplication::KeyEvent: public GlfwApplication::InputEvent { constexpr bool isRepeated() const { return _repeated; } private: - static Modifiers getCurrentGlfwModifiers(GLFWwindow* window); - constexpr KeyEvent(Key key, Modifiers modifiers, bool repeated): _key{key}, _modifiers{modifiers}, _repeated{repeated} {} const Key _key; @@ -1195,16 +1194,21 @@ class GlfwApplication::MouseMoveEvent: public GlfwApplication::InputEvent { public: /** @brief Position */ - constexpr Vector2i position() const { return _position; } + Vector2i position() const { return _position; } - /** @brief Modifiers */ - constexpr Modifiers modifiers() const { return _modifiers; } + /** + * @brief Modifiers + * + * Lazily populated on first request. + */ + Modifiers modifiers(); private: - constexpr MouseMoveEvent(const Vector2i& position, Modifiers modifiers): _position(position), _modifiers(modifiers) {} + explicit MouseMoveEvent(GLFWwindow* window, const Vector2i& position): _window{window}, _position{position} {} + GLFWwindow* _window; const Vector2i _position; - const Modifiers _modifiers; + Containers::Optional _modifiers; }; /** @@ -1217,16 +1221,21 @@ class GlfwApplication::MouseScrollEvent: public GlfwApplication::InputEvent { public: /** @brief Scroll offset */ - constexpr Vector2 offset() const { return _offset; } + Vector2 offset() const { return _offset; } - /** @brief Modifiers */ - constexpr Modifiers modifiers() const { return _modifiers; } + /** + * @brief Modifiers + * + * Lazily populated on first request. + */ + Modifiers modifiers(); private: - constexpr MouseScrollEvent(const Vector2& offset, Modifiers modifiers): _offset(offset), _modifiers(modifiers) {} + explicit MouseScrollEvent(GLFWwindow* window, const Vector2& offset): _window{window}, _offset{offset} {} + GLFWwindow* _window; const Vector2 _offset; - const Modifiers _modifiers; + Containers::Optional _modifiers; }; /**