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();