From 631103bfa8f58d8a1de8d9f3ab0b2c9a3ef9c641 Mon Sep 17 00:00:00 2001 From: Richard Gale Date: Mon, 24 Aug 2015 19:12:01 -0700 Subject: [PATCH] Adds suspend event mapped to application lifecycle On Android WillSuspend and WillResume maps to focus and DidSuspend and DidResume maps to onPause and onResume. On OSX WillSuspend and DidSuspend maps to resign key, WillResume and DidResumg maps to make key. --- examples/common/entry/entry.cpp | 5 ++- examples/common/entry/entry.h | 16 +++++++- examples/common/entry/entry_android.cpp | 16 ++++++++ examples/common/entry/entry_asmjs.cpp | 54 +++++++++++++++++++++---- examples/common/entry/entry_ios.mm | 4 ++ examples/common/entry/entry_osx.mm | 28 +++++++++++++ examples/common/entry/entry_p.h | 15 +++++++ 7 files changed, 129 insertions(+), 9 deletions(-) diff --git a/examples/common/entry/entry.cpp b/examples/common/entry/entry.cpp index 94f8e4ded..773ec5f4b 100644 --- a/examples/common/entry/entry.cpp +++ b/examples/common/entry/entry.cpp @@ -464,7 +464,10 @@ BX_PRAGMA_DIAGNOSTIC_POP(); case Event::Window: break; - default: + case Event::Suspend: + break; + + default: break; } } diff --git a/examples/common/entry/entry.h b/examples/common/entry/entry.h index 373808b67..13b852620 100644 --- a/examples/common/entry/entry.h +++ b/examples/common/entry/entry.h @@ -62,7 +62,8 @@ namespace entry }; struct Modifier - { enum Enum + { + enum Enum { None = 0, LeftAlt = 0x01, @@ -187,6 +188,19 @@ namespace entry }; }; + struct Suspend + { + enum Enum + { + WillSuspend, + DidSuspend, + WillResume, + DidResume, + + Count + }; + }; + const char* getName(Key::Enum _key); struct MouseState diff --git a/examples/common/entry/entry_android.cpp b/examples/common/entry/entry_android.cpp index 2d7c852c8..f16b1e5da 100644 --- a/examples/common/entry/entry_android.cpp +++ b/examples/common/entry/entry_android.cpp @@ -181,14 +181,22 @@ namespace entry break; case APP_CMD_GAINED_FOCUS: + { // Command from main thread: the app's activity window has gained // input focus. + WindowHandle defaultWindow = { 0 }; + m_eventQueue.postSuspendEvent(defaultWindow, Suspend::WillResume); break; + } case APP_CMD_LOST_FOCUS: + { // Command from main thread: the app's activity window has lost // input focus. + WindowHandle defaultWindow = { 0 }; + m_eventQueue.postSuspendEvent(defaultWindow, Suspend::WillSuspend); break; + } case APP_CMD_CONFIG_CHANGED: // Command from main thread: the current device configuration has changed. @@ -204,8 +212,12 @@ namespace entry break; case APP_CMD_RESUME: + { // Command from main thread: the app's activity has been resumed. + WindowHandle defaultWindow = { 0 }; + m_eventQueue.postSuspendEvent(defaultWindow, Suspend::DidResume); break; + } case APP_CMD_SAVE_STATE: // Command from main thread: the app should generate a new saved state @@ -216,8 +228,12 @@ namespace entry break; case APP_CMD_PAUSE: + { // Command from main thread: the app's activity has been paused. + WindowHandle defaultWindow = { 0 }; + m_eventQueue.postSuspendEvent(defaultWindow, Suspend::DidSuspend); break; + } case APP_CMD_STOP: // Command from main thread: the app's activity has been stopped. diff --git a/examples/common/entry/entry_asmjs.cpp b/examples/common/entry/entry_asmjs.cpp index 73e7483cf..f5c3dc62c 100644 --- a/examples/common/entry/entry_asmjs.cpp +++ b/examples/common/entry/entry_asmjs.cpp @@ -109,15 +109,20 @@ namespace entry emscripten_request_fullscreen_strategy("#canvas", false, &fullscreenStrategy); + emscripten_set_focus_callback(NULL, this, true, focusCb); + emscripten_set_focusin_callback(NULL, this, true, focusCb); + emscripten_set_focusout_callback(NULL, this, true, focusCb); + int32_t result = main(_argc, _argv); return result; } - static EM_BOOL mouseCb(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData); - static EM_BOOL wheelCb(int eventType, const EmscriptenWheelEvent* wheelEvent, void* userData); - static EM_BOOL keyCb(int eventType, const EmscriptenKeyboardEvent* keyEvent, void* userData); - static EM_BOOL resizeCb(int eventType, const EmscriptenUiEvent* uiEvent, void* userData); - static EM_BOOL canvasResizeCb(int eventType, const void* reserved, void *userData); + static EM_BOOL mouseCb(int eventType, const EmscriptenMouseEvent* event, void* userData); + static EM_BOOL wheelCb(int eventType, const EmscriptenWheelEvent* event, void* userData); + static EM_BOOL keyCb(int eventType, const EmscriptenKeyboardEvent* event, void* userData); + static EM_BOOL resizeCb(int eventType, const EmscriptenUiEvent* event, void* userData); + static EM_BOOL canvasResizeCb(int eventType, const void* reserved, void* userData); + static EM_BOOL focusCb(int eventType, const EmscriptenFocusEvent* event, void* userData); EventQueue m_eventQueue; @@ -284,18 +289,53 @@ namespace entry return false; } - EM_BOOL Context::resizeCb(int eventType, const EmscriptenUiEvent* event, void *userData) + EM_BOOL Context::resizeCb(int eventType, const EmscriptenUiEvent* event, void* userData) { BX_UNUSED(eventType, event, userData); return false; } - EM_BOOL Context::canvasResizeCb(int eventType, const void* reserved, void *userData) + EM_BOOL Context::canvasResizeCb(int eventType, const void* reserved, void* userData) { BX_UNUSED(eventType, reserved, userData); return false; } + EM_BOOL Context::focusCb(int eventType, const EmscriptenFocusEvent* event, void* userData) + { + printf("focusCb %d", eventType); + BX_UNUSED(event, userData); + + if (event) + { + switch (eventType) + { + case EMSCRIPTEN_EVENT_BLUR: + { + s_ctx.m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::DidSuspend); + return true; + } + case EMSCRIPTEN_EVENT_FOCUS: + { + s_ctx.m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::DidResume); + return true; + } + case EMSCRIPTEN_EVENT_FOCUSIN: + { + s_ctx.m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::WillResume); + return true; + } + case EMSCRIPTEN_EVENT_FOCUSOUT: + { + s_ctx.m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::WillSuspend); + return true; + } + } + } + + return false; + } + const Event* poll() { entry_emscripten_yield(); diff --git a/examples/common/entry/entry_ios.mm b/examples/common/entry/entry_ios.mm index f721bfa0f..d2392d898 100644 --- a/examples/common/entry/entry_ios.mm +++ b/examples/common/entry/entry_ios.mm @@ -323,22 +323,26 @@ static void* m_device = NULL; - (void)applicationWillResignActive:(UIApplication *)application { BX_UNUSED(application); + s_ctx->m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::WillSuspend); [m_view stop]; } - (void)applicationDidEnterBackground:(UIApplication *)application { BX_UNUSED(application); + s_ctx->m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::DidSuspend); } - (void)applicationWillEnterForeground:(UIApplication *)application { BX_UNUSED(application); + s_ctx->m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::WillResume); } - (void)applicationDidBecomeActive:(UIApplication *)application { BX_UNUSED(application); + s_ctx->m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::DidResume); [m_view start]; } diff --git a/examples/common/entry/entry_osx.mm b/examples/common/entry/entry_osx.mm index a43c47abc..6446e4259 100644 --- a/examples/common/entry/entry_osx.mm +++ b/examples/common/entry/entry_osx.mm @@ -39,6 +39,8 @@ - (void)windowWillClose:(NSNotification*)notification; - (BOOL)windowShouldClose:(NSWindow*)window; - (void)windowDidResize:(NSNotification*)notification; +- (void)windowDidBecomeKey:(NSNotification *)notification; +- (void)windowDidResignKey:(NSNotification *)notification; @end @@ -384,6 +386,18 @@ namespace entry m_eventQueue.postMouseEvent(s_defaultWindow, m_mx, m_my, m_scroll, MouseButton::Right, false); } + void windowDidBecomeKey() + { + m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::WillResume); + m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::DidResume); + } + + void windowDidResignKey() + { + m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::WillSuspend); + m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::DidSuspend); + } + int32_t run(int _argc, char** _argv) { [NSApplication sharedApplication]; @@ -723,6 +737,20 @@ namespace entry s_ctx.windowDidResize(); } +- (void)windowDidBecomeKey:(NSNotification*)notification +{ + BX_UNUSED(notification); + using namespace entry; + s_ctx.windowDidBecomeKey(); +} + +- (void)windowDidResignKey:(NSNotification*)notification +{ + BX_UNUSED(notification); + using namespace entry; + s_ctx.windowDidResignKey(); +} + @end int main(int _argc, char** _argv) diff --git a/examples/common/entry/entry_p.h b/examples/common/entry/entry_p.h index d0ba73311..e1a1a5148 100644 --- a/examples/common/entry/entry_p.h +++ b/examples/common/entry/entry_p.h @@ -75,6 +75,7 @@ namespace entry Mouse, Size, Window, + Suspend, }; Event(Enum _type) @@ -154,6 +155,13 @@ namespace entry void* m_nwh; }; + struct SuspendEvent : public Event + { + ENTRY_IMPLEMENT_EVENT(SuspendEvent, Event::Suspend); + + Suspend::Enum m_state; + }; + const Event* poll(); const Event* poll(WindowHandle _handle); void release(const Event* _event); @@ -248,6 +256,13 @@ namespace entry m_queue.push(ev); } + void postSuspendEvent(WindowHandle _handle, Suspend::Enum _state) + { + SuspendEvent* ev = new SuspendEvent(_handle); + ev->m_state = _state; + m_queue.push(ev); + } + const Event* poll() { return m_queue.pop();