WinRT: Add camera button events on Windows Phone

Windows Phone 8.1 provides access to the camera button and press/release
events get passed as Key_CameraFocus and Key_Camera. Unfortunately a
release does not provide what has been pressed before, hence this
information needs to be cached when the press happens.

Done-with: Maurice Kalinowski<maurice.kalinowski@theqtcompany.com>
Task-number: QTBUG-39115
Change-Id: I6ce58a1f07a6bf7183b8d99a26e5cd7b0d32d6db
Reviewed-by: Topi Reiniö <topi.reinio@theqtcompany.com>
Reviewed-by: Samuel Nevala <samuel.nevala@intopalo.com>
Reviewed-by: Oliver Wolff <oliver.wolff@theqtcompany.com>
bb10
Samuel Nevala 2015-11-17 07:52:28 +02:00 committed by Oliver Wolff
parent 4ed8733d90
commit 2ca20724dd
3 changed files with 70 additions and 2 deletions

View File

@ -1704,8 +1704,8 @@
\value Key_unknown
\value Key_Call A key to answer or initiate a call (see Qt::Key_ToggleCallHangup for a key to toggle current call state)
\value Key_Camera A key to activate the camera shutter
\value Key_CameraFocus A key to focus the camera
\value Key_Camera A key to activate the camera shutter. On Windows Runtime, the environment variable QT_QPA_ENABLE_CAMERA_KEYS must be set to receive the event.
\value Key_CameraFocus A key to focus the camera. On Windows Runtime, the environment variable QT_QPA_ENABLE_CAMERA_KEYS must be set to receive the event.
\value Key_Context1
\value Key_Context2
\value Key_Context3

View File

