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.
This commit is contained in:
David Ludwig 2014-01-26 08:06:36 -05:00
parent 7eaa3cd81d
commit abfbed92cf
3 changed files with 39 additions and 0 deletions

View File

@ -378,6 +378,15 @@ extern "C" {
*/ */
#define SDL_HINT_WINRT_PRIVACY_POLICY_LABEL "SDL_HINT_WINRT_PRIVACY_POLICY_LABEL" #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 * \brief An enumeration of hint priorities
*/ */

View File

@ -19,6 +19,10 @@ using namespace Windows::System;
using namespace Windows::UI::Core; using namespace Windows::UI::Core;
using namespace Windows::UI::Input; using namespace Windows::UI::Input;
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
using namespace Windows::Phone::UI::Input;
#endif
/* SDL includes */ /* SDL includes */
extern "C" { extern "C" {
@ -31,6 +35,7 @@ extern "C" {
#include "SDL_render.h" #include "SDL_render.h"
#include "../../video/SDL_sysvideo.h" #include "../../video/SDL_sysvideo.h"
//#include "../../SDL_hints_c.h" //#include "../../SDL_hints_c.h"
#include "../../events/SDL_keyboard_c.h"
#include "../../events/SDL_mouse_c.h" #include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_windowevents_c.h" #include "../../events/SDL_windowevents_c.h"
#include "../../render/SDL_sysrender.h" #include "../../render/SDL_sysrender.h"
@ -316,6 +321,11 @@ void SDL_WinRTApp::SetWindow(CoreWindow^ window)
window->KeyUp += window->KeyUp +=
ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyUp); 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) #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. // 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 // This is needed in order to display a privacy policy, which needs
@ -597,3 +607,19 @@ void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::C
{ {
WINRT_ProcessKeyUpEvent(args); 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

View File

@ -45,6 +45,10 @@ protected:
void OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args); void OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args);
void OnKeyUp(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: private:
bool m_windowClosed; bool m_windowClosed;
bool m_windowVisible; bool m_windowVisible;