Start the native interface QWindowsApplication

Implement the static parts of QWindowsWindowFunctions.

Move some things around and make them static in tablet support
to make this easier.

Task-number: QTBUG-83252
Change-Id: I24c3b0b3c6548eb96c4f3285a4e46385a1e79ef5
Reviewed-by: André de la Rocha <andre.rocha@qt.io>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
bb10
Friedemann Kleint 2020-07-20 13:09:42 +02:00
parent beab436d77
commit 8e48184120
18 changed files with 200 additions and 210 deletions

View File

@ -368,6 +368,32 @@ Q_GUI_EXPORT size_t qHash(const QGuiApplicationPrivate::ActiveTouchPointsKey &k,
Q_GUI_EXPORT bool operator==(const QGuiApplicationPrivate::ActiveTouchPointsKey &a,
const QGuiApplicationPrivate::ActiveTouchPointsKey &b);
// ----------------- QPlatformInterface -----------------
namespace QPlatformInterface::Private {
#if defined(Q_OS_WIN)
struct Q_GUI_EXPORT QWindowsApplication
{
QT_DECLARE_PLATFORM_INTERFACE(QWindowsApplication)
enum WindowActivationBehavior {
DefaultActivateWindow,
AlwaysActivateWindow
};
virtual WindowActivationBehavior windowActivationBehavior() const = 0;
virtual void setWindowActivationBehavior(WindowActivationBehavior behavior) = 0;
virtual bool isTabletMode() const = 0;
virtual bool isWinTabEnabled() const = 0;
virtual bool setWinTabEnabled(bool enabled) = 0;
};
#endif // Q_OS_WIN
} // QPlatformInterface::Private
QT_END_NAMESPACE
#endif // QGUIAPPLICATION_P_H

View File

@ -65,4 +65,6 @@ QOpenGLContext *QPlatformInterface::QWGLContext::fromNative(HGLRC context, HWND
#endif // QT_NO_OPENGL
QT_DEFINE_PRIVATE_PLATFORM_INTERFACE(QWindowsApplication);
QT_END_NAMESPACE

View File

@ -129,111 +129,3 @@
See also \l [QtDoc] {Fullscreen OpenGL Based Windows}
\sa setHasBorderInFullScreen()
*/
/*!
\enum QWindowsWindowFunctions::WindowActivationBehavior
This enum specifies the behavior of QWidget::activateWindow() and
QWindow::requestActivate().
\value DefaultActivateWindow The window is activated according to the default
behavior of the Windows operating system. This means the window will not
be activated in some circumstances (most notably when the calling process
is not the active process); only the taskbar entry will be flashed.
\value AlwaysActivateWindow The window is always activated, even when the
calling process is not the active process.
\sa QWidget::activateWindow(), QWindow::requestActivate()
\since 5.7
*/
/*!
\typedef QWindowsWindowFunctions::SetWindowActivationBehaviorType
This is the typedef for the function returned by QGuiApplication::platformFunction()
when passed setWindowActivationBehaviorIdentifier().
\sa QWidget::activateWindow(), QWindow::requestActivate()
\since 5.7
*/
/*!
\fn QByteArray QWindowsWindowFunctions::setWindowActivationBehaviorIdentifier()
This function returns a bytearray that can be used to query
QGuiApplication::platformFunction() to retrieve the SetWindowActivationBehaviorType
function.
\sa QWidget::activateWindow(), QWindow::requestActivate()
\since 5.7
*/
/*!
\fn void QWindowsWindowFunctions::setWindowActivationBehavior(WindowActivationBehavior behavior)
This is a convenience function that can be used directly instead of resolving
the function pointer. \a behavior will be relayed to the function retrieved
by QGuiApplication.
\sa QWidget::activateWindow(), QWindow::requestActivate()
\since 5.7
*/
/*!
\typedef QWindowsWindowFunctions::IsTabletModeType
This is the typedef for the function returned by QGuiApplication::platformFunction()
when passed isTabletModeIdentifier().
\since 5.9
*/
/*!
\fn QByteArray QWindowsWindowFunctions::isTabletModeIdentifier()
Returns a bytearray that can be used to query
QGuiApplication::platformFunction() to retrieve the IsTabletModeType
function.
\since 5.9
*/
/*!
\fn bool QWindowsWindowFunctions::isTabletMode()
This is a convenience function that can be used directly instead of resolving
the function pointer. Returns true if Windows 10 operates in \e{Tablet Mode}.
In this mode, Windows forces all application main windows to open in maximized
state. Applications should then avoid resizing windows or restoring geometries
to non-maximized states.
\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

@ -68,11 +68,6 @@ public:
Q_DECLARE_FLAGS(TouchWindowTouchTypes, TouchWindowTouchType)
enum WindowActivationBehavior {
DefaultActivateWindow,
AlwaysActivateWindow
};
typedef void (*SetTouchWindowTouchType)(QWindow *window, QWindowsWindowFunctions::TouchWindowTouchTypes touchType);
static const QByteArray setTouchWindowTouchTypeIdentifier() { return QByteArrayLiteral("WindowsSetTouchWindowTouchType"); }
@ -101,32 +96,6 @@ public:
func(border);
}
typedef void (*SetWindowActivationBehaviorType)(WindowActivationBehavior);
static const QByteArray setWindowActivationBehaviorIdentifier() { return QByteArrayLiteral("WindowsSetWindowActivationBehavior"); }
static void setWindowActivationBehavior(WindowActivationBehavior behavior)
{
SetWindowActivationBehaviorType func = reinterpret_cast<SetWindowActivationBehaviorType>(QGuiApplication::platformFunction(setWindowActivationBehaviorIdentifier()));
if (func)
func(behavior);
}
typedef bool (*IsTabletModeType)();
static const QByteArray isTabletModeIdentifier() { return QByteArrayLiteral("WindowsIsTabletMode"); }
static bool isTabletMode()
{
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

@ -11,6 +11,7 @@ qt_internal_add_plugin(QWindowsIntegrationPlugin
main.cpp
qtwindowsglobal.h
qwin10helpers.cpp qwin10helpers.h
qwindowsapplication.cpp qwindowsapplication.h
qwindowsbackingstore.cpp qwindowsbackingstore.h
qwindowscombase.h
qwindowscontext.cpp qwindowscontext.h

View File

@ -12,6 +12,7 @@ qt_internal_add_plugin(QWindowsIntegrationPlugin
main.cpp
qtwindowsglobal.h
qwin10helpers.cpp qwin10helpers.h
qwindowsapplication.cpp qwindowsapplication.h
qwindowsbackingstore.cpp qwindowsbackingstore.h
qwindowscombase.h
qwindowscontext.cpp qwindowscontext.h

View File

@ -0,0 +1,83 @@
/****************************************************************************
**
** Copyright (C) 2020 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 "qwindowsapplication.h"
#include "qwindowsclipboard.h"
#include "qwindowscontext.h"
#include "qwin10helpers.h"
QT_BEGIN_NAMESPACE
QWindowsApplication::WindowActivationBehavior QWindowsApplication::windowActivationBehavior() const
{
return m_windowActivationBehavior;
}
void QWindowsApplication::setWindowActivationBehavior(WindowActivationBehavior behavior)
{
m_windowActivationBehavior = behavior;
}
bool QWindowsApplication::isTabletMode() const
{
#if QT_CONFIG(clipboard)
if (const QWindowsClipboard *clipboard = QWindowsClipboard::instance())
return qt_windowsIsTabletMode(clipboard->clipboardViewer());
#endif
return false;
}
bool QWindowsApplication::isWinTabEnabled() const
{
auto ctx = QWindowsContext::instance();
return ctx != nullptr && ctx->tabletSupport() != nullptr;
}
bool QWindowsApplication::setWinTabEnabled(bool enabled)
{
if (enabled == isWinTabEnabled())
return true;
auto ctx = QWindowsContext::instance();
if (!ctx)
return false;
return enabled ? ctx->initTablet() : ctx->disposeTablet();
}
QT_END_NAMESPACE

View File

@ -0,0 +1,64 @@
/****************************************************************************
**
** Copyright (C) 2020 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 QWINDOWSAPPLICATION_H
#define QWINDOWSAPPLICATION_H
#include <QtGui/private/qguiapplication_p.h>
QT_BEGIN_NAMESPACE
class QWindowsApplication : public QPlatformInterface::Private::QWindowsApplication
{
public:
WindowActivationBehavior windowActivationBehavior() const override;
void setWindowActivationBehavior(WindowActivationBehavior behavior) override;
bool isTabletMode() const override;
bool isWinTabEnabled() const override;
bool setWinTabEnabled(bool enabled) override;
private:
WindowActivationBehavior m_windowActivationBehavior = DefaultActivateWindow;
};
QT_END_NAMESPACE
#endif // QWINDOWSAPPLICATION_H

View File

@ -374,9 +374,8 @@ bool QWindowsContext::initTouch(unsigned integrationOptions)
return true;
}
bool QWindowsContext::initTablet(unsigned integrationOptions)
bool QWindowsContext::initTablet()
{
Q_UNUSED(integrationOptions);
#if QT_CONFIG(tabletevent)
d->m_tabletSupport.reset(QWindowsTabletSupport::create());
return true;
@ -462,8 +461,7 @@ bool QWindowsContext::initPowerNotificationHandler()
void QWindowsContext::setTabletAbsoluteRange(int a)
{
#if QT_CONFIG(tabletevent)
if (!d->m_tabletSupport.isNull())
d->m_tabletSupport->setAbsoluteRange(a);
QWindowsTabletSupport::setAbsoluteRange(a);
#else
Q_UNUSED(a);
#endif

View File

@ -173,7 +173,7 @@ public:
bool initTouch();
bool initTouch(unsigned integrationOptions); // For calls from QWindowsIntegration::QWindowsIntegration() only.
bool initTablet(unsigned integrationOptions);
bool initTablet();
bool initPointer(unsigned integrationOptions);
bool disposeTablet();
@ -223,7 +223,7 @@ public:
QSharedPointer<QWindowCreationContext> setWindowCreationContext(const QSharedPointer<QWindowCreationContext> &ctx);
QSharedPointer<QWindowCreationContext> windowCreationContext() const;
void setTabletAbsoluteRange(int a);
static void setTabletAbsoluteRange(int a);
void setProcessDpiAwareness(QtWindows::ProcessDpiAwareness dpiAwareness);
static int processDpiAwareness();

View File

@ -139,7 +139,6 @@ struct QWindowsIntegrationPrivate
~QWindowsIntegrationPrivate();
unsigned m_options = 0;
int m_tabletAbsoluteRange = -1;
QWindowsContext m_context;
QPlatformFontDatabase *m_fontDatabase = nullptr;
#if QT_CONFIG(clipboard)
@ -242,16 +241,16 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList &paramL
// 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, &m_tabletAbsoluteRange, &dpiAwareness);
int tabletAbsoluteRange = -1;
m_options = parseOptions(paramList, &tabletAbsoluteRange, &dpiAwareness);
QWindowsFontDatabase::setFontOptions(m_options);
if (tabletAbsoluteRange >= 0)
QWindowsContext::setTabletAbsoluteRange(tabletAbsoluteRange);
if (m_context.initPointer(m_options)) {
if (m_context.initPointer(m_options))
QCoreApplication::setAttribute(Qt::AA_CompressHighFrequencyEvents);
} else {
m_context.initTablet(m_options);
if (m_tabletAbsoluteRange >= 0)
m_context.setTabletAbsoluteRange(m_tabletAbsoluteRange);
}
else
m_context.initTablet();
if (!dpiAwarenessSet) { // Set only once in case of repeated instantiations of QGuiApplication.
if (!QCoreApplication::testAttribute(Qt::AA_PluginApplication)) {
@ -650,28 +649,6 @@ 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

@ -41,6 +41,8 @@
#ifndef QWINDOWSINTEGRATION_H
#define QWINDOWSINTEGRATION_H
#include "qwindowsapplication.h"
#include <qpa/qplatformintegration.h>
#include <QtCore/qscopedpointer.h>
#include <QtGui/private/qwindowsfontdatabase_p.h>
@ -58,6 +60,7 @@ class QWindowsIntegration : public QPlatformIntegration
#ifndef QT_NO_OPENGL
, public QPlatformInterface::Private::QWindowsGLIntegration
#endif
, public QWindowsApplication
{
Q_DISABLE_COPY_MOVE(QWindowsIntegration)
public:
@ -119,8 +122,6 @@ public:
static QWindowsIntegration *instance() { return m_instance; }
static bool setWinTabEnabled(bool enabled);
unsigned options() const;
void beep() const override;

View File

@ -38,7 +38,6 @@
****************************************************************************/
#include "qwindowsnativeinterface.h"
#include "qwindowsclipboard.h"
#include "qwindowswindow.h"
#include "qwindowsscreen.h"
#include "qwindowscontext.h"
@ -84,9 +83,6 @@ static int resourceType(const QByteArray &key)
return int(result - names);
}
QWindowsWindowFunctions::WindowActivationBehavior QWindowsNativeInterface::m_windowActivationBehavior =
QWindowsWindowFunctions::DefaultActivateWindow;
void *QWindowsNativeInterface::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
{
if (!window || !window->handle()) {
@ -260,15 +256,6 @@ QFont QWindowsNativeInterface::logFontToQFont(const void *logFont, int verticalD
return QWindowsFontDatabase::LOGFONT_to_QFont(*reinterpret_cast<const LOGFONT *>(logFont), verticalDpi);
}
bool QWindowsNativeInterface::isTabletMode()
{
#if QT_CONFIG(clipboard)
if (const QWindowsClipboard *clipboard = QWindowsClipboard::instance())
return qt_windowsIsTabletMode(clipboard->clipboardViewer());
#endif
return false;
}
QFunctionPointer QWindowsNativeInterface::platformFunction(const QByteArray &function) const
{
if (function == QWindowsWindowFunctions::setTouchWindowTouchTypeIdentifier())
@ -277,12 +264,6 @@ QFunctionPointer QWindowsNativeInterface::platformFunction(const QByteArray &fun
return QFunctionPointer(QWindowsWindow::setHasBorderInFullScreenStatic);
if (function == QWindowsWindowFunctions::setHasBorderInFullScreenDefaultIdentifier())
return QFunctionPointer(QWindowsWindow::setHasBorderInFullScreenDefault);
if (function == QWindowsWindowFunctions::setWindowActivationBehaviorIdentifier())
return QFunctionPointer(QWindowsNativeInterface::setWindowActivationBehavior);
if (function == QWindowsWindowFunctions::isTabletModeIdentifier())
return QFunctionPointer(QWindowsNativeInterface::isTabletMode);
if (function == QWindowsWindowFunctions::setWinTabEnabledIdentifier())
return QFunctionPointer(QWindowsIntegration::setWinTabEnabled);
return nullptr;
}

View File

@ -104,20 +104,10 @@ public:
QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const override;
void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value) override;
static QWindowsWindowFunctions::WindowActivationBehavior windowActivationBehavior()
{ return QWindowsNativeInterface::m_windowActivationBehavior; }
static void setWindowActivationBehavior(QWindowsWindowFunctions::WindowActivationBehavior b)
{ QWindowsNativeInterface::m_windowActivationBehavior = b; }
static bool isTabletMode();
QFunctionPointer platformFunction(const QByteArray &function) const override;
Q_SIGNALS:
void darkModeChanged(bool);
private:
static QWindowsWindowFunctions::WindowActivationBehavior m_windowActivationBehavior;
};
QT_END_NAMESPACE

View File

@ -206,6 +206,8 @@ bool QWindowsWinTab32DLL::init()
\since 5.2
*/
int QWindowsTabletSupport::m_absoluteRange = 20;
QWindowsTabletSupport::QWindowsTabletSupport(HWND window, HCTX context)
: m_window(window)
, m_context(context)

View File

@ -140,8 +140,8 @@ public:
bool translateTabletProximityEvent(WPARAM wParam, LPARAM lParam);
bool translateTabletPacketEvent();
int absoluteRange() const { return m_absoluteRange; }
void setAbsoluteRange(int a) { m_absoluteRange = a; }
static int absoluteRange() { return m_absoluteRange; }
static void setAbsoluteRange(int a) { m_absoluteRange = a; }
private:
unsigned options() const;
@ -150,7 +150,7 @@ private:
static QWindowsWinTab32DLL m_winTab32DLL;
const HWND m_window;
const HCTX m_context;
int m_absoluteRange = 20;
static int m_absoluteRange;
bool m_tiltSupport = false;
QList<QWindowsTabletDeviceData> m_devices;
int m_currentDevice = -1;

View File

@ -2547,8 +2547,9 @@ void QWindowsWindow::requestActivateWindow()
// when activating windows of inactive applications. Attach to the input of the
// currently active window while setting the foreground window to always activate
// the window when desired.
const auto activationBehavior = QWindowsIntegration::instance()->windowActivationBehavior();
if (QGuiApplication::applicationState() != Qt::ApplicationActive
&& QWindowsNativeInterface::windowActivationBehavior() == QWindowsWindowFunctions::AlwaysActivateWindow) {
&& activationBehavior == QWindowsApplication::AlwaysActivateWindow) {
if (const HWND foregroundWindow = GetForegroundWindow()) {
foregroundThread = GetWindowThreadProcessId(foregroundWindow, nullptr);
if (foregroundThread && foregroundThread != currentThread)

View File

@ -19,6 +19,7 @@ QMAKE_USE_PRIVATE += \
DEFINES *= QT_NO_CAST_FROM_ASCII QT_NO_FOREACH
SOURCES += \
$$PWD/qwindowsapplication.cpp \
$$PWD/qwindowswindow.cpp \
$$PWD/qwindowsintegration.cpp \
$$PWD/qwindowscontext.cpp \
@ -41,6 +42,7 @@ SOURCES += \
$$PWD/qwin10helpers.cpp
HEADERS += \
$$PWD/qwindowsapplication.h \
$$PWD/qwindowscombase.h \
$$PWD/qwindowswindow.h \
$$PWD/qwindowsintegration.h \