@ -79,6 +79,7 @@ typedef IEventHandler<IInspectable *> ResumeHandler;
typedef IEventHandler<SuspendingEventArgs *> SuspendHandler;
#ifdef Q_OS_WINPHONE
typedef IEventHandler<BackPressedEventArgs*> BackPressedHandler;
typedef IEventHandler<CameraEventArgs*> CameraButtonHandler;
#endif
QT_BEGIN_NAMESPACE
@ -88,6 +89,8 @@ uint qHash(CoreApplicationCallbackRemover key) { void *ptr = *(void **)(&key); r
#ifdef Q_OS_WINPHONE
typedef HRESULT (__stdcall IHardwareButtonsStatics::*HardwareButtonsCallbackRemover)(EventRegistrationToken);
uint qHash(HardwareButtonsCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
typedef HRESULT (__stdcall IHardwareButtonsStatics2::*HardwareButtons2CallbackRemover)(EventRegistrationToken);
uint qHash(HardwareButtons2CallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
#endif
class QWinRTIntegrationPrivate
@ -103,6 +106,10 @@ public:
#ifdef Q_OS_WINPHONE
ComPtr<IHardwareButtonsStatics> hardwareButtons;
QHash<HardwareButtonsCallbackRemover, EventRegistrationToken> buttonsTokens;
ComPtr<IHardwareButtonsStatics2> cameraButtons;
QHash<HardwareButtons2CallbackRemover, EventRegistrationToken> cameraTokens;
bool cameraHalfPressed : 1;
bool cameraPressed : 1;
#endif
};
@ -130,6 +137,23 @@ QWinRTIntegration::QWinRTIntegration() : d_ptr(new QWinRTIntegrationPrivate)
hr = d->hardwareButtons->add_BackPressed(Callback<BackPressedHandler>(this, &QWinRTIntegration::onBackButtonPressed).Get(),
&d->buttonsTokens[&IHardwareButtonsStatics::remove_BackPressed]);
Q_ASSERT_SUCCEEDED(hr);
hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Phone_UI_Input_HardwareButtons).Get(),
IID_PPV_ARGS(&d->cameraButtons));
Q_ASSERT_SUCCEEDED(hr);
if (qEnvironmentVariableIntValue("QT_QPA_ENABLE_CAMERA_KEYS")) {
hr = d->cameraButtons->add_CameraPressed(Callback<CameraButtonHandler>(this, &QWinRTIntegration::onCameraPressed).Get(),
&d->cameraTokens[&IHardwareButtonsStatics2::remove_CameraPressed]);
Q_ASSERT_SUCCEEDED(hr);
hr = d->cameraButtons->add_CameraHalfPressed(Callback<CameraButtonHandler>(this, &QWinRTIntegration::onCameraHalfPressed).Get(),
&d->cameraTokens[&IHardwareButtonsStatics2::remove_CameraHalfPressed]);
Q_ASSERT_SUCCEEDED(hr);
hr = d->cameraButtons->add_CameraReleased(Callback<CameraButtonHandler>(this, &QWinRTIntegration::onCameraReleased).Get(),
&d->cameraTokens[&IHardwareButtonsStatics2::remove_CameraReleased]);
Q_ASSERT_SUCCEEDED(hr);
}
d->cameraPressed = false;
d->cameraHalfPressed = false;
#endif // Q_OS_WINPHONE
QEventDispatcherWinRT::runOnXamlThread([d]() {
@ -151,6 +175,10 @@ QWinRTIntegration::~QWinRTIntegration()
hr = (d->hardwareButtons.Get()->*i.key())(i.value());
Q_ASSERT_SUCCEEDED(hr);
}
for (QHash<HardwareButtons2CallbackRemover, EventRegistrationToken>::const_iterator i = d->cameraTokens.begin(); i != d->cameraTokens.end(); ++i) {
hr = (d->cameraButtons.Get()->*i.key())(i.value());
Q_ASSERT_SUCCEEDED(hr);
}
#endif
for (QHash<CoreApplicationCallbackRemover, EventRegistrationToken>::const_iterator i = d->applicationTokens.begin(); i != d->applicationTokens.end(); ++i) {
hr = (d->application.Get()->*i.key())(i.value());
@ -268,6 +296,42 @@ HRESULT QWinRTIntegration::onBackButtonPressed(IInspectable *, IBackPressedEvent
args->put_Handled(pressed || released);
return S_OK;
}
HRESULT QWinRTIntegration::onCameraPressed(IInspectable *, ICameraEventArgs *)
{
Q_D(QWinRTIntegration);
QWindow *window = d->mainScreen->topWindow();
QWindowSystemInterface::handleExtendedKeyEvent(window, QEvent::KeyPress, Qt::Key_Camera, Qt::NoModifier,
0, 0, 0, QString(), false, 1, false);
d->cameraPressed = true;
return S_OK;
}
HRESULT QWinRTIntegration::onCameraHalfPressed(IInspectable *, ICameraEventArgs *)
{
Q_D(QWinRTIntegration);
QWindow *window = d->mainScreen->topWindow();
QWindowSystemInterface::handleExtendedKeyEvent(window, QEvent::KeyPress, Qt::Key_CameraFocus, Qt::NoModifier,
0, 0, 0, QString(), false, 1, false);
d->cameraHalfPressed = true;
return S_OK;
}
HRESULT QWinRTIntegration::onCameraReleased(IInspectable *, ICameraEventArgs *)
{
Q_D(QWinRTIntegration);
QWindow *window = d->mainScreen->topWindow();
if (d->cameraHalfPressed)
QWindowSystemInterface::handleExtendedKeyEvent(window, QEvent::KeyRelease, Qt::Key_CameraFocus, Qt::NoModifier,
0, 0, 0, QString(), false, 1, false);
if (d->cameraPressed)
QWindowSystemInterface::handleExtendedKeyEvent(window, QEvent::KeyRelease, Qt::Key_Camera, Qt::NoModifier,
0, 0, 0, QString(), false, 1, false);
d->cameraHalfPressed = false;
d->cameraPressed = false;
return S_OK;
}
#endif // Q_OS_WINPHONE
HRESULT QWinRTIntegration::onSuspended(IInspectable *, ISuspendingEventArgs *)

View File

@ -52,6 +52,7 @@ namespace ABI {
namespace UI {
namespace Input {
struct IBackPressedEventArgs;
struct ICameraEventArgs;
}
}
}
@ -100,6 +101,9 @@ public:
private:
#ifdef Q_OS_WINPHONE
HRESULT onBackButtonPressed(IInspectable *, ABI::Windows::Phone::UI::Input::IBackPressedEventArgs *args);
HRESULT onCameraPressed(IInspectable *, ABI::Windows::Phone::UI::Input::ICameraEventArgs *);
HRESULT onCameraHalfPressed(IInspectable *, ABI::Windows::Phone::UI::Input::ICameraEventArgs *);
HRESULT onCameraReleased(IInspectable *, ABI::Windows::Phone::UI::Input::ICameraEventArgs *);
#endif
HRESULT onSuspended(IInspectable *, ABI::Windows::ApplicationModel::ISuspendingEventArgs *);
HRESULT onResume(IInspectable *, IInspectable *);