summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/winrt/qwinrtscreen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/winrt/qwinrtscreen.cpp')
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp1543
1 files changed, 0 insertions, 1543 deletions
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
deleted file mode 100644
index 5db1459213..0000000000
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ /dev/null
@@ -1,1543 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwinrtscreen.h"
-
-#include "qwinrtbackingstore.h"
-#include "qwinrtinputcontext.h"
-#include "qwinrtcursor.h"
-#if QT_CONFIG(draganddrop)
-#include "qwinrtdrag.h"
-#endif
-#include "qwinrtwindow.h"
-#include "qwinrtcanvas.h"
-#include <private/qeventdispatcher_winrt_p.h>
-#include <private/qhighdpiscaling_p.h>
-
-#include <QtCore/qdebug.h>
-#include <QtCore/QLoggingCategory>
-#include <QtGui/QSurfaceFormat>
-#include <QtGui/QGuiApplication>
-#include <qpa/qwindowsysteminterface.h>
-#include <QtCore/qt_windows.h>
-#include <QtCore/qfunctions_winrt.h>
-
-#include <functional>
-#include <wrl.h>
-#include <windows.system.h>
-#include <Windows.ApplicationModel.h>
-#include <Windows.ApplicationModel.core.h>
-#include <windows.devices.input.h>
-#include <windows.ui.h>
-#include <windows.ui.core.h>
-#include <windows.ui.input.h>
-#include <windows.ui.xaml.h>
-#include <windows.ui.viewmanagement.h>
-#include <windows.graphics.display.h>
-#include <windows.foundation.h>
-
-using namespace Microsoft::WRL;
-using namespace Microsoft::WRL::Wrappers;
-using namespace ABI::Windows::ApplicationModel;
-using namespace ABI::Windows::ApplicationModel::Core;
-using namespace ABI::Windows::Foundation;
-using namespace ABI::Windows::System;
-using namespace ABI::Windows::UI;
-using namespace ABI::Windows::UI::Core;
-using namespace ABI::Windows::UI::Input;
-using namespace ABI::Windows::UI::ViewManagement;
-using namespace ABI::Windows::Devices::Input;
-using namespace ABI::Windows::Graphics::Display;
-
-typedef ITypedEventHandler<CoreWindow*, WindowActivatedEventArgs*> ActivatedHandler;
-typedef ITypedEventHandler<CoreWindow*, CoreWindowEventArgs*> ClosedHandler;
-typedef ITypedEventHandler<CoreWindow*, CharacterReceivedEventArgs*> CharacterReceivedHandler;
-typedef ITypedEventHandler<CoreWindow*, InputEnabledEventArgs*> InputEnabledHandler;
-typedef ITypedEventHandler<CoreWindow*, KeyEventArgs*> KeyHandler;
-typedef ITypedEventHandler<CoreWindow*, PointerEventArgs*> PointerHandler;
-typedef ITypedEventHandler<CoreWindow*, VisibilityChangedEventArgs*> VisibilityChangedHandler;
-typedef ITypedEventHandler<DisplayInformation*, IInspectable*> DisplayInformationHandler;
-typedef ITypedEventHandler<ICorePointerRedirector*, PointerEventArgs*> RedirectHandler;
-typedef ITypedEventHandler<ApplicationView*, IInspectable*> VisibleBoundsChangedHandler;
-
-QT_BEGIN_NAMESPACE
-
-Q_LOGGING_CATEGORY(lcQpaEvents, "qt.qpa.events")
-
-#if !defined(QT_NO_DEBUG_STREAM)
-QDebug operator<<(QDebug dbg, QWinRTScreen::MousePositionTransition transition)
-{
- QDebugStateSaver saver(dbg);
- dbg.nospace() << "QWinRTScreen::MousePositionTransition::";
- switch (transition) {
- case QWinRTScreen::MousePositionTransition::MovedOut:
- dbg << "MovedOut";
- break;
- case QWinRTScreen::MousePositionTransition::MovedIn:
- dbg << "MovedIn";
- break;
- case QWinRTScreen::MousePositionTransition::StayedOut:
- dbg << "StayedOut";
- break;
- case QWinRTScreen::MousePositionTransition::StayedIn:
- dbg << "StayedIn";
- break;
- }
- return dbg;
-}
-#endif
-
-struct KeyInfo {
- KeyInfo()
- {
- }
-
- KeyInfo(quint32 virtualKey)
- : virtualKey(virtualKey)
- {
- }
-
- QString text;
- quint32 virtualKey{0};
- bool isAutoRepeat{false};
-};
-
-static inline Qt::ScreenOrientations qtOrientationsFromNative(DisplayOrientations native)
-{
- Qt::ScreenOrientations orientations = Qt::PrimaryOrientation;
- if (native & DisplayOrientations_Portrait)
- orientations |= Qt::PortraitOrientation;
- if (native & DisplayOrientations_PortraitFlipped)
- orientations |= Qt::InvertedPortraitOrientation;
- if (native & DisplayOrientations_Landscape)
- orientations |= Qt::LandscapeOrientation;
- if (native & DisplayOrientations_LandscapeFlipped)
- orientations |= Qt::InvertedLandscapeOrientation;
- return orientations;
-}
-
-static inline DisplayOrientations nativeOrientationsFromQt(Qt::ScreenOrientations orientation)
-{
- DisplayOrientations native = DisplayOrientations_None;
- if (orientation & Qt::PortraitOrientation)
- native |= DisplayOrientations_Portrait;
- if (orientation & Qt::InvertedPortraitOrientation)
- native |= DisplayOrientations_PortraitFlipped;
- if (orientation & Qt::LandscapeOrientation)
- native |= DisplayOrientations_Landscape;
- if (orientation & Qt::InvertedLandscapeOrientation)
- native |= DisplayOrientations_LandscapeFlipped;
- return native;
-}
-
-static inline bool qIsNonPrintable(quint32 keyCode)
-{
- switch (keyCode) {
- case '\b':
- case '\n':
- case '\t':
- case '\r':
- case '\v':
- case '\f':
- return true;
- default:
- return false;
- }
-}
-
-// Return Qt meta key from VirtualKey
-static inline Qt::Key qKeyFromVirtual(VirtualKey key)
-{
- switch (key) {
-
- default:
- return Qt::Key_unknown;
-
- // Non-printable characters
- case VirtualKey_Enter:
- return Qt::Key_Enter;
- case VirtualKey_Tab:
- return Qt::Key_Tab;
- case VirtualKey_Back:
- return Qt::Key_Backspace;
-
- // Modifiers
- case VirtualKey_Shift:
- case VirtualKey_LeftShift:
- case VirtualKey_RightShift:
- return Qt::Key_Shift;
- case VirtualKey_Control:
- case VirtualKey_LeftControl:
- case VirtualKey_RightControl:
- return Qt::Key_Control;
- case VirtualKey_Menu:
- case VirtualKey_LeftMenu:
- case VirtualKey_RightMenu:
- return Qt::Key_Alt;
- case VirtualKey_LeftWindows:
- case VirtualKey_RightWindows:
- return Qt::Key_Meta;
-
- // Toggle keys
- case VirtualKey_CapitalLock:
- return Qt::Key_CapsLock;
- case VirtualKey_NumberKeyLock:
- return Qt::Key_NumLock;
- case VirtualKey_Scroll:
- return Qt::Key_ScrollLock;
-
- // East-Asian language keys
- case VirtualKey_Kana:
- //case VirtualKey_Hangul: // Same enum as Kana
- return Qt::Key_Kana_Shift;
- case VirtualKey_Junja:
- return Qt::Key_Hangul_Jeonja;
- case VirtualKey_Kanji:
- //case VirtualKey_Hanja: // Same enum as Kanji
- return Qt::Key_Kanji;
- case VirtualKey_ModeChange:
- return Qt::Key_Mode_switch;
- case VirtualKey_Convert:
- return Qt::Key_Henkan;
- case VirtualKey_NonConvert:
- return Qt::Key_Muhenkan;
-
- // Misc. keys
- case VirtualKey_Cancel:
- return Qt::Key_Cancel;
- case VirtualKey_Clear:
- return Qt::Key_Clear;
- case VirtualKey_Application:
- return Qt::Key_ApplicationLeft;
- case VirtualKey_Sleep:
- return Qt::Key_Sleep;
- case VirtualKey_Pause:
- return Qt::Key_Pause;
- case VirtualKey_PageUp:
- return Qt::Key_PageUp;
- case VirtualKey_PageDown:
- return Qt::Key_PageDown;
- case VirtualKey_End:
- return Qt::Key_End;
- case VirtualKey_Home:
- return Qt::Key_Home;
- case VirtualKey_Left:
- return Qt::Key_Left;
- case VirtualKey_Up:
- return Qt::Key_Up;
- case VirtualKey_Right:
- return Qt::Key_Right;
- case VirtualKey_Down:
- return Qt::Key_Down;
- case VirtualKey_Select:
- return Qt::Key_Select;
- case VirtualKey_Print:
- return Qt::Key_Print;
- case VirtualKey_Execute:
- return Qt::Key_Execute;
- case VirtualKey_Insert:
- return Qt::Key_Insert;
- case VirtualKey_Delete:
- return Qt::Key_Delete;
- case VirtualKey_Help:
- return Qt::Key_Help;
- case VirtualKey_Snapshot:
- return Qt::Key_Camera;
- case VirtualKey_Escape:
- return Qt::Key_Escape;
-
- // Function Keys
- case VirtualKey_F1:
- return Qt::Key_F1;
- case VirtualKey_F2:
- return Qt::Key_F2;
- case VirtualKey_F3:
- return Qt::Key_F3;
- case VirtualKey_F4:
- return Qt::Key_F4;
- case VirtualKey_F5:
- return Qt::Key_F5;
- case VirtualKey_F6:
- return Qt::Key_F6;
- case VirtualKey_F7:
- return Qt::Key_F7;
- case VirtualKey_F8:
- return Qt::Key_F8;
- case VirtualKey_F9:
- return Qt::Key_F9;
- case VirtualKey_F10:
- return Qt::Key_F10;
- case VirtualKey_F11:
- return Qt::Key_F11;
- case VirtualKey_F12:
- return Qt::Key_F12;
- case VirtualKey_F13:
- return Qt::Key_F13;
- case VirtualKey_F14:
- return Qt::Key_F14;
- case VirtualKey_F15:
- return Qt::Key_F15;
- case VirtualKey_F16:
- return Qt::Key_F16;
- case VirtualKey_F17:
- return Qt::Key_F17;
- case VirtualKey_F18:
- return Qt::Key_F18;
- case VirtualKey_F19:
- return Qt::Key_F19;
- case VirtualKey_F20:
- return Qt::Key_F20;
- case VirtualKey_F21:
- return Qt::Key_F21;
- case VirtualKey_F22:
- return Qt::Key_F22;
- case VirtualKey_F23:
- return Qt::Key_F23;
- case VirtualKey_F24:
- return Qt::Key_F24;
-
- // Character keys
- case VirtualKey_Space:
- return Qt::Key_Space;
- case VirtualKey_Number0:
- case VirtualKey_NumberPad0:
- return Qt::Key_0;
- case VirtualKey_Number1:
- case VirtualKey_NumberPad1:
- return Qt::Key_1;
- case VirtualKey_Number2:
- case VirtualKey_NumberPad2:
- return Qt::Key_2;
- case VirtualKey_Number3:
- case VirtualKey_NumberPad3:
- return Qt::Key_3;
- case VirtualKey_Number4:
- case VirtualKey_NumberPad4:
- return Qt::Key_4;
- case VirtualKey_Number5:
- case VirtualKey_NumberPad5:
- return Qt::Key_5;
- case VirtualKey_Number6:
- case VirtualKey_NumberPad6:
- return Qt::Key_6;
- case VirtualKey_Number7:
- case VirtualKey_NumberPad7:
- return Qt::Key_7;
- case VirtualKey_Number8:
- case VirtualKey_NumberPad8:
- return Qt::Key_8;
- case VirtualKey_Number9:
- case VirtualKey_NumberPad9:
- return Qt::Key_9;
- case VirtualKey_A:
- return Qt::Key_A;
- case VirtualKey_B:
- return Qt::Key_B;
- case VirtualKey_C:
- return Qt::Key_C;
- case VirtualKey_D:
- return Qt::Key_D;
- case VirtualKey_E:
- return Qt::Key_E;
- case VirtualKey_F:
- return Qt::Key_F;
- case VirtualKey_G:
- return Qt::Key_G;
- case VirtualKey_H:
- return Qt::Key_H;
- case VirtualKey_I:
- return Qt::Key_I;
- case VirtualKey_J:
- return Qt::Key_J;
- case VirtualKey_K:
- return Qt::Key_K;
- case VirtualKey_L:
- return Qt::Key_L;
- case VirtualKey_M:
- return Qt::Key_M;
- case VirtualKey_N:
- return Qt::Key_N;
- case VirtualKey_O:
- return Qt::Key_O;
- case VirtualKey_P:
- return Qt::Key_P;
- case VirtualKey_Q:
- return Qt::Key_Q;
- case VirtualKey_R:
- return Qt::Key_R;
- case VirtualKey_S:
- return Qt::Key_S;
- case VirtualKey_T:
- return Qt::Key_T;
- case VirtualKey_U:
- return Qt::Key_U;
- case VirtualKey_V:
- return Qt::Key_V;
- case VirtualKey_W:
- return Qt::Key_W;
- case VirtualKey_X:
- return Qt::Key_X;
- case VirtualKey_Y:
- return Qt::Key_Y;
- case VirtualKey_Z:
- return Qt::Key_Z;
- case VirtualKey_Multiply:
- return Qt::Key_9;
- case VirtualKey_Add:
- return Qt::Key_9;
- case VirtualKey_Separator:
- return Qt::Key_9;
- case VirtualKey_Subtract:
- return Qt::Key_9;
- case VirtualKey_Decimal:
- return Qt::Key_9;
- case VirtualKey_Divide:
- return Qt::Key_9;
-
- /* Keys with no matching Qt enum (?)
- case VirtualKey_None:
- case VirtualKey_LeftButton:
- case VirtualKey_RightButton:
- case VirtualKey_MiddleButton:
- case VirtualKey_XButton1:
- case VirtualKey_XButton2:
- case VirtualKey_Final:
- case VirtualKey_Accept:*/
- }
-}
-
-// Some keys like modifiers, caps lock etc. should not be automatically repeated if the key is held down
-static inline bool shouldAutoRepeat(Qt::Key key)
-{
- switch (key) {
- case Qt::Key_Shift:
- case Qt::Key_Control:
- case Qt::Key_Alt:
- case Qt::Key_Meta:
- case Qt::Key_CapsLock:
- case Qt::Key_NumLock:
- case Qt::Key_ScrollLock:
- return false;
- default:
- return true;
- }
-}
-
-static inline Qt::Key qKeyFromCode(quint32 code, int mods)
-{
- if (code >= 'a' && code <= 'z')
- code = toupper(code);
- if ((mods & Qt::ControlModifier) != 0) {
- if (code >= 0 && code <= 31) // Ctrl+@..Ctrl+A..CTRL+Z..Ctrl+_
- code += '@'; // to @..A..Z.._
- }
- return static_cast<Qt::Key>(code & 0xff);
-}
-
-typedef HRESULT (__stdcall ICoreWindow::*CoreWindowCallbackRemover)(EventRegistrationToken);
-size_t qHash(CoreWindowCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
-typedef HRESULT (__stdcall IDisplayInformation::*DisplayCallbackRemover)(EventRegistrationToken);
-size_t qHash(DisplayCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
-typedef HRESULT (__stdcall ICorePointerRedirector::*RedirectorCallbackRemover)(EventRegistrationToken);
-size_t qHash(RedirectorCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
-typedef HRESULT (__stdcall IApplicationView2::*ApplicationView2CallbackRemover)(EventRegistrationToken);
-size_t qHash(ApplicationView2CallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
-
-class QWinRTScreenPrivate
-{
-public:
- QTouchDevice *touchDevice;
- ComPtr<ICoreWindow> coreWindow;
- ComPtr<ICorePointerRedirector> redirect;
- ComPtr<QWinRTCanvas> canvas;
- ComPtr<IApplicationView> view;
- ComPtr<IDisplayInformation> displayInformation;
-
- QScopedPointer<QWinRTCursor> cursor;
- QHash<quint32, QWindowSystemInterface::TouchPoint> touchPoints;
- QRectF logicalRect;
- QRectF visibleRect;
- QSurfaceFormat surfaceFormat;
- qreal logicalDpi;
- QDpi physicalDpi;
- qreal scaleFactor;
- Qt::ScreenOrientation nativeOrientation;
- Qt::ScreenOrientation orientation;
- QList<QWindow *> visibleWindows;
- QHash<Qt::Key, KeyInfo> activeKeys;
- QHash<CoreWindowCallbackRemover, EventRegistrationToken> windowTokens;
- QHash<DisplayCallbackRemover, EventRegistrationToken> displayTokens;
- QHash<RedirectorCallbackRemover, EventRegistrationToken> redirectTokens;
- QHash<ApplicationView2CallbackRemover, EventRegistrationToken> view2Tokens;
- ComPtr<IApplicationView2> view2;
- QAtomicPointer<QWinRTWindow> mouseGrabWindow;
- QAtomicPointer<QWinRTWindow> keyboardGrabWindow;
- QWindow *currentPressWindow = nullptr;
- QWindow *currentTargetWindow = nullptr;
- bool firstMouseMove = true;
- bool resizePending = false;
-};
-
-// To be called from the XAML thread
-QWinRTScreen::QWinRTScreen()
- : d_ptr(new QWinRTScreenPrivate)
-{
- Q_D(QWinRTScreen);
- qCDebug(lcQpaWindows) << __FUNCTION__;
- d->orientation = Qt::PrimaryOrientation;
- d->touchDevice = nullptr;
-
- HRESULT hr;
- ComPtr<Xaml::IWindowStatics> windowStatics;
- hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Window).Get(),
- IID_PPV_ARGS(&windowStatics));
- Q_ASSERT_SUCCEEDED(hr);
- ComPtr<Xaml::IWindow> window;
- hr = windowStatics->get_Current(&window);
- Q_ASSERT_SUCCEEDED(hr);
- hr = window->Activate();
- Q_ASSERT_SUCCEEDED(hr);
-
- hr = window->get_CoreWindow(&d->coreWindow);
- Q_ASSERT_SUCCEEDED(hr);
-
- hr = d->coreWindow.As(&d->redirect);
- Q_ASSERT_SUCCEEDED(hr);
-
- hr = d->coreWindow->Activate();
- Q_ASSERT_SUCCEEDED(hr);
-
- Rect rect;
- hr = d->coreWindow->get_Bounds(&rect);
- Q_ASSERT_SUCCEEDED(hr);
- d->logicalRect = QRectF(0.0f, 0.0f, rect.Width, rect.Height);
- d->visibleRect = QRectF(0.0f, 0.0f, rect.Width, rect.Height);
-
- // Orientation handling
- ComPtr<IDisplayInformationStatics> displayInformationStatics;
- hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayInformation).Get(),
- IID_PPV_ARGS(&displayInformationStatics));
- Q_ASSERT_SUCCEEDED(hr);
-
- hr = displayInformationStatics->GetForCurrentView(&d->displayInformation);
- Q_ASSERT_SUCCEEDED(hr);
-
- // Set native orientation
- DisplayOrientations displayOrientation;
- hr = d->displayInformation->get_NativeOrientation(&displayOrientation);
- Q_ASSERT_SUCCEEDED(hr);
- d->nativeOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation)));
- // Set initial pixel density
- onDpiChanged(nullptr, nullptr);
- d->orientation = d->nativeOrientation;
-
- ComPtr<IApplicationViewStatics2> applicationViewStatics;
- hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_ApplicationView).Get(),
- IID_PPV_ARGS(&applicationViewStatics));
- RETURN_VOID_IF_FAILED("Could not get ApplicationViewStatics");
-
- hr = applicationViewStatics->GetForCurrentView(&d->view);
- RETURN_VOID_IF_FAILED("Could not access currentView");
-
- d->canvas = Make<QWinRTCanvas>([this]() { return topWindow(); });
-
- ComPtr<Xaml::IFrameworkElement> frameworkElement;
- hr = d->canvas.As(&frameworkElement);
- Q_ASSERT_SUCCEEDED(hr);
- hr = frameworkElement->put_Width(d->logicalRect.width());
- Q_ASSERT_SUCCEEDED(hr);
- hr = frameworkElement->put_Height(d->logicalRect.height());
- Q_ASSERT_SUCCEEDED(hr);
-
- ComPtr<Xaml::IUIElement> uiElement;
- hr = d->canvas.As(&uiElement);
- Q_ASSERT_SUCCEEDED(hr);
-
-#if QT_CONFIG(draganddrop)
- QWinRTDrag::instance()->setUiElement(uiElement);
-#endif
- hr = window->put_Content(uiElement.Get());
- Q_ASSERT_SUCCEEDED(hr);
-
- d->cursor.reset(new QWinRTCursor);
-
- hr = d->view.As(&d->view2);
- Q_ASSERT_SUCCEEDED(hr);
-}
-
-QWinRTScreen::~QWinRTScreen()
-{
- Q_D(QWinRTScreen);
- qCDebug(lcQpaWindows) << __FUNCTION__ << this;
-
- // Unregister callbacks
- HRESULT hr;
- hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() {
- HRESULT hr;
- for (QHash<CoreWindowCallbackRemover, EventRegistrationToken>::const_iterator i = d->windowTokens.begin(); i != d->windowTokens.end(); ++i) {
- hr = (d->coreWindow.Get()->*i.key())(i.value());
- Q_ASSERT_SUCCEEDED(hr);
- }
- for (QHash<DisplayCallbackRemover, EventRegistrationToken>::const_iterator i = d->displayTokens.begin(); i != d->displayTokens.end(); ++i) {
- hr = (d->displayInformation.Get()->*i.key())(i.value());
- Q_ASSERT_SUCCEEDED(hr);
- }
- for (QHash<RedirectorCallbackRemover, EventRegistrationToken>::const_iterator i = d->redirectTokens.begin(); i != d->redirectTokens.end(); ++i) {
- hr = (d->redirect.Get()->*i.key())(i.value());
- Q_ASSERT_SUCCEEDED(hr);
- }
- for (QHash<ApplicationView2CallbackRemover, EventRegistrationToken>::const_iterator i = d->view2Tokens.begin(); i != d->view2Tokens.end(); ++i) {
- hr = (d->view2.Get()->*i.key())(i.value());
- Q_ASSERT_SUCCEEDED(hr);
- }
- return hr;
- });
- RETURN_VOID_IF_FAILED("Failed to unregister screen event callbacks");
-}
-
-QRect QWinRTScreen::geometry() const
-{
- Q_D(const QWinRTScreen);
- return QRect(QPoint(), QSizeF(d->logicalRect.size() * d->scaleFactor).toSize());
-}
-
-QRect QWinRTScreen::availableGeometry() const
-{
- Q_D(const QWinRTScreen);
- return QRectF((d->visibleRect.x() - d->logicalRect.x())* d->scaleFactor,
- (d->visibleRect.y() - d->logicalRect.y()) * d->scaleFactor,
- d->visibleRect.width() * d->scaleFactor,
- d->visibleRect.height() * d->scaleFactor).toRect();
-}
-
-int QWinRTScreen::depth() const
-{
- return 32;
-}
-
-QImage::Format QWinRTScreen::format() const
-{
- return QImage::Format_RGB32;
-}
-
-QSizeF QWinRTScreen::physicalSize() const
-{
- Q_D(const QWinRTScreen);
- return QSizeF(d->logicalRect.width() * d->scaleFactor / d->physicalDpi.first * qreal(25.4),
- d->logicalRect.height() * d->scaleFactor / d->physicalDpi.second * qreal(25.4));
-}
-
-QDpi QWinRTScreen::logicalDpi() const
-{
- Q_D(const QWinRTScreen);
- return QDpi(d->logicalDpi, d->logicalDpi);
-}
-
-qreal QWinRTScreen::scaleFactor() const
-{
- Q_D(const QWinRTScreen);
- return d->scaleFactor;
-}
-
-QPlatformCursor *QWinRTScreen::cursor() const
-{
- Q_D(const QWinRTScreen);
- return d->cursor.data();
-}
-
-Qt::KeyboardModifiers QWinRTScreen::keyboardModifiers() const
-{
- Q_D(const QWinRTScreen);
-
- Qt::KeyboardModifiers mods;
- CoreVirtualKeyStates mod;
- HRESULT hr = d->coreWindow->GetAsyncKeyState(VirtualKey_Shift, &mod);
- Q_ASSERT_SUCCEEDED(hr);
- if (mod & CoreVirtualKeyStates_Down)
- mods |= Qt::ShiftModifier;
- hr = d->coreWindow->GetAsyncKeyState(VirtualKey_Menu, &mod);
- Q_ASSERT_SUCCEEDED(hr);
- if (mod & CoreVirtualKeyStates_Down)
- mods |= Qt::AltModifier;
- hr = d->coreWindow->GetAsyncKeyState(VirtualKey_Control, &mod);
- Q_ASSERT_SUCCEEDED(hr);
- if (mod & CoreVirtualKeyStates_Down)
- mods |= Qt::ControlModifier;
- hr = d->coreWindow->GetAsyncKeyState(VirtualKey_LeftWindows, &mod);
- Q_ASSERT_SUCCEEDED(hr);
- if (mod & CoreVirtualKeyStates_Down) {
- mods |= Qt::MetaModifier;
- } else {
- hr = d->coreWindow->GetAsyncKeyState(VirtualKey_RightWindows, &mod);
- Q_ASSERT_SUCCEEDED(hr);
- if (mod & CoreVirtualKeyStates_Down)
- mods |= Qt::MetaModifier;
- }
- return mods;
-}
-
-Qt::ScreenOrientation QWinRTScreen::nativeOrientation() const
-{
- Q_D(const QWinRTScreen);
- return d->nativeOrientation;
-}
-
-Qt::ScreenOrientation QWinRTScreen::orientation() const
-{
- Q_D(const QWinRTScreen);
- return d->orientation;
-}
-
-ICoreWindow *QWinRTScreen::coreWindow() const
-{
- Q_D(const QWinRTScreen);
- return d->coreWindow.Get();
-}
-
-Xaml::IDependencyObject *QWinRTScreen::canvas() const
-{
- Q_D(const QWinRTScreen);
- Xaml::IDependencyObject *depCanvas;
- if (SUCCEEDED(d->canvas.CopyTo(&depCanvas)))
- return depCanvas;
- return nullptr;
-}
-
-void QWinRTScreen::initialize()
-{
- Q_D(QWinRTScreen);
- HRESULT hr;
- hr = d->coreWindow->add_KeyDown(Callback<KeyHandler>(this, &QWinRTScreen::onKeyDown).Get(), &d->windowTokens[&ICoreWindow::remove_KeyDown]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->coreWindow->add_KeyUp(Callback<KeyHandler>(this, &QWinRTScreen::onKeyUp).Get(), &d->windowTokens[&ICoreWindow::remove_KeyUp]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->coreWindow->add_CharacterReceived(Callback<CharacterReceivedHandler>(this, &QWinRTScreen::onCharacterReceived).Get(), &d->windowTokens[&ICoreWindow::remove_CharacterReceived]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->coreWindow->add_PointerEntered(Callback<PointerHandler>(this, &QWinRTScreen::onPointerEntered).Get(), &d->windowTokens[&ICoreWindow::remove_PointerEntered]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->coreWindow->add_PointerExited(Callback<PointerHandler>(this, &QWinRTScreen::onPointerExited).Get(), &d->windowTokens[&ICoreWindow::remove_PointerExited]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->coreWindow->add_PointerMoved(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerMoved]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->coreWindow->add_PointerPressed(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerPressed]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->coreWindow->add_PointerReleased(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerReleased]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->coreWindow->add_PointerWheelChanged(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerWheelChanged]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->view2->add_VisibleBoundsChanged(Callback<VisibleBoundsChangedHandler>(this, &QWinRTScreen::onWindowSizeChanged).Get(), &d->view2Tokens[&IApplicationView2::remove_VisibleBoundsChanged]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->coreWindow->add_Activated(Callback<ActivatedHandler>(this, &QWinRTScreen::onActivated).Get(), &d->windowTokens[&ICoreWindow::remove_Activated]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->coreWindow->add_Closed(Callback<ClosedHandler>(this, &QWinRTScreen::onClosed).Get(), &d->windowTokens[&ICoreWindow::remove_Closed]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->coreWindow->add_VisibilityChanged(Callback<VisibilityChangedHandler>(this, &QWinRTScreen::onVisibilityChanged).Get(), &d->windowTokens[&ICoreWindow::remove_VisibilityChanged]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->displayInformation->add_OrientationChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onOrientationChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_OrientationChanged]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->displayInformation->add_DpiChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onDpiChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_DpiChanged]);
- Q_ASSERT_SUCCEEDED(hr);
- onOrientationChanged(nullptr, nullptr);
- onVisibilityChanged(nullptr, nullptr);
-
- hr = d->redirect->add_PointerRoutedReleased(Callback<RedirectHandler>(this, &QWinRTScreen::onRedirectReleased).Get(), &d->redirectTokens[&ICorePointerRedirector::remove_PointerRoutedReleased]);
- Q_ASSERT_SUCCEEDED(hr);
-}
-
-void QWinRTScreen::setCursorRect(const QRectF &cursorRect)
-{
- mCursorRect = cursorRect;
-}
-
-void QWinRTScreen::setKeyboardRect(const QRectF &keyboardRect)
-{
- Q_D(QWinRTScreen);
- QRectF visibleRectF;
- HRESULT hr;
- Rect windowSize;
-
- hr = d->coreWindow->get_Bounds(&windowSize);
- if (FAILED(hr)) {
- qErrnoWarning(hr, "Failed to get window bounds");
- return;
- }
- d->logicalRect = QRectF(windowSize.X, windowSize.Y, windowSize.Width, windowSize.Height);
- Rect visibleRect;
- hr = d->view2->get_VisibleBounds(&visibleRect);
- if (FAILED(hr)) {
- qErrnoWarning(hr, "Failed to get window visible bounds");
- return;
- }
- visibleRectF = QRectF(visibleRect.X, visibleRect.Y, visibleRect.Width, visibleRect.Height);
- // if keyboard is snapped to the bottom of the screen and would cover the cursor the content is
- // moved up to make it visible
- if (keyboardRect.intersects(mCursorRect)
- && qFuzzyCompare(geometry().height(), keyboardRect.y() + keyboardRect.height())) {
- visibleRectF.moveTop(visibleRectF.top() - keyboardRect.height() / d->scaleFactor);
- }
- d->visibleRect = visibleRectF;
-
- qCDebug(lcQpaWindows) << __FUNCTION__ << d->visibleRect;
- QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry());
- QPlatformScreen::resizeMaximizedWindows();
- handleExpose();
-}
-
-QWindow *QWinRTScreen::topWindow() const
-{
- Q_D(const QWinRTScreen);
- return d->visibleWindows.isEmpty() ? 0 : d->visibleWindows.first();
-}
-
-QWindow *QWinRTScreen::windowAt(const QPoint &pos)
-{
- Q_D(const QWinRTScreen);
- for (auto w : qAsConst(d->visibleWindows)) {
- if (w->geometry().contains(pos))
- return w;
- }
- qCDebug(lcQpaWindows) << __FUNCTION__ << ": No window found at:" << pos;
- return nullptr;
-}
-
-void QWinRTScreen::addWindow(QWindow *window)
-{
- Q_D(QWinRTScreen);
- qCDebug(lcQpaWindows) << __FUNCTION__ << window;
- if (window == topWindow() || window->surfaceClass() == QSurface::Offscreen)
- return;
-
- d->visibleWindows.prepend(window);
- const Qt::WindowType type = window->type();
- if (type != Qt::Popup && type != Qt::ToolTip && type != Qt::Tool) {
- updateWindowTitle(window->title());
- QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason);
- }
-
- handleExpose();
- d->firstMouseMove = true;
- QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
-
-#if QT_CONFIG(draganddrop)
- QWinRTDrag::instance()->setDropTarget(window);
-#endif
-}
-
-void QWinRTScreen::removeWindow(QWindow *window)
-{
- Q_D(QWinRTScreen);
- qCDebug(lcQpaWindows) << __FUNCTION__ << window;
-
- handleExpose();
-
- const bool wasTopWindow = window == topWindow();
- if (!d->visibleWindows.removeAll(window))
- return;
-
- const Qt::WindowType type = window->type();
- if (wasTopWindow && type != Qt::Popup && type != Qt::ToolTip && type != Qt::Tool)
- QWindowSystemInterface::handleWindowActivated(nullptr, Qt::OtherFocusReason);
- QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
-#if QT_CONFIG(draganddrop)
- if (wasTopWindow)
- QWinRTDrag::instance()->setDropTarget(topWindow());
-#endif
-}
-
-void QWinRTScreen::raise(QWindow *window)
-{
- Q_D(QWinRTScreen);
- d->visibleWindows.removeAll(window);
- addWindow(window);
-}
-
-void QWinRTScreen::lower(QWindow *window)
-{
- Q_D(QWinRTScreen);
- const bool wasTopWindow = window == topWindow();
- if (wasTopWindow && d->visibleWindows.size() == 1)
- return;
- if (window->surfaceClass() == QSurface::Offscreen)
- return;
- d->visibleWindows.removeAll(window);
- d->visibleWindows.append(window);
- if (wasTopWindow)
- QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason);
- handleExpose();
-}
-
-bool QWinRTScreen::setMouseGrabWindow(QWinRTWindow *window, bool grab)
-{
- Q_D(QWinRTScreen);
- qCDebug(lcQpaWindows) << __FUNCTION__ << window
- << "(" << window->window()->objectName() << "):" << grab;
-
- if (!grab || window == nullptr)
- d->mouseGrabWindow = nullptr;
- else if (d->mouseGrabWindow != window)
- d->mouseGrabWindow = window;
- return grab;
-}
-
-QWinRTWindow *QWinRTScreen::mouseGrabWindow() const
-{
- Q_D(const QWinRTScreen);
- return d->mouseGrabWindow;
-}
-
-bool QWinRTScreen::setKeyboardGrabWindow(QWinRTWindow *window, bool grab)
-{
- Q_D(QWinRTScreen);
- qCDebug(lcQpaWindows) << __FUNCTION__ << window
- << "(" << window->window()->objectName() << "):" << grab;
-
- if (!grab || window == nullptr)
- d->keyboardGrabWindow = nullptr;
- else if (d->keyboardGrabWindow != window)
- d->keyboardGrabWindow = window;
- return grab;
-}
-
-QWinRTWindow *QWinRTScreen::keyboardGrabWindow() const
-{
- Q_D(const QWinRTScreen);
- return d->keyboardGrabWindow;
-}
-
-void QWinRTScreen::updateWindowTitle(const QString &title)
-{
- Q_D(QWinRTScreen);
-
- HStringReference titleRef(reinterpret_cast<LPCWSTR>(title.utf16()), title.length());
- HRESULT hr = d->view->put_Title(titleRef.Get());
- RETURN_VOID_IF_FAILED("Unable to set window title");
-}
-
-void QWinRTScreen::handleExpose()
-{
- Q_D(QWinRTScreen);
- if (d->visibleWindows.isEmpty())
- return;
- QList<QWindow *>::const_iterator it = d->visibleWindows.constBegin();
- QWindowSystemInterface::handleExposeEvent(*it, geometry());
- while (++it != d->visibleWindows.constEnd())
- QWindowSystemInterface::handleExposeEvent(*it, QRegion());
-}
-
-HRESULT QWinRTScreen::onKeyDown(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IKeyEventArgs *args)
-{
- Q_D(QWinRTScreen);
- VirtualKey virtualKey;
- HRESULT hr = args->get_VirtualKey(&virtualKey);
- Q_ASSERT_SUCCEEDED(hr);
- CorePhysicalKeyStatus status;
- hr = args->get_KeyStatus(&status);
- Q_ASSERT_SUCCEEDED(hr);
-
- Qt::Key key = qKeyFromVirtual(virtualKey);
-
- const bool wasPressed = d->activeKeys.contains(key);
- if (wasPressed) {
- if (!shouldAutoRepeat(key))
- return S_OK;
-
- d->activeKeys[key].isAutoRepeat = true;
- // If the key was pressed before trigger a key release before the next key press
- QWindowSystemInterface::handleExtendedKeyEvent(
- topWindow(),
- QEvent::KeyRelease,
- key,
- keyboardModifiers(),
- !status.ScanCode ? -1 : status.ScanCode,
- virtualKey,
- 0,
- QString(),
- d->activeKeys.value(key).isAutoRepeat);
- } else {
- d->activeKeys.insert(key, KeyInfo(virtualKey));
- }
-
- // Defer character key presses to onCharacterReceived
- if (key == Qt::Key_unknown || (key >= Qt::Key_Space && key <= Qt::Key_ydiaeresis))
- return S_OK;
-
- Qt::KeyboardModifiers modifiers = keyboardModifiers();
- // If the key actually pressed is a modifier key, then we remove its modifier key from the
- // state, since a modifier-key can't have itself as a modifier (see qwindowskeymapper.cpp)
- if (key == Qt::Key_Control)
- modifiers = modifiers ^ Qt::ControlModifier;
- else if (key == Qt::Key_Shift)
- modifiers = modifiers ^ Qt::ShiftModifier;
- else if (key == Qt::Key_Alt)
- modifiers = modifiers ^ Qt::AltModifier;
-
- QWindowSystemInterface::handleExtendedKeyEvent(
- topWindow(),
- QEvent::KeyPress,
- key,
- modifiers,
- !status.ScanCode ? -1 : status.ScanCode,
- virtualKey,
- 0,
- QString(),
- d->activeKeys.value(key).isAutoRepeat);
- return S_OK;
-}
-
-HRESULT QWinRTScreen::onKeyUp(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IKeyEventArgs *args)
-{
- Q_D(QWinRTScreen);
- VirtualKey virtualKey;
- HRESULT hr = args->get_VirtualKey(&virtualKey);
- Q_ASSERT_SUCCEEDED(hr);
- CorePhysicalKeyStatus status;
- hr = args->get_KeyStatus(&status);
- Q_ASSERT_SUCCEEDED(hr);
-
- Qt::Key key = qKeyFromVirtual(virtualKey);
- const KeyInfo info = d->activeKeys.take(key);
- QWindowSystemInterface::handleExtendedKeyEvent(
- topWindow(),
- QEvent::KeyRelease,
- key,
- keyboardModifiers(),
- !status.ScanCode ? -1 : status.ScanCode,
- virtualKey,
- 0,
- info.text,
- false); // The final key release does not have autoRepeat set on Windows
- return S_OK;
-}
-
-HRESULT QWinRTScreen::onCharacterReceived(ICoreWindow *, ICharacterReceivedEventArgs *args)
-{
- Q_D(QWinRTScreen);
- quint32 keyCode;
- HRESULT hr = args->get_KeyCode(&keyCode);
- Q_ASSERT_SUCCEEDED(hr);
- CorePhysicalKeyStatus status;
- hr = args->get_KeyStatus(&status);
- Q_ASSERT_SUCCEEDED(hr);
-
- // Don't generate character events for non-printables; the meta key stage is enough
- if (qIsNonPrintable(keyCode))
- return S_OK;
-
- const Qt::KeyboardModifiers modifiers = keyboardModifiers();
- const Qt::Key key = qKeyFromCode(keyCode, modifiers);
- const QString text = QChar(keyCode);
- KeyInfo &info = d->activeKeys[key];
- info.text = text;
- QWindowSystemInterface::handleExtendedKeyEvent(
- topWindow(),
- QEvent::KeyPress,
- key,
- modifiers,
- !status.ScanCode ? -1 : status.ScanCode,
- info.virtualKey,
- 0,
- text,
- info.isAutoRepeat);
- return S_OK;
-}
-
-HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *, IPointerEventArgs *args)
-{
- Q_D(QWinRTScreen);
- qCDebug(lcQpaEvents) << __FUNCTION__;
-
- ComPtr<IPointerPoint> pointerPoint;
- if (SUCCEEDED(args->get_CurrentPoint(&pointerPoint))) {
- // Assumes full-screen window
- Point point;
- pointerPoint->get_Position(&point);
- QPoint pos(point.X * d->scaleFactor, point.Y * d->scaleFactor);
-
- d->currentTargetWindow = topWindow();
- if (d->mouseGrabWindow)
- d->currentTargetWindow = d->mouseGrabWindow.loadRelaxed()->window();
-
- qCDebug(lcQpaEvents) << __FUNCTION__ << "handleEnterEvent" << d->currentTargetWindow << pos;
- QWindowSystemInterface::handleEnterEvent(d->currentTargetWindow, pos, pos);
- d->firstMouseMove = false;
- }
- return S_OK;
-}
-
-HRESULT QWinRTScreen::onPointerExited(ICoreWindow *, IPointerEventArgs *args)
-{
- Q_D(QWinRTScreen);
- qCDebug(lcQpaEvents) << __FUNCTION__;
- ComPtr<IPointerPoint> pointerPoint;
- if (FAILED(args->get_CurrentPoint(&pointerPoint)))
- return E_INVALIDARG;
-
- quint32 id;
- if (FAILED(pointerPoint->get_PointerId(&id)))
- return E_INVALIDARG;
-
- d->touchPoints.remove(id);
-
- if (d->mouseGrabWindow)
- d->currentTargetWindow = d->mouseGrabWindow.loadRelaxed()->window();
-
- qCDebug(lcQpaEvents) << __FUNCTION__ << "handleLeaveEvent" << d->currentTargetWindow;
- QWindowSystemInterface::handleLeaveEvent(d->currentTargetWindow);
- d->currentTargetWindow = nullptr;
- return S_OK;
-}
-
-// Required for qwinrtdrag.cpp
-ComPtr<IPointerPoint> qt_winrt_lastPointerPoint;
-
-HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
-{
- Q_D(QWinRTScreen);
- qCDebug(lcQpaEvents) << __FUNCTION__;
- ComPtr<IPointerPoint> pointerPoint;
- if (FAILED(args->get_CurrentPoint(&pointerPoint)))
- return E_INVALIDARG;
-
- qt_winrt_lastPointerPoint = pointerPoint;
- // Common traits - point, modifiers, properties
- Point point;
- pointerPoint->get_Position(&point);
- const QPointF pos(point.X * d->scaleFactor, point.Y * d->scaleFactor);
- QPointF localPos = pos;
-
- const QPoint posPoint = pos.toPoint();
- QWindow *windowUnderPointer = windowAt(QHighDpiScaling::mapPositionFromNative(posPoint, this));
- d->currentTargetWindow = windowUnderPointer;
-
- if (d->mouseGrabWindow)
- d->currentTargetWindow = d->mouseGrabWindow.loadRelaxed()->window();
-
- if (d->currentTargetWindow) {
- const QPointF globalPosDelta = pos - posPoint;
- localPos = d->currentTargetWindow->mapFromGlobal(posPoint) + globalPosDelta;
- }
-
- VirtualKeyModifiers modifiers;
- args->get_KeyModifiers(&modifiers);
- Qt::KeyboardModifiers mods;
- if (modifiers & VirtualKeyModifiers_Control)
- mods |= Qt::ControlModifier;
- if (modifiers & VirtualKeyModifiers_Menu)
- mods |= Qt::AltModifier;
- if (modifiers & VirtualKeyModifiers_Shift)
- mods |= Qt::ShiftModifier;
- if (modifiers & VirtualKeyModifiers_Windows)
- mods |= Qt::MetaModifier;
-
- ComPtr<IPointerPointProperties> properties;
- if (FAILED(pointerPoint->get_Properties(&properties)))
- return E_INVALIDARG;
-
- ComPtr<IPointerDevice> pointerDevice;
- HRESULT hr = pointerPoint->get_PointerDevice(&pointerDevice);
- RETURN_OK_IF_FAILED("Failed to get pointer device.");
-
- PointerDeviceType pointerDeviceType;
- hr = pointerDevice->get_PointerDeviceType(&pointerDeviceType);
- RETURN_OK_IF_FAILED("Failed to get pointer device type.");
-
- switch (pointerDeviceType) {
- case PointerDeviceType_Mouse: {
- qint32 delta;
- properties->get_MouseWheelDelta(&delta);
- if (delta) {
- boolean isHorizontal;
- properties->get_IsHorizontalMouseWheel(&isHorizontal);
- QPoint angleDelta(isHorizontal ? delta : 0, isHorizontal ? 0 : delta);
- qCDebug(lcQpaEvents) << __FUNCTION__ << "handleWheelEvent" << d->currentTargetWindow
- << localPos << pos << angleDelta << mods;
- QWindowSystemInterface::handleWheelEvent(d->currentTargetWindow, localPos, pos, QPoint(), angleDelta, mods);
- break;
- }
-
- boolean isPressed;
- Qt::MouseButtons buttons = Qt::NoButton;
- properties->get_IsLeftButtonPressed(&isPressed);
- if (isPressed)
- buttons |= Qt::LeftButton;
-
- properties->get_IsMiddleButtonPressed(&isPressed);
- if (isPressed)
- buttons |= Qt::MiddleButton;
-
- properties->get_IsRightButtonPressed(&isPressed);
- if (isPressed)
- buttons |= Qt::RightButton;
-
- properties->get_IsXButton1Pressed(&isPressed);
- if (isPressed)
- buttons |= Qt::XButton1;
-
- properties->get_IsXButton2Pressed(&isPressed);
- if (isPressed)
- buttons |= Qt::XButton2;
-
- // In case of a mouse grab we have to store the target of a press event
- // to be able to send one additional release event to this target when the mouse
- // button is released. This is a similar approach to AutoMouseCapture in the
- // windows qpa backend. Otherwise the release might not be propagated and the original
- // press event receiver considers a button to still be pressed, as in Qt Quick Controls 1
- // menus.
- if (buttons != Qt::NoButton && d->currentPressWindow == nullptr && !d->mouseGrabWindow)
- d->currentPressWindow = windowUnderPointer;
- if (buttons == Qt::NoButton && d->currentPressWindow && d->mouseGrabWindow) {
- const QPointF globalPosDelta = pos - posPoint;
- const QPointF localPressPos = d->currentPressWindow->mapFromGlobal(posPoint) + globalPosDelta;
-
- qCDebug(lcQpaEvents) << __FUNCTION__ << "handleMouseEvent" << d->currentPressWindow
- << localPressPos << pos << buttons << mods;
- QWindowSystemInterface::handleMouseEvent(d->currentPressWindow, localPressPos, pos, buttons, mods);
- d->currentPressWindow = nullptr;
- }
- // If the mouse button is released outside of a window, targetWindow is 0, but the event
- // has to be delivered to the window, that initially received the mouse press. Do not reset
- // d->currentTargetWindow though, as it is used (and reset) in onPointerExited.
- if (buttons == Qt::NoButton && d->currentPressWindow && !d->currentTargetWindow) {
- d->currentTargetWindow = d->currentPressWindow;
- d->currentPressWindow = nullptr;
- }
-
- qCDebug(lcQpaEvents) << __FUNCTION__ << "handleMouseEvent" << d->currentTargetWindow
- << localPos << pos << buttons << mods;
- QWindowSystemInterface::handleMouseEvent(d->currentTargetWindow, localPos, pos, buttons, mods);
-
- break;
- }
- case PointerDeviceType_Pen:
- case PointerDeviceType_Touch: {
- if (!d->touchDevice) {
- d->touchDevice = new QTouchDevice;
- d->touchDevice->setName(QStringLiteral("WinRTTouchScreen"));
- d->touchDevice->setType(QTouchDevice::TouchScreen);
- d->touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure | QTouchDevice::NormalizedPosition);
- QWindowSystemInterface::registerTouchDevice(d->touchDevice);
- }
-
- quint32 id;
- pointerPoint->get_PointerId(&id);
-
- Rect area;
- properties->get_ContactRect(&area);
-
- float pressure;
- properties->get_Pressure(&pressure);
-
- boolean isPressed;
- pointerPoint->get_IsInContact(&isPressed);
-
- // Devices like the Hololens set a static pressure of 0.0 or 0.5
- // (depending on the image) independent of the pressed state.
- // In those cases we need to synthesize the pressure value. To our
- // knowledge this does not apply to pens
- if (pointerDeviceType == PointerDeviceType_Touch && (pressure == 0.0f || pressure == 0.5f))
- pressure = isPressed ? 1. : 0.;
-
- const QRectF areaRect(area.X * d->scaleFactor, area.Y * d->scaleFactor,
- area.Width * d->scaleFactor, area.Height * d->scaleFactor);
-
- QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator it = d->touchPoints.find(id);
- if (it == d->touchPoints.end()) {
- it = d->touchPoints.insert(id, QWindowSystemInterface::TouchPoint());
- it.value().id = id;
- }
-
- const bool wasPressEvent = isPressed && it.value().pressure == 0.;
- if (wasPressEvent)
- it.value().state = Qt::TouchPointPressed;
- else if (!isPressed && it.value().pressure > 0.)
- it.value().state = Qt::TouchPointReleased;
- else if (it.value().area == areaRect)
- it.value().state = Qt::TouchPointStationary;
- else
- it.value().state = Qt::TouchPointMoved;
-
- it.value().area = areaRect;
- it.value().normalPosition = QPointF(point.X/d->logicalRect.width(), point.Y/d->logicalRect.height());
- it.value().pressure = pressure;
-
- qCDebug(lcQpaEvents) << __FUNCTION__ << "handleTouchEvent" << d->currentTargetWindow
- << d->touchDevice << d->touchPoints.values() << mods;
- QWindowSystemInterface::handleTouchEvent(d->currentTargetWindow, d->touchDevice, d->touchPoints.values(), mods);
- if (wasPressEvent)
- it.value().state = Qt::TouchPointStationary;
-
- // Fall-through for pen to generate tablet event
- if (pointerDeviceType != PointerDeviceType_Pen)
- break;
-
- boolean isEraser;
- properties->get_IsEraser(&isEraser);
- int pointerType = isEraser ? 3 : 1;
-
- float xTilt;
- properties->get_XTilt(&xTilt);
-
- float yTilt;
- properties->get_YTilt(&yTilt);
-
- float rotation;
- properties->get_Twist(&rotation);
-
- qCDebug(lcQpaEvents) << __FUNCTION__ << "handleTabletEvent" << d->currentTargetWindow
- << isPressed << pos << pointerType << pressure << xTilt << yTilt
- << rotation << id << mods;
- QWindowSystemInterface::handleTabletEvent(d->currentTargetWindow, isPressed, pos, pos, 0,
- pointerType, pressure, xTilt, yTilt,
- 0, rotation, 0, id, mods);
-
- break;
- }
- }
-
- return S_OK;
-}
-
-void QWinRTScreen::emulateMouseMove(const QPointF &point, MousePositionTransition transition)
-{
- Q_D(QWinRTScreen);
- qCDebug(lcQpaEvents) << __FUNCTION__ << point << transition;
- if (transition == MousePositionTransition::StayedOut)
- return;
- qt_winrt_lastPointerPoint = nullptr;
- const QPointF pos(point.x() * d->scaleFactor, point.y() * d->scaleFactor);
- QPointF localPos = pos;
-
- const QPoint posPoint = pos.toPoint();
- QWindow *windowUnderPointer = windowAt(QHighDpiScaling::mapPositionFromNative(posPoint, this));
- d->currentTargetWindow = windowUnderPointer;
-
- if (d->mouseGrabWindow)
- d->currentTargetWindow = d->mouseGrabWindow.loadRelaxed()->window();
-
- if (d->currentTargetWindow) {
- const QPointF globalPosDelta = pos - posPoint;
- localPos = d->currentTargetWindow->mapFromGlobal(posPoint) + globalPosDelta;
- }
-
- // In case of a mouse grab we have to store the target of a press event
- // to be able to send one additional release event to this target when the mouse
- // button is released. This is a similar approach to AutoMouseCapture in the
- // windows qpa backend. Otherwise the release might not be propagated and the original
- // press event receiver considers a button to still be pressed, as in Qt Quick Controls 1
- // menus.
- if (d->currentPressWindow && d->mouseGrabWindow) {
- const QPointF globalPosDelta = pos - posPoint;
- const QPointF localPressPos = d->currentPressWindow->mapFromGlobal(posPoint) + globalPosDelta;
-
- qCDebug(lcQpaEvents) << __FUNCTION__ << "handleMouseEvent" << d->currentPressWindow
- << localPressPos << pos << Qt::NoButton << Qt::NoModifier;
- QWindowSystemInterface::handleMouseEvent(d->currentPressWindow, localPressPos, pos,
- Qt::NoButton, Qt::NoModifier);
- d->currentPressWindow = nullptr;
- }
- // If the mouse button is released outside of a window, targetWindow is 0, but the event
- // has to be delivered to the window, that initially received the mouse press. Do not reset
- // d->currentTargetWindow though, as it is used (and reset) in onPointerExited.
- if (d->currentPressWindow && !d->currentTargetWindow) {
- d->currentTargetWindow = d->currentPressWindow;
- d->currentPressWindow = nullptr;
- }
-
- if (transition == MousePositionTransition::MovedOut) {
- qCDebug(lcQpaEvents) << __FUNCTION__ << "handleLeaveEvent" << d->currentTargetWindow;
- QWindowSystemInterface::handleLeaveEvent(d->currentTargetWindow);
- return;
- }
-
- if (transition == MousePositionTransition::MovedIn || d->firstMouseMove) {
- qCDebug(lcQpaEvents) << __FUNCTION__ << "handleEnterEvent" << d->currentTargetWindow
- << localPos << pos;
- QWindowSystemInterface::handleEnterEvent(d->currentTargetWindow, localPos, pos);
- d->firstMouseMove = false;
- }
- qCDebug(lcQpaEvents) << __FUNCTION__ << "handleMouseEvent" << d->currentTargetWindow
- << localPos << pos << Qt::NoButton << Qt::NoModifier;
- QWindowSystemInterface::handleMouseEvent(d->currentTargetWindow, localPos, pos, Qt::NoButton,
- Qt::NoModifier);
-}
-
-void QWinRTScreen::setResizePending()
-{
- Q_D(QWinRTScreen);
- d->resizePending = true;
-}
-
-bool QWinRTScreen::resizePending() const
-{
- Q_D(const QWinRTScreen);
- return d->resizePending;
-}
-
-HRESULT QWinRTScreen::onActivated(ICoreWindow *, IWindowActivatedEventArgs *args)
-{
- Q_D(QWinRTScreen);
- qCDebug(lcQpaWindows) << __FUNCTION__;
-
- CoreWindowActivationState activationState;
- args->get_WindowActivationState(&activationState);
- if (activationState == CoreWindowActivationState_Deactivated) {
- QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive);
- return S_OK;
- }
-
- QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive);
-
- // Activate topWindow
- if (!d->visibleWindows.isEmpty()) {
- Qt::FocusReason focusReason = activationState == CoreWindowActivationState_PointerActivated
- ? Qt::MouseFocusReason : Qt::ActiveWindowFocusReason;
- QWindowSystemInterface::handleWindowActivated(topWindow(), focusReason);
- }
- return S_OK;
-}
-
-HRESULT QWinRTScreen::onClosed(ICoreWindow *, ICoreWindowEventArgs *)
-{
- qCDebug(lcQpaWindows) << __FUNCTION__;
-
- foreach (QWindow *w, QGuiApplication::topLevelWindows())
- QWindowSystemInterface::handleCloseEvent(w);
- return S_OK;
-}
-
-HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *, IVisibilityChangedEventArgs *args)
-{
- Q_D(QWinRTScreen);
- boolean visible;
- HRESULT hr = args ? args->get_Visible(&visible) : d->coreWindow->get_Visible(&visible);
- RETURN_OK_IF_FAILED("Failed to get visibility.");
- qCDebug(lcQpaWindows) << __FUNCTION__ << visible;
- QWindowSystemInterface::handleApplicationStateChanged(visible ? Qt::ApplicationActive : Qt::ApplicationHidden);
- if (visible) {
- handleExpose();
- onWindowSizeChanged(nullptr, nullptr);
- }
- return S_OK;
-}
-
-HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable *)
-{
- Q_D(QWinRTScreen);
- qCDebug(lcQpaWindows) << __FUNCTION__;
- DisplayOrientations displayOrientation;
- HRESULT hr = d->displayInformation->get_CurrentOrientation(&displayOrientation);
- RETURN_OK_IF_FAILED("Failed to get current orientations.");
-
- Qt::ScreenOrientation newOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation)));
- if (d->orientation != newOrientation) {
- d->orientation = newOrientation;
- qCDebug(lcQpaWindows) << " New orientation:" << newOrientation;
- onWindowSizeChanged(nullptr, nullptr);
- QWindowSystemInterface::handleScreenOrientationChange(screen(), d->orientation);
- handleExpose(); // Clean broken frames caused by race between Qt and ANGLE
- }
- return S_OK;
-}
-
-HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *)
-{
- Q_D(QWinRTScreen);
-
- HRESULT hr;
- ResolutionScale resolutionScale;
- hr = d->displayInformation->get_ResolutionScale(&resolutionScale);
- d->scaleFactor = qreal(resolutionScale) / 100;
-
- qCDebug(lcQpaWindows) << __FUNCTION__ << "Scale Factor:" << d->scaleFactor;
-
- RETURN_OK_IF_FAILED("Failed to get scale factor");
-
- FLOAT dpi;
- hr = d->displayInformation->get_LogicalDpi(&dpi);
- RETURN_OK_IF_FAILED("Failed to get logical DPI.");
- d->logicalDpi = dpi;
-
- hr = d->displayInformation->get_RawDpiX(&dpi);
- RETURN_OK_IF_FAILED("Failed to get x raw DPI.");
- d->physicalDpi.first = dpi ? dpi : 96.0;
-
- hr = d->displayInformation->get_RawDpiY(&dpi);
- RETURN_OK_IF_FAILED("Failed to get y raw DPI.");
- d->physicalDpi.second = dpi ? dpi : 96.0;
- qCDebug(lcQpaWindows) << __FUNCTION__ << "Logical DPI:" << d->logicalDpi
- << "Physical DPI:" << d->physicalDpi;
-
- return S_OK;
-}
-
-HRESULT QWinRTScreen::onRedirectReleased(ICorePointerRedirector *, IPointerEventArgs *args)
-{
- // When dragging ends with a non-mouse input device then onRedirectRelease is invoked.
- // QTBUG-58781
- qCDebug(lcQpaEvents) << __FUNCTION__;
- return onPointerUpdated(nullptr, args);
-}
-
-HRESULT QWinRTScreen::onWindowSizeChanged(IApplicationView *w, IInspectable *)
-{
- Q_D(QWinRTScreen);
-
- HRESULT hr;
- Rect windowSize;
-
- hr = d->coreWindow->get_Bounds(&windowSize);
- RETURN_OK_IF_FAILED("Failed to get window bounds");
- d->logicalRect = QRectF(windowSize.X, windowSize.Y, windowSize.Width, windowSize.Height);
-
- Rect visibleRect;
- hr = d->view2->get_VisibleBounds(&visibleRect);
- RETURN_OK_IF_FAILED("Failed to get window visible bounds");
- d->visibleRect = QRectF(visibleRect.X, visibleRect.Y, visibleRect.Width, visibleRect.Height);
-
- qCDebug(lcQpaWindows) << __FUNCTION__ << d->logicalRect;
- QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry());
- QPlatformScreen::resizeMaximizedWindows();
- handleExpose();
- // If we "emulate" a resize, w will be nullptr.Checking w shows whether it's a real resize
- if (w)
- d->resizePending = false;
- return S_OK;
-}
-
-QT_END_NAMESPACE