From d377f14fd5b4fe3ed64392c6b743bac395f9f891 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 7 Nov 2016 11:28:16 +0100 Subject: Windows QPA: Detect Windows 10 tablet mode Add new file for dynamically loading Window 10 Helpers via combase.dll and add function qt_windowsIsTabletMode() querying UIViewSettings::get_UserInteractionMode() for "Touch" mode. The style hint QPlatformIntegration::ShowIsMaximized will then reflect the tablet mode setting. Task-number: QTBUG-56831 Change-Id: Ia361dd172fcf0e54fdfc70863c43527f3ea72fe2 Reviewed-by: Oliver Wolff Reviewed-by: Maurice Kalinowski --- src/plugins/platforms/windows/qwin10helpers.cpp | 167 +++++++++++++++++++++ src/plugins/platforms/windows/qwin10helpers.h | 52 +++++++ src/plugins/platforms/windows/qwindowsclipboard.h | 2 + .../platforms/windows/qwindowsintegration.cpp | 7 + src/plugins/platforms/windows/windows.pri | 4 +- 5 files changed, 231 insertions(+), 1 deletion(-) create mode 100644 src/plugins/platforms/windows/qwin10helpers.cpp create mode 100644 src/plugins/platforms/windows/qwin10helpers.h (limited to 'src/plugins/platforms/windows') diff --git a/src/plugins/platforms/windows/qwin10helpers.cpp b/src/plugins/platforms/windows/qwin10helpers.cpp new file mode 100644 index 0000000000..3ded96b9d6 --- /dev/null +++ b/src/plugins/platforms/windows/qwin10helpers.cpp @@ -0,0 +1,167 @@ +/**************************************************************************** +** +** 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 "qwin10helpers.h" + +#include +#include + +#if defined(Q_CC_MINGW) +# define HAS_UI_VIEW_SETTINGS_INTEROP +#elif !defined(Q_CC_MSVC) || _MSC_VER >= 1900 // MSVC2013 is lacking both +# define HAS_UI_VIEW_SETTINGS_INTEROP +# define HAS_UI_VIEW_SETTINGS +#endif + +#include + +#ifdef HAS_UI_VIEW_SETTINGS +# include +#endif + +#ifdef HAS_UI_VIEW_SETTINGS_INTEROP +# include +#endif + +#ifndef HAS_UI_VIEW_SETTINGS_INTEROP +MIDL_INTERFACE("3694dbf9-8f68-44be-8ff5-195c98ede8a6") +IUIViewSettingsInterop : public IInspectable +{ +public: + virtual HRESULT STDMETHODCALLTYPE GetForWindow( + __RPC__in HWND hwnd, + __RPC__in REFIID riid, + __RPC__deref_out_opt void **ppv) = 0; +}; +#endif // !HAS_UI_VIEW_SETTINGS_INTEROP + +#ifndef HAS_UI_VIEW_SETTINGS +namespace ABI { +namespace Windows { +namespace UI { +namespace ViewManagement { + +enum UserInteractionMode { Mouse, Touch }; + +MIDL_INTERFACE("C63657F6-8850-470D-88F8-455E16EA2C26") +IUIViewSettings : public IInspectable +{ +public: + virtual HRESULT STDMETHODCALLTYPE get_UserInteractionMode(UserInteractionMode *value) = 0; +}; + +} // namespace ViewManagement +} // namespace UI +} // namespace Windows +} // namespace ABI +#endif // HAS_UI_VIEW_SETTINGS + +QT_BEGIN_NAMESPACE + +// Starting from Windows 10 +struct QWindowsComBaseDLL +{ + bool init(); + bool isValid() const + { + return roGetActivationFactory != nullptr && windowsCreateStringReference != nullptr; + } + + typedef HRESULT (WINAPI *RoGetActivationFactory)(HSTRING, REFIID, void **); + typedef HRESULT (WINAPI *WindowsCreateStringReference)(PCWSTR, UINT32, HSTRING_HEADER *, HSTRING *); + + RoGetActivationFactory roGetActivationFactory = nullptr; + WindowsCreateStringReference windowsCreateStringReference = nullptr; +}; + +static QWindowsComBaseDLL baseComDll; + +bool QWindowsComBaseDLL::init() +{ + if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS10 && !isValid()) { + QSystemLibrary library(QStringLiteral("combase")); + roGetActivationFactory = + reinterpret_cast(library.resolve("RoGetActivationFactory")); + windowsCreateStringReference = + reinterpret_cast(library.resolve("WindowsCreateStringReference")); + } + return isValid(); +} + +// Return tablet mode, note: Does not work for GetDesktopWindow(). +bool qt_windowsIsTabletMode(HWND hwnd) +{ + bool result = false; + + if (!baseComDll.init()) + return false; + + const wchar_t uiViewSettingsId[] = L"Windows.UI.ViewManagement.UIViewSettings"; + HSTRING_HEADER uiViewSettingsIdRefHeader; + HSTRING uiViewSettingsIdHs = nullptr; + const UINT32 uiViewSettingsIdLen = UINT32(sizeof(uiViewSettingsId) / sizeof(uiViewSettingsId[0]) - 1); + if (FAILED(baseComDll.windowsCreateStringReference(uiViewSettingsId, uiViewSettingsIdLen, &uiViewSettingsIdRefHeader, &uiViewSettingsIdHs))) + return false; + + IUIViewSettingsInterop *uiViewSettingsInterop = nullptr; + // __uuidof(IUIViewSettingsInterop); + const GUID uiViewSettingsInteropRefId = {0x3694dbf9, 0x8f68, 0x44be,{0x8f, 0xf5, 0x19, 0x5c, 0x98, 0xed, 0xe8, 0xa6}}; + + HRESULT hr = baseComDll.roGetActivationFactory(uiViewSettingsIdHs, uiViewSettingsInteropRefId, + reinterpret_cast(&uiViewSettingsInterop)); + if (FAILED(hr)) + return false; + + // __uuidof(ABI::Windows::UI::ViewManagement::IUIViewSettings); + const GUID uiViewSettingsRefId = {0xc63657f6, 0x8850, 0x470d,{0x88, 0xf8, 0x45, 0x5e, 0x16, 0xea, 0x2c, 0x26}}; + ABI::Windows::UI::ViewManagement::IUIViewSettings *viewSettings = nullptr; + hr = uiViewSettingsInterop->GetForWindow(hwnd, uiViewSettingsRefId, + reinterpret_cast(&viewSettings)); + if (SUCCEEDED(hr)) { + ABI::Windows::UI::ViewManagement::UserInteractionMode currentMode; + hr = viewSettings->get_UserInteractionMode(¤tMode); + if (SUCCEEDED(hr)) + result = currentMode == 1; // Touch, 1 + viewSettings->Release(); + } + uiViewSettingsInterop->Release(); + return result; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwin10helpers.h b/src/plugins/platforms/windows/qwin10helpers.h new file mode 100644 index 0000000000..e1485003dd --- /dev/null +++ b/src/plugins/platforms/windows/qwin10helpers.h @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef QWIN10HELPERS_H +#define QWIN10HELPERS_H + +#include +#include + +QT_BEGIN_NAMESPACE + +bool qt_windowsIsTabletMode(HWND hwnd); + +QT_END_NAMESPACE + +#endif // QWIN10HELPERS_H diff --git a/src/plugins/platforms/windows/qwindowsclipboard.h b/src/plugins/platforms/windows/qwindowsclipboard.h index 3fe0c74e78..992d34d492 100644 --- a/src/plugins/platforms/windows/qwindowsclipboard.h +++ b/src/plugins/platforms/windows/qwindowsclipboard.h @@ -73,6 +73,8 @@ public: static QWindowsClipboard *instance() { return m_instance; } + HWND clipboardViewer() const { return m_clipboardViewer; } + private: void clear(); void releaseIData(); diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 004b03d9a9..f49ad0e767 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -41,6 +41,7 @@ #include "qwindowsintegration.h" #include "qwindowswindow.h" #include "qwindowscontext.h" +#include "qwin10helpers.h" #include "qwindowsopenglcontext.h" #include "qwindowsscreen.h" @@ -509,6 +510,12 @@ QVariant QWindowsIntegration::styleHint(QPlatformIntegration::StyleHint hint) co #ifdef SPI_GETKEYBOARDSPEED case KeyboardAutoRepeatRate: return QVariant(keyBoardAutoRepeatRateMS()); +#endif + case QPlatformIntegration::ShowIsMaximized: +#ifndef QT_NO_CLIPBOARD + return qt_windowsIsTabletMode(d->m_clipboard.clipboardViewer()); +#else + break; #endif case QPlatformIntegration::StartDragTime: case QPlatformIntegration::StartDragDistance: diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri index d97e49309f..20e0b81da9 100644 --- a/src/plugins/platforms/windows/windows.pri +++ b/src/plugins/platforms/windows/windows.pri @@ -25,7 +25,8 @@ SOURCES += \ $$PWD/qwindowsdialoghelpers.cpp \ $$PWD/qwindowsservices.cpp \ $$PWD/qwindowsnativeinterface.cpp \ - $$PWD/qwindowsopengltester.cpp + $$PWD/qwindowsopengltester.cpp \ + $$PWD/qwin10helpers.cpp HEADERS += \ $$PWD/qwindowswindow.h \ @@ -46,6 +47,7 @@ HEADERS += \ $$PWD/qwindowsnativeinterface.h \ $$PWD/qwindowsopengltester.h \ $$PWD/qwindowsthreadpoolrunner.h + $$PWD/qwin10helpers.h INCLUDEPATH += $$PWD -- cgit v1.2.3