Browse Source

Platform: add focusEvent() and blurEvent() to Application implementations.

Android, Emscripten, Sdl2 and Glfw. Not to XEgl / Glx, nobody cares
about those anymore.
pull/680/head
Vladimír Vondruš 11 months ago
parent
commit
7558bc71ba
  1. 4
      doc/changelog.dox
  2. 11
      src/Magnum/Platform/AndroidApplication.cpp
  3. 46
      src/Magnum/Platform/AndroidApplication.h
  4. 13
      src/Magnum/Platform/EmscriptenApplication.cpp
  5. 53
      src/Magnum/Platform/EmscriptenApplication.h
  6. 8
      src/Magnum/Platform/GlfwApplication.cpp
  7. 33
      src/Magnum/Platform/GlfwApplication.h
  8. 7
      src/Magnum/Platform/Sdl2Application.cpp
  9. 57
      src/Magnum/Platform/Sdl2Application.h
  10. 7
      src/Magnum/Platform/Test/AndroidApplicationTest.cpp
  11. 7
      src/Magnum/Platform/Test/EmscriptenApplicationTest.cpp
  12. 7
      src/Magnum/Platform/Test/GlfwApplicationTest.cpp
  13. 7
      src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp

4
doc/changelog.dox

@ -378,6 +378,10 @@ See also:
building upon [mosra/magnum#527](https://github.com/mosra/magnum/pull/527).
There's also a new @ref Platform::TwoFingerGesture helper for recognition
of common two-finger gestures for zoom, rotation and pan.
- Added @relativeref{Platform::Sdl2Application,focusEvent()} and
@relativeref{Platform::Sdl2Application,blurEvent()} to
@ref Platform::Sdl2Application, @ref Platform::GlfwApplication,
@ref Platform::EmscriptenApplication and @ref Platform::AndroidApplication
@subsubsection changelog-latest-new-scenegraph SceneGraph library

11
src/Magnum/Platform/AndroidApplication.cpp

@ -191,6 +191,8 @@ void AndroidApplication::redraw() {
}
void AndroidApplication::viewportEvent(ViewportEvent&) {}
void AndroidApplication::focusEvent(FocusEvent&) {}
void AndroidApplication::blurEvent(FocusEvent&) {}
namespace {
struct Data {
@ -225,9 +227,12 @@ void AndroidApplication::commandEvent(android_app* state, int32_t cmd) {
break;
case APP_CMD_GAINED_FOCUS:
case APP_CMD_LOST_FOCUS:
/** @todo Make use of these */
break;
case APP_CMD_LOST_FOCUS: {
FocusEvent e;
cmd == APP_CMD_GAINED_FOCUS ?
data.instance->focusEvent(e) :
data.instance->blurEvent(e);
} break;
case APP_CMD_CONFIG_CHANGED: {
/* This says "the current device configuration has changed", which

46
src/Magnum/Platform/AndroidApplication.h

@ -206,6 +206,7 @@ class AndroidApplication {
class Configuration;
class GLConfiguration;
class ViewportEvent;
class FocusEvent;
class InputEvent;
class PointerEvent;
class PointerMoveEvent;
@ -431,6 +432,25 @@ class AndroidApplication {
*/
virtual void viewportEvent(ViewportEvent& event);
/**
* @brief Application focus event
* @m_since_latest
*
* Called when the application gains focus. The default implementation
* does nothing.
*/
virtual void focusEvent(FocusEvent& event);
/**
* @brief Application blur event
* @m_since_latest
*
* Called when the application loses focus, which may be happening for
* example together with the application getting suspended to
* background. The default implementation does nothing.
*/
virtual void blurEvent(FocusEvent& event);
/** @copydoc Sdl2Application::drawEvent() */
virtual void drawEvent() = 0;
@ -949,6 +969,32 @@ class AndroidApplication::ViewportEvent {
const Vector2i _windowSize;
};
/**
@brief Window focus and blur event
@m_since_latest
@see @ref focusEvent(), @ref blurEvent()
*/
class AndroidApplication::FocusEvent {
public:
/** @brief Copying is not allowed */
FocusEvent(const FocusEvent&) = delete;
/** @brief Moving is not allowed */
FocusEvent(FocusEvent&&) = delete;
/** @brief Copying is not allowed */
FocusEvent& operator=(const FocusEvent&) = delete;
/** @brief Moving is not allowed */
FocusEvent& operator=(FocusEvent&&) = delete;
private:
friend AndroidApplication;
explicit FocusEvent() = default;
};
/**
@brief Base for input events

13
src/Magnum/Platform/EmscriptenApplication.cpp

@ -627,6 +627,17 @@ void EmscriptenApplication::setupCallbacks(bool resizable) {
emscripten_set_resize_callback(target, this, false, cb);
}
emscripten_set_focus_callback(_canvasTarget.data(), this, false, ([](int, const EmscriptenFocusEvent* event, void* userData) -> EM_BOOL {
FocusEvent e{*event};
static_cast<EmscriptenApplication*>(userData)->focusEvent(e);
return true;
}));
emscripten_set_blur_callback(_canvasTarget.data(), this, false, ([](int, const EmscriptenFocusEvent* event, void* userData) -> EM_BOOL {
FocusEvent e{*event};
static_cast<EmscriptenApplication*>(userData)->blurEvent(e);
return true;
}));
/* Done this way instead of passing the lambda inline so it can have the
#if inside. Because, apparently, emscripten_set_mousedown_callback() is
some crazy macro, and I get "warning: embedding a directive within macro
@ -1040,6 +1051,8 @@ void EmscriptenApplication::setTextInputRect(const Range2Di&) {
}
void EmscriptenApplication::viewportEvent(ViewportEvent&) {}
void EmscriptenApplication::focusEvent(FocusEvent&) {}
void EmscriptenApplication::blurEvent(FocusEvent&) {}
void EmscriptenApplication::keyPressEvent(KeyEvent&) {}
void EmscriptenApplication::keyReleaseEvent(KeyEvent&) {}

53
src/Magnum/Platform/EmscriptenApplication.h

@ -69,6 +69,7 @@
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT
struct EmscriptenFocusEvent;
struct EmscriptenKeyboardEvent;
struct EmscriptenMouseEvent;
struct EmscriptenTouchEvent;
@ -334,6 +335,7 @@ class EmscriptenApplication {
class Configuration;
class GLConfiguration;
class ViewportEvent;
class FocusEvent;
class InputEvent;
class PointerEvent;
class PointerMoveEvent;
@ -668,6 +670,26 @@ class EmscriptenApplication {
*/
virtual void viewportEvent(ViewportEvent& event);
/**
* @brief Canvas focus event
* @m_since_latest
*
* Called when the canvas gains (keyboard) input focus. The default
* implementation does nothing.
*/
virtual void focusEvent(FocusEvent& event);
/**
* @brief Canvas blur event
* @m_since_latest
*
* Called when the canvas loses (keyboard) input focus, which for
* example can be used by the application code to discard all
* information about currently pressed keys. The default implementation
* does nothing.
*/
virtual void blurEvent(FocusEvent& event);
/** @copydoc Sdl2Application::drawEvent() */
virtual void drawEvent() = 0;
@ -2000,6 +2022,37 @@ class EmscriptenApplication::ViewportEvent {
const Vector2 _dpiScaling, _devicePixelRatio;
};
/**
@brief Window focus and blur event
@m_since_latest
@see @ref focusEvent(), @ref blurEvent()
*/
class EmscriptenApplication::FocusEvent {
public:
/** @brief Copying is not allowed */
FocusEvent(const FocusEvent&) = delete;
/** @brief Moving is not allowed */
FocusEvent(FocusEvent&&) = delete;
/** @brief Copying is not allowed */
FocusEvent& operator=(const FocusEvent&) = delete;
/** @brief Moving is not allowed */
FocusEvent& operator=(FocusEvent&&) = delete;
/** @brief Underlying Emscripten event */
const EmscriptenFocusEvent& event() const { return _event; }
private:
friend EmscriptenApplication;
explicit FocusEvent(const EmscriptenFocusEvent& event): _event(event) {}
const EmscriptenFocusEvent& _event;
};
/**
@brief Base for input events

8
src/Magnum/Platform/GlfwApplication.cpp

@ -670,6 +670,12 @@ void GlfwApplication::setupCallbacks() {
#endif
app.viewportEvent(e);
});
glfwSetWindowFocusCallback(_window, [](GLFWwindow* const window, const int focused) {
auto& app = *static_cast<GlfwApplication*>(glfwGetWindowUserPointer(window));
FocusEvent e;
focused ? app.focusEvent(e) : app.blurEvent(e);
});
glfwSetKeyCallback(_window, [](GLFWwindow* const window, const int key, const int scancode, const int action, const int mods) {
auto& app = *static_cast<GlfwApplication*>(glfwGetWindowUserPointer(window));
@ -974,6 +980,8 @@ void GlfwApplication::tickEvent() {
}
void GlfwApplication::viewportEvent(ViewportEvent&) {}
void GlfwApplication::focusEvent(FocusEvent&) {}
void GlfwApplication::blurEvent(FocusEvent&) {}
void GlfwApplication::keyPressEvent(KeyEvent&) {}
void GlfwApplication::keyReleaseEvent(KeyEvent&) {}

33
src/Magnum/Platform/GlfwApplication.h

@ -176,6 +176,7 @@ class GlfwApplication {
#endif
class ExitEvent;
class ViewportEvent;
class FocusEvent;
class InputEvent;
class KeyEvent;
class PointerEvent;
@ -638,6 +639,12 @@ class GlfwApplication {
*/
virtual void viewportEvent(ViewportEvent& event);
/** @copydoc Sdl2Application::focusEvent() */
virtual void focusEvent(FocusEvent& event);
/** @copydoc Sdl2Application::blurEvent() */
virtual void blurEvent(FocusEvent& event);
/** @copydoc Sdl2Application::drawEvent() */
virtual void drawEvent() = 0;
@ -2112,6 +2119,32 @@ class GlfwApplication::ViewportEvent {
const Vector2 _dpiScaling;
};
/**
@brief Window focus and blur event
@m_since_latest
@see @ref focusEvent(), @ref blurEvent()
*/
class GlfwApplication::FocusEvent {
public:
/** @brief Copying is not allowed */
FocusEvent(const FocusEvent&) = delete;
/** @brief Moving is not allowed */
FocusEvent(FocusEvent&&) = delete;
/** @brief Copying is not allowed */
FocusEvent& operator=(const FocusEvent&) = delete;
/** @brief Moving is not allowed */
FocusEvent& operator=(FocusEvent&&) = delete;
private:
friend GlfwApplication;
explicit FocusEvent() = default;
};
/**
@brief Base for input events

7
src/Magnum/Platform/Sdl2Application.cpp

@ -1064,6 +1064,11 @@ bool Sdl2Application::mainLoopIteration() {
_flags |= Flag::Redraw;
#endif
} break;
case SDL_WINDOWEVENT_FOCUS_GAINED:
case SDL_WINDOWEVENT_FOCUS_LOST: {
FocusEvent e{event};
event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED ? focusEvent(e) : blurEvent(e);
} break;
/* Direct everything that wasn't exposed via a callback to
anyEvent(), so users can implement event handling for
things not present in the Application APIs */
@ -1466,6 +1471,8 @@ void Sdl2Application::anyEvent(SDL_Event&) {
}
void Sdl2Application::viewportEvent(ViewportEvent&) {}
void Sdl2Application::focusEvent(FocusEvent&) {}
void Sdl2Application::blurEvent(FocusEvent&) {}
void Sdl2Application::keyPressEvent(KeyEvent&) {}
void Sdl2Application::keyReleaseEvent(KeyEvent&) {}

57
src/Magnum/Platform/Sdl2Application.h

@ -551,6 +551,7 @@ class Sdl2Application {
#endif
class ExitEvent;
class ViewportEvent;
class FocusEvent;
class InputEvent;
class KeyEvent;
class PointerEvent;
@ -1113,6 +1114,26 @@ class Sdl2Application {
*/
virtual void viewportEvent(ViewportEvent& event);
/**
* @brief Window focus event
* @m_since_latest
*
* Called when the window gains (keyboard) input focus. The default
* implementation does nothing.
*/
virtual void focusEvent(FocusEvent& event);
/**
* @brief Window blur event
* @m_since_latest
*
* Called when the window loses (keyboard) input focus, which for
* example can be used by the application code to discard all
* information about currently pressed keys. The default implementation
* does nothing.
*/
virtual void blurEvent(FocusEvent& event);
/**
* @brief Draw event
*
@ -2830,6 +2851,42 @@ class Sdl2Application::ViewportEvent {
const Vector2 _dpiScaling;
};
/**
@brief Window focus and blur event
@m_since_latest
@see @ref focusEvent(), @ref blurEvent()
*/
class Sdl2Application::FocusEvent {
public:
/** @brief Copying is not allowed */
FocusEvent(const FocusEvent&) = delete;
/** @brief Moving is not allowed */
FocusEvent(FocusEvent&&) = delete;
/** @brief Copying is not allowed */
FocusEvent& operator=(const FocusEvent&) = delete;
/** @brief Moving is not allowed */
FocusEvent& operator=(FocusEvent&&) = delete;
/**
* @brief Underlying SDL event
*
* Of type `SDL_WINDOWEVENT`
* @see @ref Sdl2Application::anyEvent()
*/
const SDL_Event& event() const { return _event; }
private:
friend Sdl2Application;
explicit FocusEvent(const SDL_Event& event): _event(event) {}
const SDL_Event& _event;
};
/**
@brief Base for input events

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

@ -142,6 +142,13 @@ struct AndroidApplicationTest: Platform::Application {
Debug{} << "viewport:" << event.windowSize() << event.framebufferSize() << event.dpiScaling();
}
void focusEvent(FocusEvent&) override {
Debug{} << "application focused";
}
void blurEvent(FocusEvent&) override {
Debug{} << "application blurred";
}
/* Set to 0 to test the deprecated mouse events instead */
#if 1
void pointerPressEvent(PointerEvent& event) override {

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

@ -314,6 +314,13 @@ struct EmscriptenApplicationTest: Platform::Application {
}
#endif
void focusEvent(FocusEvent&) override {
Debug{} << "canvas focused";
}
void blurEvent(FocusEvent&) override {
Debug{} << "canvas blurred";
}
/* Set to 0 to test the deprecated mouse events instead */
#if 1
void pointerPressEvent(PointerEvent& event) override {

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

@ -285,6 +285,13 @@ struct GlfwApplicationTest: Platform::Application {
<< event.dpiScaling();
}
void focusEvent(FocusEvent&) override {
Debug{} << "window focused";
}
void blurEvent(FocusEvent&) override {
Debug{} << "window blurred";
}
void exitEvent(ExitEvent& event) override {
Debug{} << "application exiting";
event.setAccepted(); /* Comment-out to test app exit suppression */

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

@ -328,6 +328,13 @@ struct Sdl2ApplicationTest: Platform::Application {
<< event.dpiScaling();
}
void focusEvent(FocusEvent&) override {
Debug{} << "window focused";
}
void blurEvent(FocusEvent&) override {
Debug{} << "window blurred";
}
void drawEvent() override {
Debug{} << "draw event";
#ifdef MAGNUM_TARGET_GL

Loading…
Cancel
Save