Windows: Provide a way to switch between WinTab and Windows Ink at run-time

This change adds the setWinTabEnabled() function to Qt Platform Headers,
which allows an application to set at run-time whether the WinTab API will
be used for tablet input instead of the native Windows Ink API.

[ChangeLog][Windows] The setWinTabEnabled() function added to Qt Platform
Headers now allows an application to set at run-time whether the WinTab API
will be used for tablet input instead of the native Windows Ink API.

Fixes: QTBUG-83218
Change-Id: I51d3c7316baeda136763cf37c2f54295905450ec
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
bb10
Andre de la Rocha 2020-03-31 07:41:45 +02:00
parent ae57e4fba5
commit 4c4693cf96
7 changed files with 76 additions and 4 deletions

View File

@ -108,6 +108,14 @@ public:
IsTabletModeType func = reinterpret_cast<IsTabletModeType>(QGuiApplication::platformFunction(isTabletModeIdentifier()));
return func && func();
}
typedef bool (*SetWinTabEnabled)(bool enabled);
static const QByteArray setWinTabEnabledIdentifier() { return QByteArrayLiteral("WindowsSetWinTabEnabled"); }
static bool setWinTabEnabled(bool enabled)
{
SetWinTabEnabled func = reinterpret_cast<SetWinTabEnabled>(QGuiApplication::platformFunction(setWinTabEnabledIdentifier()));
return func && func(enabled);
}
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QWindowsWindowFunctions::TouchWindowTouchTypes)

View File

@ -210,3 +210,30 @@
\sa QWidget::showMaximized(), QWidget::saveGeometry(), QWidget::restoreGeometry()
\since 5.9
*/
/*!
\typedef QWindowsWindowFunctions::SetWinTabEnabled
\since 6.0
This is the typedef for the function returned by QGuiApplication::platformFunction
when passed setWinTabEnabledIdentifier().
*/
/*!
\fn QByteArray QWindowsWindowFunctions::setWinTabEnabledIdentifier()
\since 6.0
This function returns the bytearray that can be used to query
QGuiApplication::platformFunction to retrieve the SetWinTabEnabled function.
*/
/*!
\fn bool QWindowsWindowFunctions::setWinTabEnabled(bool enabled)
\since 6.0
This is a convenience function that can be used directly instead of resolving
the function pointer.
\a enabled determines whether the WinTab API will be used for tablet input instead
of the native API. Returns true if the operation was successful.
*/

View File

@ -380,6 +380,16 @@ bool QWindowsContext::initTablet(unsigned integrationOptions)
#endif
}
bool QWindowsContext::disposeTablet()
{
#if QT_CONFIG(tabletevent)
d->m_tabletSupport.reset();
return true;
#else
return false;
#endif
}
bool QWindowsContext::initPointer(unsigned integrationOptions)
{
if (integrationOptions & QWindowsIntegration::DontUseWMPointer)

View File

@ -175,6 +175,7 @@ public:
bool initTouch(unsigned integrationOptions); // For calls from QWindowsIntegration::QWindowsIntegration() only.
bool initTablet(unsigned integrationOptions);
bool initPointer(unsigned integrationOptions);
bool disposeTablet();
bool initPowerNotificationHandler();

View File

@ -140,6 +140,7 @@ struct QWindowsIntegrationPrivate
~QWindowsIntegrationPrivate();
unsigned m_options = 0;
int m_tabletAbsoluteRange = -1;
QWindowsContext m_context;
QPlatformFontDatabase *m_fontDatabase = nullptr;
#if QT_CONFIG(clipboard)
@ -239,19 +240,18 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList &paramL
initOpenGlBlacklistResources();
static bool dpiAwarenessSet = false;
int tabletAbsoluteRange = -1;
// Default to per-monitor awareness to avoid being scaled when monitors with different DPI
// are connected to Windows 8.1
QtWindows::ProcessDpiAwareness dpiAwareness = QtWindows::ProcessPerMonitorDpiAware;
m_options = parseOptions(paramList, &tabletAbsoluteRange, &dpiAwareness);
m_options = parseOptions(paramList, &m_tabletAbsoluteRange, &dpiAwareness);
QWindowsFontDatabase::setFontOptions(m_options);
if (m_context.initPointer(m_options)) {
QCoreApplication::setAttribute(Qt::AA_CompressHighFrequencyEvents);
} else {
m_context.initTablet(m_options);
if (tabletAbsoluteRange >= 0)
m_context.setTabletAbsoluteRange(tabletAbsoluteRange);
if (m_tabletAbsoluteRange >= 0)
m_context.setTabletAbsoluteRange(m_tabletAbsoluteRange);
}
if (!dpiAwarenessSet) { // Set only once in case of repeated instantiations of QGuiApplication.
@ -642,6 +642,28 @@ void QWindowsIntegration::beep() const
MessageBeep(MB_OK); // For QApplication
}
bool QWindowsIntegration::setWinTabEnabled(bool enabled)
{
bool ret = false;
if (QWindowsIntegration *p = QWindowsIntegration::instance()) {
if (enabled) {
if (p->d->m_context.tabletSupport()) {
ret = true;
} else {
ret = p->d->m_context.initTablet(p->d->m_options);
if (ret && p->d->m_tabletAbsoluteRange >= 0)
p->d->m_context.setTabletAbsoluteRange(p->d->m_tabletAbsoluteRange);
}
} else {
if (p->d->m_context.tabletSupport())
ret = p->d->m_context.disposeTablet();
else
ret = true;
}
}
return ret;
}
#if QT_CONFIG(vulkan)
QPlatformVulkanInstance *QWindowsIntegration::createPlatformVulkanInstance(QVulkanInstance *instance) const
{

View File

@ -111,6 +111,8 @@ public:
static QWindowsIntegration *instance() { return m_instance; }
static bool setWinTabEnabled(bool enabled);
unsigned options() const;
void beep() const override;

View File

@ -300,6 +300,8 @@ QFunctionPointer QWindowsNativeInterface::platformFunction(const QByteArray &fun
return QFunctionPointer(QWindowsNativeInterface::setWindowActivationBehavior);
if (function == QWindowsWindowFunctions::isTabletModeIdentifier())
return QFunctionPointer(QWindowsNativeInterface::isTabletMode);
if (function == QWindowsWindowFunctions::setWinTabEnabledIdentifier())
return QFunctionPointer(QWindowsIntegration::setWinTabEnabled);
return nullptr;
}