diff options
Diffstat (limited to 'src/plugins/platforms/winrt')
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtcursor.cpp | 60 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtcursor.h | 24 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtintegration.cpp | 58 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp | 232 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtmessagedialoghelper.h (renamed from src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.h) | 29 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.cpp | 204 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtplatformtheme.cpp | 76 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtscreen.cpp | 544 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtscreen.h | 84 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtservices.cpp | 122 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtservices.h | 27 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrttheme.cpp | 211 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrttheme.h (renamed from src/plugins/platforms/winrt/qwinrtplatformtheme.h) | 20 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/winrt.pro | 10 |
14 files changed, 905 insertions, 796 deletions
diff --git a/src/plugins/platforms/winrt/qwinrtcursor.cpp b/src/plugins/platforms/winrt/qwinrtcursor.cpp index f09454ebc3..d2d87bde0b 100644 --- a/src/plugins/platforms/winrt/qwinrtcursor.cpp +++ b/src/plugins/platforms/winrt/qwinrtcursor.cpp @@ -40,40 +40,54 @@ ****************************************************************************/ #include "qwinrtcursor.h" +#include "qwinrtscreen.h" + +#include <QtCore/qfunctions_winrt.h> +#include <QtGui/QGuiApplication> +#include <QtGui/QScreen> #include <wrl.h> #include <windows.ui.core.h> #include <windows.foundation.h> +using namespace Microsoft::WRL; using namespace Microsoft::WRL::Wrappers; using namespace ABI::Windows::UI::Core; using namespace ABI::Windows::Foundation; -QT_BEGIN_NAMESPACE +QT_USE_NAMESPACE + +class QWinRTCursorPrivate +{ +public: + ComPtr<ICoreCursorFactory> cursorFactory; +}; -QWinRTCursor::QWinRTCursor(ICoreWindow *window) : m_window(window), m_cursorFactory(nullptr) +QWinRTCursor::QWinRTCursor() + : d_ptr(new QWinRTCursorPrivate) { -#ifndef Q_OS_WINPHONE - GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Core_CoreCursor).Get(), &m_cursorFactory); -#endif + Q_D(QWinRTCursor); + + HRESULT hr; + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Core_CoreCursor).Get(), + IID_PPV_ARGS(&d->cursorFactory)); + Q_ASSERT_SUCCEEDED(hr); } QWinRTCursor::~QWinRTCursor() { - if (m_cursorFactory) - m_cursorFactory->Release(); } #ifndef QT_NO_CURSOR -void QWinRTCursor::changeCursor(QCursor *windowCursor, QWindow *) +void QWinRTCursor::changeCursor(QCursor *windowCursor, QWindow *window) { -#ifndef Q_OS_WINPHONE - if (!m_cursorFactory) - return; + Q_D(QWinRTCursor); + + ICoreWindow *coreWindow = static_cast<QWinRTScreen *>(window->screen()->handle())->coreWindow(); CoreCursorType type; switch (windowCursor ? windowCursor->shape() : Qt::ArrowCursor) { case Qt::BlankCursor: - m_window->put_PointerCursor(nullptr); + coreWindow->put_PointerCursor(Q_NULLPTR); return; default: case Qt::OpenHandCursor: @@ -132,24 +146,20 @@ void QWinRTCursor::changeCursor(QCursor *windowCursor, QWindow *) break; } - ICoreCursor *cursor; - if (SUCCEEDED(m_cursorFactory->CreateCursor(type, 0, &cursor))) - m_window->put_PointerCursor(cursor); -#else // Q_OS_WINPHONE - Q_UNUSED(windowCursor) -#endif // Q_OS_WINPHONE + ComPtr<ICoreCursor> cursor; + HRESULT hr = d->cursorFactory->CreateCursor(type, 0, &cursor); + RETURN_VOID_IF_FAILED("Failed to create native cursor."); + + hr = coreWindow->put_PointerCursor(cursor.Get()); + RETURN_VOID_IF_FAILED("Failed to set native cursor."); } #endif // QT_NO_CURSOR QPoint QWinRTCursor::pos() const { -#ifdef Q_OS_WINPHONE - return QPlatformCursor::pos(); -#else + ICoreWindow *coreWindow = + static_cast<QWinRTScreen *>(QGuiApplication::primaryScreen()->handle())->coreWindow(); Point point; - m_window->get_PointerPosition(&point); + coreWindow->get_PointerPosition(&point); return QPoint(point.X, point.Y); -#endif } - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrtcursor.h b/src/plugins/platforms/winrt/qwinrtcursor.h index f7b301a98b..a08002f34c 100644 --- a/src/plugins/platforms/winrt/qwinrtcursor.h +++ b/src/plugins/platforms/winrt/qwinrtcursor.h @@ -44,34 +44,22 @@ #include <qpa/qplatformcursor.h> -namespace ABI { - namespace Windows { - namespace UI { - namespace Core { - struct ICoreWindow; - struct ICoreCursorFactory; - } - } - } -} - -QT_BEGIN_NAMESPACE +QT_USE_NAMESPACE +class QWinRTCursorPrivate; class QWinRTCursor : public QPlatformCursor { public: - explicit QWinRTCursor(ABI::Windows::UI::Core::ICoreWindow *window); + explicit QWinRTCursor(); ~QWinRTCursor(); #ifndef QT_NO_CURSOR - void changeCursor(QCursor * windowCursor, QWindow *); + void changeCursor(QCursor * windowCursor, QWindow *window); #endif QPoint pos() const; private: - ABI::Windows::UI::Core::ICoreWindow *m_window; - ABI::Windows::UI::Core::ICoreCursorFactory *m_cursorFactory; + QScopedPointer<QWinRTCursorPrivate> d_ptr; + Q_DECLARE_PRIVATE(QWinRTCursor) }; -QT_END_NAMESPACE - #endif // QWINRTCURSOR_H diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp index b3a2cafa2e..53d52a430c 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.cpp +++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp @@ -48,7 +48,7 @@ #include "qwinrtservices.h" #include "qwinrteglcontext.h" #include "qwinrtfontdatabase.h" -#include "qwinrtplatformtheme.h" +#include "qwinrttheme.h" #include <QtGui/QOpenGLContext> @@ -63,18 +63,6 @@ using namespace ABI::Windows::UI::Core; using namespace ABI::Windows::UI::ViewManagement; using namespace ABI::Windows::ApplicationModel::Core; -static IUISettings *getSettings() -{ - static IUISettings *settings = 0; - if (!settings) { - if (FAILED(RoActivateInstance(Wrappers::HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_UISettings).Get(), - reinterpret_cast<IInspectable **>(&settings)))) { - qWarning("Could not activate UISettings."); - } - } - return settings; -} - QT_BEGIN_NAMESPACE QWinRTIntegration::QWinRTIntegration() @@ -82,26 +70,7 @@ QWinRTIntegration::QWinRTIntegration() , m_fontDatabase(new QWinRTFontDatabase) , m_services(new QWinRTServices) { - // Obtain the WinRT Application, view, and window - ICoreApplication *application; - if (FAILED(RoGetActivationFactory(Wrappers::HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(), - IID_PPV_ARGS(&application)))) - qCritical("Could not attach to the application factory."); - - ICoreApplicationView *view; - if (FAILED(application->GetCurrentView(&view))) { - qCritical("Could not obtain the application view - have you started outside of WinRT?"); - return; - } - - // Get core window (will act as our screen) - ICoreWindow *window; - if (FAILED(view->get_CoreWindow(&window))) { - qCritical("Could not obtain the application window - have you started outside of WinRT?"); - return; - } - window->Activate(); - m_screen = new QWinRTScreen(window); + m_screen = new QWinRTScreen; screenAdded(m_screen); m_success = true; @@ -133,26 +102,7 @@ bool QWinRTIntegration::hasCapability(QPlatformIntegration::Capability cap) cons QVariant QWinRTIntegration::styleHint(StyleHint hint) const { - switch (hint) { - case CursorFlashTime: - if (IUISettings *settings = getSettings()) { - quint32 blinkRate; - settings->get_CaretBlinkRate(&blinkRate); - return blinkRate; - } - break; - case MouseDoubleClickInterval: - if (IUISettings *settings = getSettings()) { - quint32 doubleClickTime; - settings->get_DoubleClickTime(&doubleClickTime); - return doubleClickTime; - } - case ShowIsFullScreen: - return true; - default: - break; - } - return QPlatformIntegration::styleHint(hint); + return QWinRTTheme::styleHint(hint); } QPlatformWindow *QWinRTIntegration::createPlatformWindow(QWindow *window) const @@ -200,7 +150,7 @@ QPlatformTheme *QWinRTIntegration::createPlatformTheme(const QString & name) const { if (name == QLatin1String("winrt")) - return new QWinRTPlatformTheme(); + return new QWinRTTheme(); return 0; } diff --git a/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp b/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp new file mode 100644 index 0000000000..6de90ba1ec --- /dev/null +++ b/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp @@ -0,0 +1,232 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwinrtmessagedialoghelper.h" +#include "qwinrttheme.h" + +#include <QtCore/qfunctions_winrt.h> + +#include <windows.ui.popups.h> +#include <windows.foundation.h> +#include <windows.foundation.collections.h> +#include <wrl.h> + +using namespace ABI::Windows::Foundation; +using namespace ABI::Windows::Foundation::Collections; +using namespace ABI::Windows::UI::Popups; +using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; + +typedef IAsyncOperationCompletedHandler<IUICommand *> DialogCompletedHandler; + +QT_BEGIN_NAMESPACE + +class CommandId : public RuntimeClass<IInspectable> +{ +public: + CommandId(QPlatformDialogHelper::StandardButton button) + : button(button) { } + QPlatformDialogHelper::StandardButton button; +}; + +class QWinRTMessageDialogHelperPrivate +{ +public: + const QWinRTTheme *theme; + bool shown; + ComPtr<IAsyncInfo> info; + QEventLoop loop; +}; + +QWinRTMessageDialogHelper::QWinRTMessageDialogHelper(const QWinRTTheme *theme) + : QPlatformMessageDialogHelper(), d_ptr(new QWinRTMessageDialogHelperPrivate) +{ + Q_D(QWinRTMessageDialogHelper); + + d->theme = theme; + d->shown = false; +} + +QWinRTMessageDialogHelper::~QWinRTMessageDialogHelper() +{ + Q_D(QWinRTMessageDialogHelper); + + if (d->shown) + hide(); +} + +void QWinRTMessageDialogHelper::exec() +{ + Q_D(QWinRTMessageDialogHelper); + + if (!d->shown) + show(Qt::Dialog, Qt::ApplicationModal, 0); + d->loop.exec(); +} + +bool QWinRTMessageDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) +{ + Q_UNUSED(windowFlags) + Q_UNUSED(windowModality) + Q_UNUSED(parent) + Q_D(QWinRTMessageDialogHelper); + + QSharedPointer<QMessageDialogOptions> options = this->options(); + const QString informativeText = options->informativeText(); + const QString title = options->windowTitle(); + const QString text = informativeText.isEmpty() ? options->text() : (options->text() + QLatin1Char('\n') + informativeText); + + HRESULT hr; + ComPtr<IMessageDialogFactory> dialogFactory; + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Popups_MessageDialog).Get(), + IID_PPV_ARGS(&dialogFactory)); + RETURN_FALSE_IF_FAILED("Failed to create dialog factory"); + + ComPtr<IUICommandFactory> commandFactory; + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Popups_UICommand).Get(), + IID_PPV_ARGS(&commandFactory)); + RETURN_FALSE_IF_FAILED("Failed to create command factory"); + + ComPtr<IMessageDialog> dialog; + HStringReference nativeText(reinterpret_cast<LPCWSTR>(text.utf16()), text.size()); + if (!title.isEmpty()) { + HStringReference nativeTitle(reinterpret_cast<LPCWSTR>(title.utf16()), title.size()); + hr = dialogFactory->CreateWithTitle(nativeText.Get(), nativeTitle.Get(), &dialog); + RETURN_FALSE_IF_FAILED("Failed to create dialog with title"); + } else { + hr = dialogFactory->Create(nativeText.Get(), &dialog); + RETURN_FALSE_IF_FAILED("Failed to create dialog"); + } + + // Add Buttons + ComPtr<IVector<IUICommand *>> dialogCommands; + hr = dialog->get_Commands(&dialogCommands); + RETURN_FALSE_IF_FAILED("Failed to get dialog commands"); + + // If no button is specified we need to create one to get close notification + int buttons = options->standardButtons(); + if (buttons == 0) + buttons = Ok; + + for (int i = FirstButton; i < LastButton; i<<=1) { + if (!(buttons & i)) + continue; + // Add native command + const QString label = d->theme->standardButtonText(i); + HStringReference nativeLabel(reinterpret_cast<LPCWSTR>(label.utf16()), label.size()); + ComPtr<IUICommand> command; + hr = commandFactory->Create(nativeLabel.Get(), &command); + RETURN_FALSE_IF_FAILED("Failed to create message box command"); + ComPtr<IInspectable> id = Make<CommandId>(static_cast<StandardButton>(i)); + hr = command->put_Id(id.Get()); + RETURN_FALSE_IF_FAILED("Failed to set command ID"); + hr = dialogCommands->Append(command.Get()); + if (hr == E_BOUNDS) { + qErrnoWarning(hr, "The WinRT message dialog supports a maximum of three buttons"); + continue; + } + RETURN_FALSE_IF_FAILED("Failed to append message box command"); + if (i == Abort || i == Cancel || i == Close) { + quint32 size; + hr = dialogCommands->get_Size(&size); + RETURN_FALSE_IF_FAILED("Failed to get command list size"); + hr = dialog->put_CancelCommandIndex(size - 1); + RETURN_FALSE_IF_FAILED("Failed to set cancel index"); + } + } + + ComPtr<IAsyncOperation<IUICommand *>> op; + hr = dialog->ShowAsync(&op); + RETURN_FALSE_IF_FAILED("Failed to show dialog"); + hr = op->put_Completed(Callback<DialogCompletedHandler>(this, &QWinRTMessageDialogHelper::onCompleted).Get()); + RETURN_FALSE_IF_FAILED("Failed to set dialog callback"); + + d->shown = true; + hr = op.As(&d->info); + RETURN_FALSE_IF_FAILED("Failed to acquire AsyncInfo for MessageDialog"); + + return true; +} + +void QWinRTMessageDialogHelper::hide() +{ + Q_D(QWinRTMessageDialogHelper); + + if (!d->shown) + return; + + HRESULT hr = d->info->Cancel(); + if (FAILED(hr)) + qErrnoWarning(hr, "Failed to cancel dialog operation"); + + d->shown = false; +} + +HRESULT QWinRTMessageDialogHelper::onCompleted(IAsyncOperation<IUICommand *> *asyncInfo, AsyncStatus status) +{ + Q_UNUSED(status); + Q_D(QWinRTMessageDialogHelper); + + if (d->loop.isRunning()) + d->loop.exit(); + + d->shown = false; + + if (status == Canceled) { + emit reject(); + return S_OK; + } + + HRESULT hr; + ComPtr<IUICommand> command; + hr = asyncInfo->GetResults(&command); + RETURN_OK_IF_FAILED("Failed to get command"); + + ComPtr<CommandId> id; + hr = command->get_Id(&id); + RETURN_OK_IF_FAILED("Failed to get command ID"); + + ButtonRole role = buttonRole(id->button); + emit clicked(id->button, role); + return S_OK; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.h b/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.h index fbb21ed69c..25199e569c 100644 --- a/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.h +++ b/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.h @@ -39,11 +39,10 @@ ** ****************************************************************************/ -#ifndef QWINRTPLATFORMMESSAGEDIALOGHELPER_H -#define QWINRTPLATFORMMESSAGEDIALOGHELPER_H +#ifndef QWINRTMESSAGEDIALOGHELPER_H +#define QWINRTMESSAGEDIALOGHELPER_H #include <qpa/qplatformdialoghelper.h> -#include <QtCore/QEventLoop> #include <QtCore/qt_windows.h> namespace ABI { @@ -53,19 +52,24 @@ namespace ABI { struct IUICommand; } } + namespace Foundation { + enum class AsyncStatus; + template <typename T> struct IAsyncOperation; + } } } QT_BEGIN_NAMESPACE -struct QWinRTPlatformMessageDialogInfo; +class QWinRTTheme; -class QWinRTPlatformMessageDialogHelper : public QPlatformMessageDialogHelper +class QWinRTMessageDialogHelperPrivate; +class QWinRTMessageDialogHelper : public QPlatformMessageDialogHelper { Q_OBJECT public: - explicit QWinRTPlatformMessageDialogHelper(); - ~QWinRTPlatformMessageDialogHelper(); + explicit QWinRTMessageDialogHelper(const QWinRTTheme *theme); + ~QWinRTMessageDialogHelper(); void exec(); bool show(Qt::WindowFlags windowFlags, @@ -73,13 +77,14 @@ public: QWindow *parent); void hide(); - HRESULT onInvoked(ABI::Windows::UI::Popups::IUICommand *command); private: - QWinRTPlatformMessageDialogInfo *m_info; - QEventLoop m_loop; - bool m_shown; + HRESULT onCompleted(ABI::Windows::Foundation::IAsyncOperation<ABI::Windows::UI::Popups::IUICommand *> *asyncInfo, + ABI::Windows::Foundation::AsyncStatus status); + + QScopedPointer<QWinRTMessageDialogHelperPrivate> d_ptr; + Q_DECLARE_PRIVATE(QWinRTMessageDialogHelper) }; QT_END_NAMESPACE -#endif // QWINRTPLATFORMMESSAGEDIALOGHELPER_H +#endif // QWINRTMESSAGEDIALOGHELPER_H diff --git a/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.cpp b/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.cpp deleted file mode 100644 index c2f884055d..0000000000 --- a/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwinrtplatformmessagedialoghelper.h" - -#include <QtGui/QGuiApplication> -#include <private/qguiapplication_p.h> -#include <qpa/qplatformtheme.h> - -#include <asyncinfo.h> -#include <windows.ui.popups.h> -#include <windows.foundation.h> -#include <windows.foundation.collections.h> -#include <wrl.h> - -using namespace ABI::Windows::Foundation; -using namespace ABI::Windows::Foundation::Collections; -using namespace ABI::Windows::UI::Popups; -using namespace Microsoft::WRL; -using namespace Microsoft::WRL::Wrappers; - -QT_BEGIN_NAMESPACE - -struct QWinRTPlatformMessageDialogInfo -{ - ComPtr<IAsyncInfo> info; -}; - -QWinRTPlatformMessageDialogHelper::QWinRTPlatformMessageDialogHelper() : - QPlatformMessageDialogHelper(), - m_info(new QWinRTPlatformMessageDialogInfo), - m_shown(false) -{ -} - -QWinRTPlatformMessageDialogHelper::~QWinRTPlatformMessageDialogHelper() -{ - if (m_shown) - hide(); - delete m_info; -} - -void QWinRTPlatformMessageDialogHelper::exec() -{ - if (!m_shown) - show(Qt::Dialog, Qt::ApplicationModal, 0); - m_loop.exec(); -} - -bool QWinRTPlatformMessageDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) -{ - Q_UNUSED(windowFlags) - Q_UNUSED(windowModality) - Q_UNUSED(parent) - - QSharedPointer<QMessageDialogOptions> options = this->options(); - - const QString informativeText = options->informativeText(); - const QString title = options->windowTitle(); - const QString text = informativeText.isEmpty() ? options->text() : (options->text() + QLatin1Char('\n') + informativeText); - - - ComPtr<IMessageDialogFactory> dialogFactory; - if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Popups_MessageDialog).Get(), &dialogFactory))) - return false; - - ComPtr<IUICommandFactory> commandFactory; - if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Popups_UICommand).Get(), &commandFactory))) - return false; - - HString nativeText; - nativeText.Set(reinterpret_cast<LPCWSTR>(text.utf16()), text.size()); - ComPtr<IMessageDialog> dialog; - - if (!title.isEmpty()) { - HString nativeTitle; - nativeTitle.Set(reinterpret_cast<LPCWSTR>(title.utf16()), title.size()); - if (FAILED(dialogFactory->CreateWithTitle(nativeText.Get(), nativeTitle.Get(), &dialog))) - return false; - } else { - if (FAILED(dialogFactory->Create(nativeText.Get(), &dialog))) - return false; - } - - // Add Buttons - ComPtr<IVector<IUICommand*> > dialogCommands; - if (FAILED(dialog->get_Commands(&dialogCommands))) - return false; - - // If no button is specified we need to create one to get close notification - int buttons = options->standardButtons(); - if (buttons == 0) - buttons = QPlatformDialogHelper::Ok; - - for (int i = QPlatformDialogHelper::FirstButton; i < QPlatformDialogHelper::LastButton; i<<=1) { - if (buttons & i) { - // Add native command - const QString label = QGuiApplicationPrivate::platformTheme()->standardButtonText(i); - - HString hLabel; - hLabel.Set(reinterpret_cast<LPCWSTR>(label.utf16()), label.size()); - - ABI::Windows::UI::Popups::IUICommand *command; - if (FAILED(commandFactory->CreateWithHandler(hLabel.Get(), - Callback<IUICommandInvokedHandler>(this, &QWinRTPlatformMessageDialogHelper::onInvoked).Get(), - &command))) - return false; - dialogCommands->Append(command); - } - } - - ComPtr<IAsyncOperation<IUICommand*> > op; - if (FAILED(dialog->ShowAsync(&op))) - return false; - - m_shown = true; - if (FAILED(op.As(&m_info->info))) { - m_shown = false; - // The dialog is shown already, so we cannot return false - qWarning("Failed to acquire AsyncInfo for MessageDialog"); - } - return true; -} - -void QWinRTPlatformMessageDialogHelper::hide() -{ - if (!m_shown) - return; - - m_info->info->Cancel(); - m_shown = false; -} - -HRESULT QWinRTPlatformMessageDialogHelper::onInvoked(ABI::Windows::UI::Popups::IUICommand *command) -{ - HString hLabel; - UINT32 labelLength; - command->get_Label(hLabel.GetAddressOf()); - PCWSTR rawString = hLabel.GetRawBuffer(&labelLength); - QString label = QString::fromWCharArray(rawString, labelLength); - int buttonId = -1; - for (int i = QPlatformDialogHelper::FirstButton; i < QPlatformDialogHelper::LastButton; i<<=1) { - if ( options()->standardButtons() & i ) { - if (QGuiApplicationPrivate::platformTheme()->standardButtonText(i) == label) { - buttonId = i; - break; - } - } - } - if (m_loop.isRunning()) - m_loop.exit(); - - m_shown = false; - - if (buttonId < 0) { - emit reject(); - return S_OK; - } - - QPlatformDialogHelper::StandardButton standardButton = static_cast<QPlatformDialogHelper::StandardButton>(buttonId); - QPlatformDialogHelper::ButtonRole role = QPlatformDialogHelper::buttonRole(standardButton); - emit clicked(standardButton, role); - return S_OK; -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrtplatformtheme.cpp b/src/plugins/platforms/winrt/qwinrtplatformtheme.cpp deleted file mode 100644 index d4034ec571..0000000000 --- a/src/plugins/platforms/winrt/qwinrtplatformtheme.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwinrtplatformtheme.h" -#include "qwinrtplatformmessagedialoghelper.h" - -QT_BEGIN_NAMESPACE - -QWinRTPlatformTheme::QWinRTPlatformTheme() -{ -} - -bool QWinRTPlatformTheme::usePlatformNativeDialog(QPlatformTheme::DialogType type) const -{ -#if !(defined(Q_OS_WINPHONE) && _MSC_VER<=1700) - if (type == QPlatformTheme::MessageDialog) - return true; -#else - Q_UNUSED(type) -#endif // !(Q_OS_WINPHONE && _MSC_VER<=1700) - return false; -} - -QPlatformDialogHelper *QWinRTPlatformTheme::createPlatformDialogHelper(QPlatformTheme::DialogType type) const -{ -#if !(defined(Q_OS_WINPHONE) && _MSC_VER<=1700) - switch (type) { - case QPlatformTheme::MessageDialog: - return new QWinRTPlatformMessageDialogHelper(); - default: - return QPlatformTheme::createPlatformDialogHelper(type); - } -#else // !(Q_OS_WINPHONE && _MSC_VER<=1700) - return QPlatformTheme::createPlatformDialogHelper(type); -#endif // Q_OS_WINPHONE && _MSC_VER<=1700 -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index f948cf9924..cbc7449591 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -51,6 +51,7 @@ #include <QtPlatformSupport/private/qeglconvenience_p.h> #include <qpa/qwindowsysteminterface.h> #include <QtCore/qt_windows.h> +#include <QtCore/qfunctions_winrt.h> #include <wrl.h> #include <windows.system.h> @@ -93,11 +94,7 @@ typedef ITypedEventHandler<CoreWindow*, PointerEventArgs*> PointerHandler; typedef ITypedEventHandler<CoreWindow*, WindowSizeChangedEventArgs*> SizeChangedHandler; typedef ITypedEventHandler<CoreWindow*, VisibilityChangedEventArgs*> VisibilityChangedHandler; typedef ITypedEventHandler<CoreWindow*, AutomationProviderRequestedEventArgs*> AutomationProviderRequestedHandler; -#if _MSC_VER <=1700 -typedef IDisplayPropertiesEventHandler DisplayInformationHandler; -#else typedef ITypedEventHandler<DisplayInformation*, IInspectable*> DisplayInformationHandler; -#endif #ifdef Q_OS_WINPHONE typedef IEventHandler<BackPressedEventArgs*> BackPressedHandler; #endif @@ -419,199 +416,272 @@ static inline Qt::Key qKeyFromCode(quint32 code, int mods) return static_cast<Qt::Key>(code & 0xff); } -QWinRTScreen::QWinRTScreen(ICoreWindow *window) - : m_coreWindow(window) - , m_depth(32) - , m_format(QImage::Format_ARGB32_Premultiplied) +typedef HRESULT (__stdcall ICoreApplication::*CoreApplicationCallbackRemover)(EventRegistrationToken); +uint qHash(CoreApplicationCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); } +typedef HRESULT (__stdcall ICoreWindow::*CoreWindowCallbackRemover)(EventRegistrationToken); +uint qHash(CoreWindowCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); } +typedef HRESULT (__stdcall IDisplayInformation::*DisplayCallbackRemover)(EventRegistrationToken); +uint qHash(DisplayCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); } +#ifdef Q_OS_WINPHONE +typedef HRESULT (__stdcall IHardwareButtonsStatics::*HardwareButtonsCallbackRemover)(EventRegistrationToken); +uint qHash(HardwareButtonsCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); } +#endif + +class QWinRTScreenPrivate +{ +public: + ComPtr<ICoreApplication> application; + ComPtr<ICoreWindow> coreWindow; + ComPtr<IDisplayInformationStatics> displayInformationStatics; + ComPtr<IDisplayInformation> displayInformation; #ifdef Q_OS_WINPHONE - , m_inputContext(new QWinRTInputContext(m_coreWindow)) + ComPtr<IHardwareButtonsStatics> hardwareButtons; +#endif + + QScopedPointer<QWinRTCursor> cursor; +#ifdef Q_OS_WINPHONE + QScopedPointer<QWinRTInputContext> inputContext; #else - , m_inputContext(Make<QWinRTInputContext>(m_coreWindow).Detach()) + ComPtr<QWinRTInputContext> inputContext; +#endif + + QRectF geometry; + QSurfaceFormat surfaceFormat; + qreal dpi; + qreal devicePixelRatio; + Qt::ScreenOrientation nativeOrientation; + Qt::ScreenOrientation orientation; + QList<QWindow *> visibleWindows; +#ifndef Q_OS_WINPHONE + QHash<quint32, QPair<Qt::Key, QString>> activeKeys; +#endif + QTouchDevice *touchDevice; + QHash<quint32, QWindowSystemInterface::TouchPoint> touchPoints; + + EGLDisplay eglDisplay; + EGLSurface eglSurface; + + QHash<CoreApplicationCallbackRemover, EventRegistrationToken> applicationTokens; + QHash<CoreWindowCallbackRemover, EventRegistrationToken> windowTokens; + QHash<DisplayCallbackRemover, EventRegistrationToken> displayTokens; +#ifdef Q_OS_WINPHONE + QHash<HardwareButtonsCallbackRemover, EventRegistrationToken> buttonsTokens; #endif - , m_cursor(new QWinRTCursor(window)) - , m_devicePixelRatio(1.0) - , m_orientation(Qt::PrimaryOrientation) - , m_touchDevice(Q_NULLPTR) +}; + +QWinRTScreen::QWinRTScreen() + : d_ptr(new QWinRTScreenPrivate) { + Q_D(QWinRTScreen); + d->orientation = Qt::PrimaryOrientation; + d->touchDevice = Q_NULLPTR; + + // Obtain the WinRT Application, view, and window + HRESULT hr; + hr = RoGetActivationFactory(Wrappers::HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(), + IID_PPV_ARGS(&d->application)); + Q_ASSERT_SUCCEEDED(hr); + hr = d->application->add_Suspending(Callback<SuspendHandler>(this, &QWinRTScreen::onSuspended).Get(), &d->applicationTokens[&ICoreApplication::remove_Resuming]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->application->add_Resuming(Callback<ResumeHandler>(this, &QWinRTScreen::onResume).Get(), &d->applicationTokens[&ICoreApplication::remove_Resuming]); + Q_ASSERT_SUCCEEDED(hr); + + ComPtr<ICoreApplicationView> view; + hr = d->application->GetCurrentView(&view); + Q_ASSERT_SUCCEEDED(hr); + hr = view->get_CoreWindow(&d->coreWindow); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->Activate(); + Q_ASSERT_SUCCEEDED(hr); + +#ifdef Q_OS_WINPHONE + d->inputContext.reset(new QWinRTInputContext(d->coreWindow.Get())); +#else + d->inputContext = Make<QWinRTInputContext>(d->coreWindow.Get()); +#endif + Rect rect; - window->get_Bounds(&rect); - m_geometry = QRectF(0, 0, rect.Width, rect.Height); - - m_surfaceFormat.setAlphaBufferSize(0); - m_surfaceFormat.setRedBufferSize(8); - m_surfaceFormat.setGreenBufferSize(8); - m_surfaceFormat.setBlueBufferSize(8); - - m_surfaceFormat.setRenderableType(QSurfaceFormat::OpenGLES); - m_surfaceFormat.setSamples(1); - m_surfaceFormat.setSwapBehavior(QSurfaceFormat::DoubleBuffer); - m_surfaceFormat.setDepthBufferSize(24); - m_surfaceFormat.setStencilBufferSize(8); - - m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); - if (m_eglDisplay == EGL_NO_DISPLAY) + d->coreWindow->get_Bounds(&rect); + d->geometry = QRectF(0, 0, rect.Width, rect.Height); + + d->surfaceFormat.setAlphaBufferSize(0); + d->surfaceFormat.setRedBufferSize(8); + d->surfaceFormat.setGreenBufferSize(8); + d->surfaceFormat.setBlueBufferSize(8); + d->surfaceFormat.setRenderableType(QSurfaceFormat::OpenGLES); + d->surfaceFormat.setSamples(1); + d->surfaceFormat.setSwapBehavior(QSurfaceFormat::DoubleBuffer); + d->surfaceFormat.setDepthBufferSize(24); + d->surfaceFormat.setStencilBufferSize(8); + + d->eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (d->eglDisplay == EGL_NO_DISPLAY) qFatal("Qt WinRT platform plugin: failed to initialize EGL display."); - if (!eglInitialize(m_eglDisplay, NULL, NULL)) + if (!eglInitialize(d->eglDisplay, NULL, NULL)) qFatal("Qt WinRT platform plugin: failed to initialize EGL. This can happen if you haven't included the D3D compiler DLL in your application package."); // TODO: move this to Window - m_eglSurface = eglCreateWindowSurface(m_eglDisplay, q_configFromGLFormat(m_eglDisplay, m_surfaceFormat), window, NULL); - if (m_eglSurface == EGL_NO_SURFACE) + d->eglSurface = eglCreateWindowSurface(d->eglDisplay, q_configFromGLFormat(d->eglDisplay, d->surfaceFormat), d->coreWindow.Get(), NULL); + if (d->eglSurface == EGL_NO_SURFACE) qFatal("Could not create EGL surface, error 0x%X", eglGetError()); - // Event handlers mapped to QEvents - m_coreWindow->add_KeyDown(Callback<KeyHandler>(this, &QWinRTScreen::onKeyDown).Get(), &m_tokens[QEvent::KeyPress]); - m_coreWindow->add_KeyUp(Callback<KeyHandler>(this, &QWinRTScreen::onKeyUp).Get(), &m_tokens[QEvent::KeyRelease]); - m_coreWindow->add_CharacterReceived(Callback<CharacterReceivedHandler>(this, &QWinRTScreen::onCharacterReceived).Get(), &m_tokens[QEvent::User]); - m_coreWindow->add_PointerEntered(Callback<PointerHandler>(this, &QWinRTScreen::onPointerEntered).Get(), &m_tokens[QEvent::Enter]); - m_coreWindow->add_PointerExited(Callback<PointerHandler>(this, &QWinRTScreen::onPointerExited).Get(), &m_tokens[QEvent::Leave]); - m_coreWindow->add_PointerMoved(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::MouseMove]); - m_coreWindow->add_PointerPressed(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::MouseButtonPress]); - m_coreWindow->add_PointerReleased(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::MouseButtonRelease]); - m_coreWindow->add_PointerWheelChanged(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::Wheel]); - m_coreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &QWinRTScreen::onSizeChanged).Get(), &m_tokens[QEvent::Resize]); + 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->coreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &QWinRTScreen::onSizeChanged).Get(), &d->windowTokens[&ICoreWindow::remove_SizeChanged]); + 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->coreWindow->add_AutomationProviderRequested(Callback<AutomationProviderRequestedHandler>(this, &QWinRTScreen::onAutomationProviderRequested).Get(), &d->windowTokens[&ICoreWindow::remove_AutomationProviderRequested]); + Q_ASSERT_SUCCEEDED(hr); #ifdef Q_OS_WINPHONE - ComPtr<IHardwareButtonsStatics> hardwareButtons; - if (SUCCEEDED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Phone_UI_Input_HardwareButtons).Get(), &hardwareButtons))) - hardwareButtons->add_BackPressed(Callback<BackPressedHandler>(this, &QWinRTScreen::onBackButtonPressed).Get(), &m_tokens[QEvent::User]); + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Phone_UI_Input_HardwareButtons).Get(), IID_PPV_ARGS(&d->hardwareButtons)); + Q_ASSERT_SUCCEEDED(hr); + hr = d->hardwareButtons->add_BackPressed(Callback<BackPressedHandler>(this, &QWinRTScreen::onBackButtonPressed).Get(), &d->buttonsTokens[&IHardwareButtonsStatics::remove_BackPressed]); + Q_ASSERT_SUCCEEDED(hr); #endif // Q_OS_WINPHONE - // Window event handlers - m_coreWindow->add_Activated(Callback<ActivatedHandler>(this, &QWinRTScreen::onActivated).Get(), &m_tokens[QEvent::WindowActivate]); - m_coreWindow->add_Closed(Callback<ClosedHandler>(this, &QWinRTScreen::onClosed).Get(), &m_tokens[QEvent::WindowDeactivate]); - m_coreWindow->add_VisibilityChanged(Callback<VisibilityChangedHandler>(this, &QWinRTScreen::onVisibilityChanged).Get(), &m_tokens[QEvent::Show]); - m_coreWindow->add_AutomationProviderRequested(Callback<AutomationProviderRequestedHandler>(this, &QWinRTScreen::onAutomationProviderRequested).Get(), &m_tokens[QEvent::InputMethodQuery]); - // Orientation handling -#if _MSC_VER<=1700 - HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), - &m_displayInformation); -#else - HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayInformation).Get(), - &m_displayInformationFactory); - if (FAILED(hr)) { - qErrnoWarning(hr, "Failed to get display information factory."); - return; - } + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayInformation).Get(), + IID_PPV_ARGS(&d->displayInformationStatics)); + Q_ASSERT_SUCCEEDED(hr); - hr = m_displayInformationFactory->GetForCurrentView(&m_displayInformation); -#endif - - if (FAILED(hr)) { - qErrnoWarning(hr, "Failed to get display information for the current view."); - return; - } + hr = d->displayInformationStatics->GetForCurrentView(&d->displayInformation); + Q_ASSERT_SUCCEEDED(hr); // Set native orientation DisplayOrientations displayOrientation; - hr = m_displayInformation->get_NativeOrientation(&displayOrientation); - if (FAILED(hr)) { - qErrnoWarning(hr, "Failed to get native orientation."); - return; - } + hr = d->displayInformation->get_NativeOrientation(&displayOrientation); + Q_ASSERT_SUCCEEDED(hr); + d->nativeOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation))); - m_nativeOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation))); + hr = d->displayInformation->add_OrientationChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onOrientationChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_OrientationChanged]); + Q_ASSERT_SUCCEEDED(hr); - hr = m_displayInformation->add_OrientationChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onOrientationChanged).Get(), - &m_tokens[QEvent::OrientationChange]); - if (FAILED(hr)) { - qErrnoWarning(hr, "Failed to add orientation change callback."); - return; - } - -#if _MSC_VER<=1700 - hr = m_displayInformation->add_LogicalDpiChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onDpiChanged).Get(), - &m_tokens[QEvent::Type(QEvent::User + 1)]); -#else - hr = m_displayInformation->add_DpiChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onDpiChanged).Get(), - &m_tokens[QEvent::Type(QEvent::User + 1)]); -#endif - if (FAILED(hr)) { - qErrnoWarning(hr, "Failed to add logical dpi change callback."); - return; - } + hr = d->displayInformation->add_DpiChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onDpiChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_DpiChanged]); + Q_ASSERT_SUCCEEDED(hr); // Set initial orientation & pixel density -#if _MSC_VER<=1700 - onOrientationChanged(Q_NULLPTR); - onDpiChanged(Q_NULLPTR); -#else onOrientationChanged(Q_NULLPTR, Q_NULLPTR); onDpiChanged(Q_NULLPTR, Q_NULLPTR); -#endif - setOrientationUpdateMask(m_nativeOrientation); + setOrientationUpdateMask(d->nativeOrientation); +} - if (SUCCEEDED(RoGetActivationFactory(Wrappers::HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(), - IID_PPV_ARGS(&m_application)))) { - m_application->add_Suspending(Callback<SuspendHandler>(this, &QWinRTScreen::onSuspended).Get(), &m_suspendTokens[Qt::ApplicationSuspended]); - m_application->add_Resuming(Callback<ResumeHandler>(this, &QWinRTScreen::onResume).Get(), &m_suspendTokens[Qt::ApplicationHidden]); - } +QWinRTScreen::~QWinRTScreen() +{ + Q_D(QWinRTScreen); + + // Unregister callbacks + for (QHash<CoreApplicationCallbackRemover, EventRegistrationToken>::const_iterator i = d->applicationTokens.begin(); i != d->applicationTokens.end(); ++i) + (d->application.Get()->*i.key())(i.value()); + for (QHash<CoreWindowCallbackRemover, EventRegistrationToken>::const_iterator i = d->windowTokens.begin(); i != d->windowTokens.end(); ++i) + (d->coreWindow.Get()->*i.key())(i.value()); + for (QHash<DisplayCallbackRemover, EventRegistrationToken>::const_iterator i = d->displayTokens.begin(); i != d->displayTokens.end(); ++i) + (d->displayInformation.Get()->*i.key())(i.value()); +#ifdef Q_OS_WINPHONE + for (QHash<HardwareButtonsCallbackRemover, EventRegistrationToken>::const_iterator i = d->buttonsTokens.begin(); i != d->buttonsTokens.end(); ++i) + (d->hardwareButtons.Get()->*i.key())(i.value()); +#endif } QRect QWinRTScreen::geometry() const { - return m_geometry.toRect(); + Q_D(const QWinRTScreen); + return d->geometry.toRect(); } int QWinRTScreen::depth() const { - return m_depth; + return 32; } QImage::Format QWinRTScreen::format() const { - return m_format; + return QImage::Format_ARGB32_Premultiplied; } QSurfaceFormat QWinRTScreen::surfaceFormat() const { - return m_surfaceFormat; + Q_D(const QWinRTScreen); + return d->surfaceFormat; } QSizeF QWinRTScreen::physicalSize() const { - return m_geometry.size() / m_dpi * qreal(25.4); + Q_D(const QWinRTScreen); + return d->geometry.size() / d->dpi * qreal(25.4); } QDpi QWinRTScreen::logicalDpi() const { - return QDpi(m_dpi, m_dpi); + Q_D(const QWinRTScreen); + return QDpi(d->dpi, d->dpi); } qreal QWinRTScreen::devicePixelRatio() const { - return m_devicePixelRatio; + Q_D(const QWinRTScreen); + return d->devicePixelRatio; } QWinRTInputContext *QWinRTScreen::inputContext() const { - return m_inputContext; + Q_D(const QWinRTScreen); +#ifdef Q_OS_WINPHONE + return d->inputContext.data(); +#else + return d->inputContext.Get(); +#endif } QPlatformCursor *QWinRTScreen::cursor() const { - return m_cursor; + Q_D(const QWinRTScreen); + if (!d->cursor) + const_cast<QWinRTScreenPrivate *>(d)->cursor.reset(new QWinRTCursor); + return d->cursor.data(); } Qt::KeyboardModifiers QWinRTScreen::keyboardModifiers() const { + Q_D(const QWinRTScreen); + Qt::KeyboardModifiers mods; CoreVirtualKeyStates mod; - m_coreWindow->GetAsyncKeyState(VirtualKey_Shift, &mod); + d->coreWindow->GetAsyncKeyState(VirtualKey_Shift, &mod); if (mod == CoreVirtualKeyStates_Down) mods |= Qt::ShiftModifier; - m_coreWindow->GetAsyncKeyState(VirtualKey_Menu, &mod); + d->coreWindow->GetAsyncKeyState(VirtualKey_Menu, &mod); if (mod == CoreVirtualKeyStates_Down) mods |= Qt::AltModifier; - m_coreWindow->GetAsyncKeyState(VirtualKey_Control, &mod); + d->coreWindow->GetAsyncKeyState(VirtualKey_Control, &mod); if (mod == CoreVirtualKeyStates_Down) mods |= Qt::ControlModifier; - m_coreWindow->GetAsyncKeyState(VirtualKey_LeftWindows, &mod); + d->coreWindow->GetAsyncKeyState(VirtualKey_LeftWindows, &mod); if (mod == CoreVirtualKeyStates_Down) { mods |= Qt::MetaModifier; } else { - m_coreWindow->GetAsyncKeyState(VirtualKey_RightWindows, &mod); + d->coreWindow->GetAsyncKeyState(VirtualKey_RightWindows, &mod); if (mod == CoreVirtualKeyStates_Down) mods |= Qt::MetaModifier; } @@ -620,56 +690,63 @@ Qt::KeyboardModifiers QWinRTScreen::keyboardModifiers() const Qt::ScreenOrientation QWinRTScreen::nativeOrientation() const { - return m_nativeOrientation; + Q_D(const QWinRTScreen); + return d->nativeOrientation; } Qt::ScreenOrientation QWinRTScreen::orientation() const { - return m_orientation; + Q_D(const QWinRTScreen); + return d->orientation; } void QWinRTScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask) { -#if _MSC_VER<=1700 - m_displayInformation->put_AutoRotationPreferences(nativeOrientationsFromQt(mask)); -#else - m_displayInformationFactory->put_AutoRotationPreferences(nativeOrientationsFromQt(mask)); -#endif + Q_D(QWinRTScreen); + + HRESULT hr = d->displayInformationStatics->put_AutoRotationPreferences(nativeOrientationsFromQt(mask)); + RETURN_VOID_IF_FAILED("Failed to set display auto rotation preferences."); } ICoreWindow *QWinRTScreen::coreWindow() const { - return m_coreWindow; + Q_D(const QWinRTScreen); + return d->coreWindow.Get(); } EGLDisplay QWinRTScreen::eglDisplay() const { - return m_eglDisplay; + Q_D(const QWinRTScreen); + return d->eglDisplay; } EGLSurface QWinRTScreen::eglSurface() const { - return m_eglSurface; + Q_D(const QWinRTScreen); + return d->eglSurface; } QWindow *QWinRTScreen::topWindow() const { - return m_visibleWindows.isEmpty() ? 0 : m_visibleWindows.first(); + Q_D(const QWinRTScreen); + return d->visibleWindows.isEmpty() ? 0 : d->visibleWindows.first(); } void QWinRTScreen::addWindow(QWindow *window) { + Q_D(QWinRTScreen); if (window == topWindow()) return; - m_visibleWindows.prepend(window); + d->visibleWindows.prepend(window); QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason); handleExpose(); } void QWinRTScreen::removeWindow(QWindow *window) { + Q_D(QWinRTScreen); const bool wasTopWindow = window == topWindow(); - if (!m_visibleWindows.removeAll(window)) + if (!d->visibleWindows.removeAll(window)) return; if (wasTopWindow) QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason); @@ -678,17 +755,19 @@ void QWinRTScreen::removeWindow(QWindow *window) void QWinRTScreen::raise(QWindow *window) { - m_visibleWindows.removeAll(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 && m_visibleWindows.size() == 1) + if (wasTopWindow && d->visibleWindows.size() == 1) return; - m_visibleWindows.removeAll(window); - m_visibleWindows.append(window); + d->visibleWindows.removeAll(window); + d->visibleWindows.append(window); if (wasTopWindow) QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason); handleExpose(); @@ -696,18 +775,18 @@ void QWinRTScreen::lower(QWindow *window) void QWinRTScreen::handleExpose() { - if (m_visibleWindows.isEmpty()) + Q_D(QWinRTScreen); + if (d->visibleWindows.isEmpty()) return; - QList<QWindow *>::const_iterator it = m_visibleWindows.constBegin(); - QWindowSystemInterface::handleExposeEvent(*it, m_geometry.toRect()); - while (++it != m_visibleWindows.constEnd()) + QList<QWindow *>::const_iterator it = d->visibleWindows.constBegin(); + QWindowSystemInterface::handleExposeEvent(*it, d->geometry.toRect()); + while (++it != d->visibleWindows.constEnd()) QWindowSystemInterface::handleExposeEvent(*it, QRegion()); QWindowSystemInterface::flushWindowSystemEvents(); } -HRESULT QWinRTScreen::onKeyDown(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IKeyEventArgs *args) +HRESULT QWinRTScreen::onKeyDown(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IKeyEventArgs *args) { - Q_UNUSED(window); VirtualKey virtualKey; args->get_VirtualKey(&virtualKey); Qt::Key key = qKeyFromVirtual(virtualKey); @@ -718,14 +797,14 @@ HRESULT QWinRTScreen::onKeyDown(ABI::Windows::UI::Core::ICoreWindow *window, ABI return S_OK; } -HRESULT QWinRTScreen::onKeyUp(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IKeyEventArgs *args) +HRESULT QWinRTScreen::onKeyUp(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IKeyEventArgs *args) { - Q_UNUSED(window); Qt::KeyboardModifiers mods = keyboardModifiers(); #ifndef Q_OS_WINPHONE + Q_D(QWinRTScreen); CorePhysicalKeyStatus status; // Look for a pressed character key - if (SUCCEEDED(args->get_KeyStatus(&status)) && m_activeKeys.contains(status.ScanCode)) { - QPair<Qt::Key, QString> keyStatus = m_activeKeys.take(status.ScanCode); + if (SUCCEEDED(args->get_KeyStatus(&status)) && d->activeKeys.contains(status.ScanCode)) { + QPair<Qt::Key, QString> keyStatus = d->activeKeys.take(status.ScanCode); QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyRelease, keyStatus.first, mods, keyStatus.second); return S_OK; @@ -738,10 +817,8 @@ HRESULT QWinRTScreen::onKeyUp(ABI::Windows::UI::Core::ICoreWindow *window, ABI:: return S_OK; } -HRESULT QWinRTScreen::onCharacterReceived(ICoreWindow *window, ICharacterReceivedEventArgs *args) +HRESULT QWinRTScreen::onCharacterReceived(ICoreWindow *, ICharacterReceivedEventArgs *args) { - Q_UNUSED(window); - quint32 keyCode; args->get_KeyCode(&keyCode); // Don't generate character events for non-printables; the meta key stage is enough @@ -753,9 +830,10 @@ HRESULT QWinRTScreen::onCharacterReceived(ICoreWindow *window, ICharacterReceive QString text = QChar(keyCode); QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyPress, key, mods, text); #ifndef Q_OS_WINPHONE + Q_D(QWinRTScreen); CorePhysicalKeyStatus status; // Defer release to onKeyUp for physical keys if (SUCCEEDED(args->get_KeyStatus(&status)) && !status.IsKeyReleased) { - m_activeKeys.insert(status.ScanCode, qMakePair(key, text)); + d->activeKeys.insert(status.ScanCode, qMakePair(key, text)); return S_OK; } #endif // !Q_OS_WINPHONE @@ -763,10 +841,9 @@ HRESULT QWinRTScreen::onCharacterReceived(ICoreWindow *window, ICharacterReceive return S_OK; } -HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *window, IPointerEventArgs *args) +HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *, IPointerEventArgs *args) { - Q_UNUSED(window); - IPointerPoint *pointerPoint; + ComPtr<IPointerPoint> pointerPoint; if (SUCCEEDED(args->get_CurrentPoint(&pointerPoint))) { // Assumes full-screen window Point point; @@ -774,24 +851,20 @@ HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *window, IPointerEventArgs *a QPoint pos(point.X, point.Y); QWindowSystemInterface::handleEnterEvent(topWindow(), pos, pos); - pointerPoint->Release(); } return S_OK; } -HRESULT QWinRTScreen::onPointerExited(ICoreWindow *window, IPointerEventArgs *args) +HRESULT QWinRTScreen::onPointerExited(ICoreWindow *, IPointerEventArgs *) { - Q_UNUSED(window); - Q_UNUSED(args); QWindowSystemInterface::handleLeaveEvent(0); return S_OK; } -HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *args) +HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) { - Q_UNUSED(window); - - IPointerPoint *pointerPoint; + Q_D(QWinRTScreen); + ComPtr<IPointerPoint> pointerPoint; if (FAILED(args->get_CurrentPoint(&pointerPoint))) return E_INVALIDARG; @@ -812,27 +885,18 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *a if (modifiers & VirtualKeyModifiers_Windows) mods |= Qt::MetaModifier; - IPointerPointProperties *properties; + ComPtr<IPointerPointProperties> properties; if (FAILED(pointerPoint->get_Properties(&properties))) return E_INVALIDARG; - PointerDeviceType pointerDeviceType; -#if defined(Q_OS_WINPHONE) && _MSC_VER <= 1700 - pointerDeviceType = PointerDeviceType_Touch; -#else ComPtr<IPointerDevice> pointerDevice; HRESULT hr = pointerPoint->get_PointerDevice(&pointerDevice); - if (FAILED(hr)) { - qErrnoWarning(hr, "Failed to get pointer device."); - return S_OK; - } + RETURN_OK_IF_FAILED("Failed to get pointer device."); + PointerDeviceType pointerDeviceType; hr = pointerDevice->get_PointerDeviceType(&pointerDeviceType); - if (FAILED(hr)) { - qErrnoWarning(hr, "Failed to get pointer device type."); - return S_OK; - } -#endif + RETURN_OK_IF_FAILED("Failed to get pointer device type."); + switch (pointerDeviceType) { case PointerDeviceType_Mouse: { qint32 delta; @@ -872,12 +936,12 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *a break; } case PointerDeviceType_Touch: { - if (!m_touchDevice) { - m_touchDevice = new QTouchDevice; - m_touchDevice->setName(QStringLiteral("WinRTTouchScreen")); - m_touchDevice->setType(QTouchDevice::TouchScreen); - m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure | QTouchDevice::NormalizedPosition); - QWindowSystemInterface::registerTouchDevice(m_touchDevice); + 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; @@ -889,8 +953,8 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *a float pressure; properties->get_Pressure(&pressure); - QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator it = m_touchPoints.find(id); - if (it != m_touchPoints.end()) { + QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator it = d->touchPoints.find(id); + if (it != d->touchPoints.end()) { boolean isPressed; #ifndef Q_OS_WINPHONE pointerPoint->get_IsInContact(&isPressed); @@ -899,20 +963,20 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *a #endif it.value().state = isPressed ? Qt::TouchPointMoved : Qt::TouchPointReleased; } else { - it = m_touchPoints.insert(id, QWindowSystemInterface::TouchPoint()); + it = d->touchPoints.insert(id, QWindowSystemInterface::TouchPoint()); it.value().state = Qt::TouchPointPressed; it.value().id = id; } it.value().area = QRectF(area.X, area.Y, area.Width, area.Height); - it.value().normalPosition = QPointF(pos.x()/m_geometry.width(), pos.y()/m_geometry.height()); + it.value().normalPosition = QPointF(pos.x()/d->geometry.width(), pos.y()/d->geometry.height()); it.value().pressure = pressure; - QWindowSystemInterface::handleTouchEvent(topWindow(), m_touchDevice, m_touchPoints.values(), mods); + QWindowSystemInterface::handleTouchEvent(topWindow(), d->touchDevice, d->touchPoints.values(), mods); // Remove released points, station others - for (QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator i = m_touchPoints.begin(); i != m_touchPoints.end();) { + for (QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator i = d->touchPoints.begin(); i != d->touchPoints.end();) { if (i.value().state == Qt::TouchPointReleased) - i = m_touchPoints.erase(i); + i = d->touchPoints.erase(i); else (i++).value().state = Qt::TouchPointStationary; } @@ -950,46 +1014,42 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *a } } - properties->Release(); - pointerPoint->Release(); - return S_OK; } HRESULT QWinRTScreen::onAutomationProviderRequested(ICoreWindow *, IAutomationProviderRequestedEventArgs *args) { + Q_D(const QWinRTScreen); #ifndef Q_OS_WINPHONE - args->put_AutomationProvider(m_inputContext); + args->put_AutomationProvider(d->inputContext.Get()); #else Q_UNUSED(args) #endif return S_OK; } -HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *window, IWindowSizeChangedEventArgs *args) +HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *args) { - Q_UNUSED(window); + Q_D(QWinRTScreen); Size size; - if (FAILED(args->get_Size(&size))) { - qWarning(Q_FUNC_INFO ": failed to get size"); - return S_OK; - } + HRESULT hr = args->get_Size(&size); + RETURN_OK_IF_FAILED("Failed to get window size."); // Regardless of state, all top-level windows are viewport-sized - this might change if // a more advanced compositor is written. - m_geometry.setSize(QSizeF(size.Width, size.Height)); - QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry.toRect()); - QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_geometry.toRect()); + d->geometry.setSize(QSizeF(size.Width, size.Height)); + QWindowSystemInterface::handleScreenGeometryChange(screen(), d->geometry.toRect()); + QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), d->geometry.toRect()); QPlatformScreen::resizeMaximizedWindows(); handleExpose(); return S_OK; } -HRESULT QWinRTScreen::onActivated(ICoreWindow *window, IWindowActivatedEventArgs *args) +HRESULT QWinRTScreen::onActivated(ICoreWindow *, IWindowActivatedEventArgs *args) { - Q_UNUSED(window); + Q_D(QWinRTScreen); CoreWindowActivationState activationState; args->get_WindowActivationState(&activationState); @@ -999,7 +1059,7 @@ HRESULT QWinRTScreen::onActivated(ICoreWindow *window, IWindowActivatedEventArgs } // Activate topWindow - if (!m_visibleWindows.isEmpty()) { + if (!d->visibleWindows.isEmpty()) { Qt::FocusReason focusReason = activationState == CoreWindowActivationState_PointerActivated ? Qt::MouseFocusReason : Qt::ActiveWindowFocusReason; QWindowSystemInterface::handleWindowActivated(topWindow(), focusReason); @@ -1022,21 +1082,15 @@ HRESULT QWinRTScreen::onResume(IInspectable *, IInspectable *) return S_OK; } -HRESULT QWinRTScreen::onClosed(ICoreWindow *window, ICoreWindowEventArgs *args) +HRESULT QWinRTScreen::onClosed(ICoreWindow *, ICoreWindowEventArgs *) { - Q_UNUSED(window); - Q_UNUSED(args); - foreach (QWindow *w, QGuiApplication::topLevelWindows()) QWindowSystemInterface::handleCloseEvent(w); return S_OK; } -HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *window, IVisibilityChangedEventArgs *args) +HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *, IVisibilityChangedEventArgs *args) { - Q_UNUSED(window); - Q_UNUSED(args); - boolean visible; args->get_Visible(&visible); QWindowSystemInterface::handleApplicationStateChanged(visible ? Qt::ApplicationActive : Qt::ApplicationHidden); @@ -1045,60 +1099,48 @@ HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *window, IVisibilityChange return S_OK; } -#if _MSC_VER<=1700 -HRESULT QWinRTScreen::onOrientationChanged(IInspectable *) -#else HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable *) -#endif { + Q_D(QWinRTScreen); + DisplayOrientations displayOrientation; - m_displayInformation->get_CurrentOrientation(&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 (m_orientation != newOrientation) { - m_orientation = newOrientation; - QWindowSystemInterface::handleScreenOrientationChange(screen(), m_orientation); + if (d->orientation != newOrientation) { + d->orientation = newOrientation; + QWindowSystemInterface::handleScreenOrientationChange(screen(), d->orientation); } return S_OK; } -#if _MSC_VER<=1700 -HRESULT QWinRTScreen::onDpiChanged(IInspectable *) -#else HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *) -#endif { -#if defined(Q_OS_WINPHONE) && _MSC_VER>=1800 // WP 8.1 + Q_D(QWinRTScreen); + + HRESULT hr; +#ifdef Q_OS_WINPHONE ComPtr<IDisplayInformation2> displayInformation; - HRESULT hr = m_displayInformation->QueryInterface(IID_IDisplayInformation2, &displayInformation); - if (FAILED(hr)) { - qErrnoWarning(hr, "Failed to cast display information."); - return S_OK; - } - hr = displayInformation->get_RawPixelsPerViewPixel(&m_devicePixelRatio); + hr = d->displayInformation.As(&displayInformation); + RETURN_OK_IF_FAILED("Failed to cast display information."); + hr = displayInformation->get_RawPixelsPerViewPixel(&d->devicePixelRatio); #else ResolutionScale resolutionScale; - HRESULT hr = m_displayInformation->get_ResolutionScale(&resolutionScale); -#endif - if (FAILED(hr)) { - qErrnoWarning(hr, "Failed to get display resolution scale."); - return S_OK; - } -#if !(defined(Q_OS_WINPHONE) && _MSC_VER>=1800) // !WP8.1 - m_devicePixelRatio = qreal(resolutionScale) / 100; + hr = d->displayInformation->get_ResolutionScale(&resolutionScale); + d->devicePixelRatio = qreal(resolutionScale) / 100; #endif + RETURN_OK_IF_FAILED("Failed to get resolution scale"); // Correct the scale factor for integer window size - m_devicePixelRatio = m_devicePixelRatio * ((m_geometry.width()/qRound(m_geometry.width()) + - m_geometry.height()/qRound(m_geometry.height())) / 2.0); + d->devicePixelRatio = d->devicePixelRatio * ((d->geometry.width()/qRound(d->geometry.width()) + + d->geometry.height()/qRound(d->geometry.height())) / 2.0); FLOAT dpi; - hr = m_displayInformation->get_LogicalDpi(&dpi); - if (FAILED(hr)) { - qErrnoWarning(hr, "Failed to get logical DPI."); - return S_OK; - } - m_dpi = dpi; + hr = d->displayInformation->get_LogicalDpi(&dpi); + RETURN_OK_IF_FAILED("Failed to get logical DPI."); + d->dpi = dpi; return S_OK; } @@ -1106,14 +1148,16 @@ HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *) #ifdef Q_OS_WINPHONE HRESULT QWinRTScreen::onBackButtonPressed(IInspectable *, IBackPressedEventArgs *args) { + Q_D(QWinRTScreen); + QKeyEvent backPress(QEvent::KeyPress, Qt::Key_Back, Qt::NoModifier); QKeyEvent backRelease(QEvent::KeyRelease, Qt::Key_Back, Qt::NoModifier); backPress.setAccepted(false); backRelease.setAccepted(false); - QObject *receiver = m_visibleWindows.isEmpty() + QObject *receiver = d->visibleWindows.isEmpty() ? static_cast<QObject *>(QGuiApplication::instance()) - : static_cast<QObject *>(m_visibleWindows.first()); + : static_cast<QObject *>(d->visibleWindows.first()); // If the event is ignored, the app will suspend QGuiApplication::sendEvent(receiver, &backPress); diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h index d39683a960..18745f1017 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.h +++ b/src/plugins/platforms/winrt/qwinrtscreen.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -45,19 +45,12 @@ #include <qpa/qplatformscreen.h> #include <qpa/qwindowsysteminterface.h> -#include <QtCore/QHash> -#include <QtGui/QSurfaceFormat> #include <EGL/egl.h> -#include <EventToken.h> - namespace ABI { namespace Windows { namespace ApplicationModel { struct ISuspendingEventArgs; - namespace Core { - struct ICoreApplication; - } } namespace UI { namespace Core { @@ -71,14 +64,9 @@ namespace ABI { struct IWindowActivatedEventArgs; struct IWindowSizeChangedEventArgs; } - namespace ViewManagement { - struct IApplicationViewStatics; - } } namespace Graphics { namespace Display { - struct IDisplayPropertiesStatics; - struct IDisplayInformationStatics; struct IDisplayInformation; } } @@ -99,14 +87,14 @@ QT_BEGIN_NAMESPACE class QTouchDevice; class QWinRTEGLContext; -class QWinRTPageFlipper; class QWinRTCursor; class QWinRTInputContext; - +class QWinRTScreenPrivate; class QWinRTScreen : public QPlatformScreen { public: - explicit QWinRTScreen(ABI::Windows::UI::Core::ICoreWindow *window); + explicit QWinRTScreen(); + ~QWinRTScreen(); QRect geometry() const; int depth() const; QImage::Format format() const; @@ -135,69 +123,31 @@ public: private: void handleExpose(); - // Event handlers - QHash<QEvent::Type, EventRegistrationToken> m_tokens; - QHash<Qt::ApplicationState, EventRegistrationToken> m_suspendTokens; + HRESULT onKeyDown(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IKeyEventArgs *); + HRESULT onKeyUp(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IKeyEventArgs *); + HRESULT onCharacterReceived(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::ICharacterReceivedEventArgs *); + HRESULT onPointerEntered(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IPointerEventArgs *); + HRESULT onPointerExited(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IPointerEventArgs *); + HRESULT onPointerUpdated(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IPointerEventArgs *); + HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *); - HRESULT onKeyDown(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IKeyEventArgs *args); - HRESULT onKeyUp(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IKeyEventArgs *args); - HRESULT onCharacterReceived(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::ICharacterReceivedEventArgs *args); - HRESULT onPointerEntered(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IPointerEventArgs *args); - HRESULT onPointerExited(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IPointerEventArgs *args); - HRESULT onPointerUpdated(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IPointerEventArgs *args); - HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *args); - - HRESULT onActivated(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowActivatedEventArgs *args); + HRESULT onActivated(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowActivatedEventArgs *); HRESULT onSuspended(IInspectable *, ABI::Windows::ApplicationModel::ISuspendingEventArgs *); HRESULT onResume(IInspectable *, IInspectable *); - HRESULT onClosed(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::ICoreWindowEventArgs *args); - HRESULT onVisibilityChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IVisibilityChangedEventArgs *args); - HRESULT onAutomationProviderRequested(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IAutomationProviderRequestedEventArgs *args); + HRESULT onClosed(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::ICoreWindowEventArgs *); + HRESULT onVisibilityChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IVisibilityChangedEventArgs *); + HRESULT onAutomationProviderRequested(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IAutomationProviderRequestedEventArgs *); -#if _MSC_VER<=1700 - HRESULT onOrientationChanged(IInspectable *); - HRESULT onDpiChanged(IInspectable *); -#else HRESULT onOrientationChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *); HRESULT onDpiChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *); -#endif #ifdef Q_OS_WINPHONE HRESULT onBackButtonPressed(IInspectable *, ABI::Windows::Phone::UI::Input::IBackPressedEventArgs *args); #endif - ABI::Windows::UI::Core::ICoreWindow *m_coreWindow; - ABI::Windows::UI::ViewManagement::IApplicationViewStatics *m_applicationView; - ABI::Windows::ApplicationModel::Core::ICoreApplication *m_application; - - QRectF m_geometry; - QImage::Format m_format; - QSurfaceFormat m_surfaceFormat; - qreal m_dpi; - int m_depth; - QWinRTInputContext *m_inputContext; - QWinRTCursor *m_cursor; - QList<QWindow *> m_visibleWindows; - - EGLDisplay m_eglDisplay; - EGLSurface m_eglSurface; - -#if _MSC_VER<=1700 - ABI::Windows::Graphics::Display::IDisplayPropertiesStatics *m_displayInformation; -#else - ABI::Windows::Graphics::Display::IDisplayInformationStatics *m_displayInformationFactory; - ABI::Windows::Graphics::Display::IDisplayInformation *m_displayInformation; -#endif - qreal m_devicePixelRatio; - Qt::ScreenOrientation m_nativeOrientation; - Qt::ScreenOrientation m_orientation; - -#ifndef Q_OS_WINPHONE - QHash<quint32, QPair<Qt::Key, QString> > m_activeKeys; -#endif - QTouchDevice *m_touchDevice; - QHash<quint32, QWindowSystemInterface::TouchPoint> m_touchPoints; + QScopedPointer<QWinRTScreenPrivate> d_ptr; + Q_DECLARE_PRIVATE(QWinRTScreen) }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrtservices.cpp b/src/plugins/platforms/winrt/qwinrtservices.cpp index b0f9247d36..6272b46f44 100644 --- a/src/plugins/platforms/winrt/qwinrtservices.cpp +++ b/src/plugins/platforms/winrt/qwinrtservices.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -43,6 +43,7 @@ #include <QtCore/QUrl> #include <QtCore/QDir> #include <QtCore/QCoreApplication> +#include <QtCore/qfunctions_winrt.h> #include <wrl.h> #include <windows.foundation.h> @@ -56,83 +57,84 @@ using namespace ABI::Windows::System; QT_BEGIN_NAMESPACE +class QWinRTServicesPrivate +{ +public: + ComPtr<IUriRuntimeClassFactory> uriFactory; + ComPtr<IStorageFileStatics> fileFactory; + ComPtr<ILauncherStatics> launcher; +}; + QWinRTServices::QWinRTServices() + : d_ptr(new QWinRTServicesPrivate) { - GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Foundation_Uri).Get(), &m_uriFactory); - GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_StorageFile).Get(), &m_fileFactory); - GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_System_Launcher).Get(), &m_launcher); + Q_D(QWinRTServices); + + HRESULT hr; + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Foundation_Uri).Get(), + IID_PPV_ARGS(&d->uriFactory)); + Q_ASSERT_X(SUCCEEDED(hr), Q_FUNC_INFO, qPrintable(qt_error_string(hr))); + + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_StorageFile).Get(), + IID_PPV_ARGS(&d->fileFactory)); + Q_ASSERT_X(SUCCEEDED(hr), Q_FUNC_INFO, qPrintable(qt_error_string(hr))); + + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_System_Launcher).Get(), + IID_PPV_ARGS(&d->launcher)); + Q_ASSERT_X(SUCCEEDED(hr), Q_FUNC_INFO, qPrintable(qt_error_string(hr))); } QWinRTServices::~QWinRTServices() { - if (m_uriFactory) - m_uriFactory->Release(); - - if (m_fileFactory) - m_fileFactory->Release(); - - if (m_launcher) - m_launcher->Release(); } bool QWinRTServices::openUrl(const QUrl &url) { - if (!(m_uriFactory && m_launcher)) - return QPlatformServices::openUrl(url); + Q_D(QWinRTServices); - IUriRuntimeClass *uri; + ComPtr<IUriRuntimeClass> uri; QString urlString = url.toString(); - // ### TODO: Replace with HStringReference when WP8.0 support is removed - HString uriString; - uriString.Set((const wchar_t*)urlString.utf16(), urlString.length()); - m_uriFactory->CreateUri(uriString.Get(), &uri); - if (!uri) - return false; - - IAsyncOperation<bool> *launchOp; - m_launcher->LaunchUriAsync(uri, &launchOp); - uri->Release(); - if (!launchOp) - return false; - - boolean result = false; - while (launchOp->GetResults(&result) == E_ILLEGAL_METHOD_CALL) - QCoreApplication::processEvents(); - launchOp->Release(); + HStringReference uriString(reinterpret_cast<LPCWSTR>(urlString.utf16()), urlString.length()); + HRESULT hr = d->uriFactory->CreateUri(uriString.Get(), &uri); + RETURN_FALSE_IF_FAILED("Failed to create URI from QUrl."); + + ComPtr<IAsyncOperation<bool>> op; + hr = d->launcher->LaunchUriAsync(uri.Get(), &op); + RETURN_FALSE_IF_FAILED("Failed to start URI launch."); + + boolean result; + hr = QWinRTFunctions::await(op, &result); + RETURN_FALSE_IF_FAILED("Failed to launch URI."); return result; } bool QWinRTServices::openDocument(const QUrl &url) { - if (!(m_fileFactory && m_launcher)) - return QPlatformServices::openDocument(url); - - const QString pathString = QDir::toNativeSeparators(url.toLocalFile()); - // ### TODO: Replace with HStringReference when WP8.0 support is removed - HString path; - path.Set((const wchar_t*)pathString.utf16(), pathString.length()); - IAsyncOperation<StorageFile*> *fileOp; - m_fileFactory->GetFileFromPathAsync(path.Get(), &fileOp); - if (!fileOp) - return false; - - IStorageFile *file = nullptr; - while (fileOp->GetResults(&file) == E_ILLEGAL_METHOD_CALL) - QCoreApplication::processEvents(); - fileOp->Release(); - if (!file) - return false; - - IAsyncOperation<bool> *launchOp; - m_launcher->LaunchFileAsync(file, &launchOp); - if (!launchOp) - return false; - - boolean result = false; - while (launchOp->GetResults(&result) == E_ILLEGAL_METHOD_CALL) - QCoreApplication::processEvents(); - launchOp->Release(); + Q_D(QWinRTServices); + + HRESULT hr; + ComPtr<IStorageFile> file; + { + const QString pathString = QDir::toNativeSeparators(url.toLocalFile()); + HStringReference path(reinterpret_cast<LPCWSTR>(pathString.utf16()), pathString.length()); + ComPtr<IAsyncOperation<StorageFile *>> op; + hr = d->fileFactory->GetFileFromPathAsync(path.Get(), &op); + RETURN_FALSE_IF_FAILED("Failed to initialize file URI."); + + hr = QWinRTFunctions::await(op, file.GetAddressOf()); + RETURN_FALSE_IF_FAILED("Failed to get file URI."); + } + + boolean result; + { + ComPtr<IAsyncOperation<bool>> op; + hr = d->launcher->LaunchFileAsync(file.Get(), &op); + RETURN_FALSE_IF_FAILED("Failed to start file launch."); + + hr = QWinRTFunctions::await(op, &result); + RETURN_FALSE_IF_FAILED("Failed to launch file."); + } return result; } diff --git a/src/plugins/platforms/winrt/qwinrtservices.h b/src/plugins/platforms/winrt/qwinrtservices.h index 9cc917030a..d3abe6f2bd 100644 --- a/src/plugins/platforms/winrt/qwinrtservices.h +++ b/src/plugins/platforms/winrt/qwinrtservices.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -43,23 +43,11 @@ #define QWINRTSERVICES_H #include <qpa/qplatformservices.h> +#include <QtCore/QScopedPointer> -namespace ABI { - namespace Windows { - namespace Foundation { - struct IUriRuntimeClassFactory; - } - namespace Storage { - struct IStorageFileStatics; - } - namespace System { - struct ILauncherStatics; - } - } -} - -QT_BEGIN_NAMESPACE +QT_USE_NAMESPACE +class QWinRTServicesPrivate; class QWinRTServices : public QPlatformServices { public: @@ -70,11 +58,8 @@ public: bool openDocument(const QUrl &url); private: - ABI::Windows::Foundation::IUriRuntimeClassFactory *m_uriFactory; - ABI::Windows::Storage::IStorageFileStatics *m_fileFactory; - ABI::Windows::System::ILauncherStatics *m_launcher; + QScopedPointer<QWinRTServicesPrivate> d_ptr; + Q_DECLARE_PRIVATE(QWinRTServices) }; -QT_END_NAMESPACE - #endif // QWINRTSERVICES_H diff --git a/src/plugins/platforms/winrt/qwinrttheme.cpp b/src/plugins/platforms/winrt/qwinrttheme.cpp new file mode 100644 index 0000000000..f9c2e21676 --- /dev/null +++ b/src/plugins/platforms/winrt/qwinrttheme.cpp @@ -0,0 +1,211 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwinrttheme.h" +#include "qwinrtmessagedialoghelper.h" + +#include <QtCore/qfunctions_winrt.h> +#include <QtGui/QPalette> + +#include <wrl.h> +#include <windows.ui.h> +#include <windows.ui.viewmanagement.h> +using namespace Microsoft::WRL; +using namespace ABI::Windows::UI; +using namespace ABI::Windows::UI::ViewManagement; + +QT_BEGIN_NAMESPACE + +static IUISettings *uiSettings() +{ + static ComPtr<IUISettings> settings; + if (!settings) { + HRESULT hr; + hr = RoActivateInstance(Wrappers::HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_UISettings).Get(), + &settings); + Q_ASSERT_SUCCEEDED(hr); + } + return settings.Get(); +} + +class QWinRTThemePrivate +{ +public: + QPalette palette; +}; + +QWinRTTheme::QWinRTTheme() + : d_ptr(new QWinRTThemePrivate) +{ + Q_D(QWinRTTheme); + + HRESULT hr; + union { Color ui; QRgb qt; } color; + + hr = uiSettings()->UIElementColor(UIElementType_ActiveCaption, &color.ui); + Q_ASSERT_SUCCEEDED(hr); + d->palette.setColor(QPalette::ToolTipBase, color.qt); + + hr = uiSettings()->UIElementColor(UIElementType_Background, &color.ui); + Q_ASSERT_SUCCEEDED(hr); + d->palette.setColor(QPalette::AlternateBase, color.qt); + + hr = uiSettings()->UIElementColor(UIElementType_ButtonFace, &color.ui); + Q_ASSERT_SUCCEEDED(hr); + d->palette.setColor(QPalette::Button, color.qt); + d->palette.setColor(QPalette::Midlight, QColor(color.qt).lighter(110)); + d->palette.setColor(QPalette::Light, QColor(color.qt).lighter(150)); + d->palette.setColor(QPalette::Mid, QColor(color.qt).dark(130)); + d->palette.setColor(QPalette::Dark, QColor(color.qt).dark(150)); + + hr = uiSettings()->UIElementColor(UIElementType_ButtonText, &color.ui); + Q_ASSERT_SUCCEEDED(hr); + d->palette.setColor(QPalette::ButtonText, color.qt); + d->palette.setColor(QPalette::Text, color.qt); + + hr = uiSettings()->UIElementColor(UIElementType_CaptionText, &color.ui); + Q_ASSERT_SUCCEEDED(hr); + d->palette.setColor(QPalette::ToolTipText, color.qt); + + hr = uiSettings()->UIElementColor(UIElementType_Highlight, &color.ui); + Q_ASSERT_SUCCEEDED(hr); + d->palette.setColor(QPalette::Highlight, color.qt); + + hr = uiSettings()->UIElementColor(UIElementType_HighlightText, &color.ui); + Q_ASSERT_SUCCEEDED(hr); + d->palette.setColor(QPalette::HighlightedText, color.qt); + + hr = uiSettings()->UIElementColor(UIElementType_Window, &color.ui); + Q_ASSERT_SUCCEEDED(hr); + d->palette.setColor(QPalette::Window, color.qt); + d->palette.setColor(QPalette::Base, color.qt); + +#ifdef Q_OS_WINPHONE + hr = uiSettings()->UIElementColor(UIElementType_TextHigh, &color.ui); + Q_ASSERT_SUCCEEDED(hr); + d->palette.setColor(QPalette::BrightText, color.qt); +#else + hr = uiSettings()->UIElementColor(UIElementType_Hotlight, &color.ui); + Q_ASSERT_SUCCEEDED(hr); + d->palette.setColor(QPalette::BrightText, color.qt); +#endif +} + +bool QWinRTTheme::usePlatformNativeDialog(DialogType type) const +{ + static bool useNativeDialogs = qEnvironmentVariableIsSet("QT_USE_WINRT_NATIVE_DIALOGS") + ? qgetenv("QT_USE_WINRT_NATIVE_DIALOGS").toInt() : true; + + if (type == MessageDialog) + return useNativeDialogs; + return false; +} + +QPlatformDialogHelper *QWinRTTheme::createPlatformDialogHelper(DialogType type) const +{ + switch (type) { + case MessageDialog: + return new QWinRTMessageDialogHelper(this); + default: + break; + } + return QPlatformTheme::createPlatformDialogHelper(type); +} + +QVariant QWinRTTheme::styleHint(QPlatformIntegration::StyleHint hint) +{ + HRESULT hr; + switch (hint) { + case QPlatformIntegration::CursorFlashTime: { + quint32 blinkRate; + hr = uiSettings()->get_CaretBlinkRate(&blinkRate); + RETURN_IF_FAILED("Failed to get caret blink rate", return defaultThemeHint(CursorFlashTime)); + return blinkRate; + } + case QPlatformIntegration::KeyboardInputInterval: + return defaultThemeHint(KeyboardInputInterval); + case QPlatformIntegration::MouseDoubleClickInterval: { + quint32 doubleClickTime; + hr = uiSettings()->get_DoubleClickTime(&doubleClickTime); + RETURN_IF_FAILED("Failed to get double click time", return defaultThemeHint(MouseDoubleClickInterval)); + return doubleClickTime; + } + case QPlatformIntegration::StartDragDistance: + return defaultThemeHint(StartDragDistance); + case QPlatformIntegration::StartDragTime: + return defaultThemeHint(StartDragTime); + case QPlatformIntegration::KeyboardAutoRepeatRate: + return defaultThemeHint(KeyboardAutoRepeatRate); + case QPlatformIntegration::ShowIsFullScreen: + return true; + case QPlatformIntegration::PasswordMaskDelay: + return defaultThemeHint(PasswordMaskDelay); + case QPlatformIntegration::FontSmoothingGamma: + return qreal(1.7); + case QPlatformIntegration::StartDragVelocity: + return defaultThemeHint(StartDragVelocity); + case QPlatformIntegration::UseRtlExtensions: + return false; + case QPlatformIntegration::SynthesizeMouseFromTouchEvents: + return true; + case QPlatformIntegration::PasswordMaskCharacter: + return defaultThemeHint(PasswordMaskCharacter); + case QPlatformIntegration::SetFocusOnTouchRelease: + return false; + case QPlatformIntegration::ShowIsMaximized: + return false; + case MousePressAndHoldInterval: + return defaultThemeHint(MousePressAndHoldInterval); + default: + break; + } + return QVariant(); +} + +const QPalette *QWinRTTheme::palette(Palette type) const +{ + Q_D(const QWinRTTheme); + if (type == SystemPalette) + return &d->palette; + return QPlatformTheme::palette(type); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrtplatformtheme.h b/src/plugins/platforms/winrt/qwinrttheme.h index f4a61982b2..f7fd07c70d 100644 --- a/src/plugins/platforms/winrt/qwinrtplatformtheme.h +++ b/src/plugins/platforms/winrt/qwinrttheme.h @@ -39,22 +39,32 @@ ** ****************************************************************************/ -#ifndef QWINRTPLATFORMTHEME_H -#define QWINRTPLATFORMTHEME_H +#ifndef QWINRTTHEME_H +#define QWINRTTHEME_H #include <qpa/qplatformtheme.h> +#include <qpa/qplatformintegration.h> QT_BEGIN_NAMESPACE -class QWinRTPlatformTheme : public QPlatformTheme +class QWinRTThemePrivate; +class QWinRTTheme : public QPlatformTheme { public: - QWinRTPlatformTheme(); + QWinRTTheme(); bool usePlatformNativeDialog(DialogType type) const; QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const; + + const QPalette *palette(Palette type = SystemPalette) const Q_DECL_OVERRIDE; + + static QVariant styleHint(QPlatformIntegration::StyleHint hint); + +private: + QScopedPointer<QWinRTThemePrivate> d_ptr; + Q_DECLARE_PRIVATE(QWinRTTheme) }; QT_END_NAMESPACE -#endif // QWINRTPLATFORMTHEME_H +#endif // QWINRTTHEME_H diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro index 349cdf11c9..427920a670 100644 --- a/src/plugins/platforms/winrt/winrt.pro +++ b/src/plugins/platforms/winrt/winrt.pro @@ -35,12 +35,13 @@ SOURCES = \ qwinrtfontdatabase.cpp \ qwinrtinputcontext.cpp \ qwinrtintegration.cpp \ - qwinrtplatformmessagedialoghelper.cpp \ - qwinrtplatformtheme.cpp \ + qwinrtmessagedialoghelper.cpp \ qwinrtscreen.cpp \ qwinrtservices.cpp \ + qwinrttheme.cpp \ qwinrtwindow.cpp + HEADERS = \ qwinrtbackingstore.h \ qwinrtcursor.h \ @@ -49,12 +50,13 @@ HEADERS = \ qwinrtfontdatabase.h \ qwinrtinputcontext.h \ qwinrtintegration.h \ - qwinrtplatformmessagedialoghelper.h \ - qwinrtplatformtheme.h \ + qwinrtmessagedialoghelper.h \ qwinrtscreen.h \ qwinrtservices.h \ + qwinrttheme.h \ qwinrtwindow.h + BLIT_INPUT = $$PWD/blit.hlsl fxc_blitps.commands = fxc.exe /nologo /T ps_4_0_level_9_1 /E blitps /Vn q_blitps /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME} fxc_blitps.output = $$OUT_PWD/blitps.h |