WinRT: simulate keyboard events on Windows Phone 8 back-button presses
authorDavid Ludwig <dludwig@pobox.com>
Sun, 26 Jan 2014 08:06:36 -0500
changeset 8577 462760a8b82e
parent 8576 8dd593afe2d7
child 8578 6517b6aca713
WinRT: simulate keyboard events on Windows Phone 8 back-button presses Pressing the hardware back button on a Windows Phone 8 device will now cause SDL to emit a pair of key-down and key-up events, with the SDL scancode, SDL_SCANCODE_AC_BACK. By default, if WinRT's native back-button-press events are not explicitly marked as 'handled', then Windows Phone will terminate the app. More details on Microsoft's reasoning behind this can be found on MSDN, at http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj247550(v=vs.105).aspx To mark back-button-press events as 'handled', set SDL_HINT_WINRT_HANDLE_BACK_BUTTON to 1. Setting it to anything else will cause these events to not be marked as 'handled'. Due to limitations in Windows Phone's APIs, SDL will emit a virtual key-up event immediately after the back button's key-down event is registered. Unfortunately, Windows Phone 8 only allows one to register for back-button-press events, and not back-button-release events.
include/SDL_hints.h
src/core/winrt/SDL_winrtapp_direct3d.cpp
src/core/winrt/SDL_winrtapp_direct3d.h
--- a/include/SDL_hints.h	Wed Jan 01 16:05:37 2014 -0500
+++ b/include/SDL_hints.h	Sun Jan 26 08:06:36 2014 -0500
@@ -378,6 +378,15 @@
  */
 #define SDL_HINT_WINRT_PRIVACY_POLICY_LABEL "SDL_HINT_WINRT_PRIVACY_POLICY_LABEL"
 
+/** \brief If set to 1, back button press events on Windows Phone 8+ will be marked as handled.
+ *
+ *  TODO, WinRT: document SDL_HINT_WINRT_HANDLE_BACK_BUTTON need and use
+ *  For now, more details on why this is needed can be found at the
+ *  beginning of the following web page:
+ *  http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj247550(v=vs.105).aspx
+ */
+#define SDL_HINT_WINRT_HANDLE_BACK_BUTTON "SDL_HINT_WINRT_HANDLE_BACK_BUTTON"
+
 /**
  *  \brief  An enumeration of hint priorities
  */
--- a/src/core/winrt/SDL_winrtapp_direct3d.cpp	Wed Jan 01 16:05:37 2014 -0500
+++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp	Sun Jan 26 08:06:36 2014 -0500
@@ -19,6 +19,10 @@
 using namespace Windows::UI::Core;
 using namespace Windows::UI::Input;
 
+#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
+using namespace Windows::Phone::UI::Input;
+#endif
+
 
 /* SDL includes */
 extern "C" {
@@ -31,6 +35,7 @@
 #include "SDL_render.h"
 #include "../../video/SDL_sysvideo.h"
 //#include "../../SDL_hints_c.h"
+#include "../../events/SDL_keyboard_c.h"
 #include "../../events/SDL_mouse_c.h"
 #include "../../events/SDL_windowevents_c.h"
 #include "../../render/SDL_sysrender.h"
@@ -316,6 +321,11 @@
     window->KeyUp +=
         ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyUp);
 
+#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
+    HardwareButtons::BackPressed +=
+        ref new EventHandler<BackPressedEventArgs^>(this, &SDL_WinRTApp::OnBackButtonPressed);
+#endif
+
 #if WINAPI_FAMILY == WINAPI_FAMILY_APP  // for Windows 8/8.1/RT apps... (and not Phone apps)
     // Make sure we know when a user has opened the app's settings pane.
     // This is needed in order to display a privacy policy, which needs
@@ -597,3 +607,19 @@
 {
     WINRT_ProcessKeyUpEvent(args);
 }
+
+#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
+void SDL_WinRTApp::OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args)
+{
+    SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_AC_BACK);
+    SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_AC_BACK);
+
+    const char *hint = SDL_GetHint(SDL_HINT_WINRT_HANDLE_BACK_BUTTON);
+    if (hint) {
+        if (*hint == '1') {
+            args->Handled = true;
+        }
+    }
+}
+#endif
+
--- a/src/core/winrt/SDL_winrtapp_direct3d.h	Wed Jan 01 16:05:37 2014 -0500
+++ b/src/core/winrt/SDL_winrtapp_direct3d.h	Sun Jan 26 08:06:36 2014 -0500
@@ -45,6 +45,10 @@
     void OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args);
     void OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args);
 
+#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
+    void OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args);
+#endif
+
 private:
     bool m_windowClosed;
     bool m_windowVisible;