Merge "Merge remote-tracking branch 'origin/5.12' into 5.13"
This commit is contained in:
commit
65cfac73bd
@ -71,6 +71,16 @@
|
||||
\title CMake AUTOMOC Documentation
|
||||
*/
|
||||
|
||||
/*!
|
||||
\externalpage https://cmake.org/cmake/help/latest/manual/cmake-qt.7.html#autorcc
|
||||
\title CMake AUTORCC Documentation
|
||||
*/
|
||||
|
||||
/*!
|
||||
\externalpage https://cmake.org/cmake/help/latest/manual/cmake-qt.7.html#autouic
|
||||
\title CMake AUTOUIC Documentation
|
||||
*/
|
||||
|
||||
/*!
|
||||
\externalpage https://cmake.org/cmake/help/latest/prop_tgt/LOCATION.html
|
||||
\title CMake LOCATION Documentation
|
||||
|
@ -2002,14 +2002,11 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t)
|
||||
QString dep_cmd = replaceExtraCompilerVariables(tmp_dep_cmd, inpf, tmp_out, LocalShell);
|
||||
dep_cmd = dep_cd_cmd + fixEnvVariables(dep_cmd);
|
||||
if (FILE *proc = QT_POPEN(dep_cmd.toLatin1().constData(), QT_POPEN_READ)) {
|
||||
QString indeps;
|
||||
while(!feof(proc)) {
|
||||
int read_in = (int)fread(buff, 1, 255, proc);
|
||||
if(!read_in)
|
||||
break;
|
||||
indeps += QByteArray(buff, read_in);
|
||||
}
|
||||
QByteArray depData;
|
||||
while (int read_in = feof(proc) ? 0 : (int)fread(buff, 1, 255, proc))
|
||||
depData.append(buff, read_in);
|
||||
QT_PCLOSE(proc);
|
||||
const QString indeps = QString::fromLocal8Bit(depData);
|
||||
if(!indeps.isEmpty()) {
|
||||
QDir outDir(Option::output_dir);
|
||||
QStringList dep_cmd_deps = splitDeps(indeps, dep_lines);
|
||||
@ -2090,14 +2087,11 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t)
|
||||
QString dep_cmd = replaceExtraCompilerVariables(tmp_dep_cmd, inpf, out, LocalShell);
|
||||
dep_cmd = dep_cd_cmd + fixEnvVariables(dep_cmd);
|
||||
if (FILE *proc = QT_POPEN(dep_cmd.toLatin1().constData(), QT_POPEN_READ)) {
|
||||
QString indeps;
|
||||
while(!feof(proc)) {
|
||||
int read_in = (int)fread(buff, 1, 255, proc);
|
||||
if(!read_in)
|
||||
break;
|
||||
indeps += QByteArray(buff, read_in);
|
||||
}
|
||||
QByteArray depData;
|
||||
while (int read_in = feof(proc) ? 0 : (int)fread(buff, 1, 255, proc))
|
||||
depData.append(buff, read_in);
|
||||
QT_PCLOSE(proc);
|
||||
const QString indeps = QString::fromLocal8Bit(depData);
|
||||
if(!indeps.isEmpty()) {
|
||||
QDir outDir(Option::output_dir);
|
||||
QStringList dep_cmd_deps = splitDeps(indeps, dep_lines);
|
||||
|
26
src/corelib/doc/snippets/cmake-macros/examples.cmake
Normal file
26
src/corelib/doc/snippets/cmake-macros/examples.cmake
Normal file
@ -0,0 +1,26 @@
|
||||
#! [qt5_wrap_cpp]
|
||||
set(SOURCES myapp.cpp main.cpp)
|
||||
qt5_wrap_cpp(SOURCES myapp.h)
|
||||
add_executable(myapp ${SOURCES})
|
||||
#! [qt5_wrap_cpp]
|
||||
|
||||
#! [qt5_add_resources]
|
||||
set(SOURCES main.cpp)
|
||||
qt5_add_resources(SOURCES example.qrc)
|
||||
add_executable(myapp ${SOURCES})
|
||||
#! [qt5_add_resources]
|
||||
|
||||
#! [qt5_add_big_resources]
|
||||
set(SOURCES main.cpp)
|
||||
qt5_add_big_resources(SOURCES big_resource.qrc)
|
||||
add_executable(myapp ${SOURCES})
|
||||
#! [qt5_add_big_resources]
|
||||
|
||||
#! [qt5_add_binary_resources]
|
||||
qt5_add_binary_resources(resources project.qrc OPTIONS -no-compress)
|
||||
add_dependencies(myapp resources)
|
||||
#! [qt5_add_binary_resources]
|
||||
|
||||
#! [qt5_generate_moc]
|
||||
qt5_generate_moc(main.cpp main.moc TARGET myapp)
|
||||
#! [qt5_generate_moc]
|
212
src/corelib/doc/src/cmake-macros.qdoc
Normal file
212
src/corelib/doc/src/cmake-macros.qdoc
Normal file
@ -0,0 +1,212 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:FDL$
|
||||
** 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 Free Documentation License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Free
|
||||
** Documentation License version 1.3 as published by the Free Software
|
||||
** Foundation and appearing in the file included in the packaging of
|
||||
** this file. Please review the following information to ensure
|
||||
** the GNU Free Documentation License version 1.3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\page qtcore-cmake-qt5-wrap-cpp.html
|
||||
\ingroup cmake-macros-qtcore
|
||||
|
||||
\title qt5_wrap_cpp
|
||||
|
||||
\brief Creates \c{.moc} files from sources.
|
||||
|
||||
\section1 Synopsis
|
||||
|
||||
\badcode
|
||||
qt5_wrap_cpp(<VAR> src_file1 [src_file2 ...]
|
||||
[TARGET target]
|
||||
[OPTIONS ...]
|
||||
[DEPENDS ...])
|
||||
\endcode
|
||||
|
||||
\section1 Description
|
||||
|
||||
Creates rules for calling \l{moc}{Meta-Object Compiler (moc)} on the given
|
||||
source files. For each input file, an output file is generated in the build
|
||||
directory. The paths of the generated files are added to\c{<VAR>}.
|
||||
|
||||
\note This is a low-level macro. See the \l{CMake AUTOMOC Documentation} for a
|
||||
more convenient way to let source files be processed with \c{moc}.
|
||||
|
||||
\section1 Options
|
||||
|
||||
You can set an explicit \c{TARGET}. This will make sure that the target
|
||||
properties \c{INCLUDE_DIRECTORIES} and \c{COMPILE_DEFINITIONS} are also used
|
||||
when scanning the source files with \c{moc}.
|
||||
|
||||
You can set additional \c{OPTIONS} that should be added to the \c{moc} calls.
|
||||
You can find possible options in the \l{moc}{moc documentation}.
|
||||
|
||||
\c{DEPENDS} allows you to add additional dependencies for recreation of the
|
||||
generated files. This is useful when the sources have implicit dependencies,
|
||||
like code for a Qt plugin that includes a \c{.json} file using the
|
||||
Q_PLUGIN_METADATA() macro.
|
||||
|
||||
\section1 Examples
|
||||
|
||||
\snippet cmake-macros/examples.cmake qt5_wrap_cpp
|
||||
*/
|
||||
|
||||
/*!
|
||||
\page qtcore-cmake-qt5-add-resources.html
|
||||
\ingroup cmake-macros-qtcore
|
||||
|
||||
\title qt5_add_resources
|
||||
|
||||
\brief Compiles binary resources into source code.
|
||||
|
||||
\section1 Synopsis
|
||||
|
||||
\badcode
|
||||
qt5_add_resources(<VAR> file1.qrc [file2.qrc ...]
|
||||
[OPTIONS ...])
|
||||
\endcode
|
||||
|
||||
\section1 Description
|
||||
|
||||
Creates source code from Qt resource files using the
|
||||
\l{Resource Compiler (rcc)}. Paths to the generated source files are added to
|
||||
\c{<VAR>}.
|
||||
|
||||
\note This is a low-level macro. See the \l{CMake AUTORCC Documentation} for a
|
||||
more convenient way to let Qt resource files be processed with \c{rcc}.
|
||||
For embedding bigger resources, see \l qt5_add_big_resources.
|
||||
|
||||
\section1 Arguments
|
||||
|
||||
You can set additional \c{OPTIONS} that should be added to the \c{rcc} calls.
|
||||
You can find possible options in the \l{rcc}{rcc documentation}.
|
||||
|
||||
\section1 Examples
|
||||
|
||||
\snippet cmake-macros/examples.cmake qt5_add_resources
|
||||
*/
|
||||
|
||||
/*!
|
||||
\page qtcore-cmake-qt5-add-big-resources.html
|
||||
\ingroup cmake-macros-qtcore
|
||||
|
||||
\title qt5_add_big_resources
|
||||
|
||||
\brief Compiles big binary resources into object code.
|
||||
|
||||
\section1 Synopsis
|
||||
|
||||
\badcode
|
||||
qt5_add_big_resources(<VAR> file1.qrc [file2.qrc ...]
|
||||
[OPTIONS ...])
|
||||
\endcode
|
||||
|
||||
\section1 Description
|
||||
|
||||
Creates compiled object files from Qt resource files using the
|
||||
\l{Resource Compiler (rcc)}. Paths to the generated files are added to
|
||||
\c{<VAR>}.
|
||||
|
||||
This is similar to \l qt5_add_resources, but directly generates object
|
||||
files (\c .o, \c .obj) files instead of C++ source code. This allows to
|
||||
embed bigger resources, where compiling to C++ sources and then to
|
||||
binaries would be too time consuming or memory intensive.
|
||||
|
||||
\section1 Arguments
|
||||
|
||||
You can set additional \c{OPTIONS} that should be added to the \c{rcc} calls.
|
||||
You can find possible options in the \l{rcc}{rcc documentation}.
|
||||
|
||||
\section1 Examples
|
||||
|
||||
\snippet cmake-macros/examples.cmake qt5_add_big_resources
|
||||
*/
|
||||
|
||||
/*!
|
||||
\page qtcore-cmake-qt5_add_binary_resources.html
|
||||
\ingroup cmake-macros-qtcore
|
||||
|
||||
\title qt5_add_binary_resources
|
||||
|
||||
\brief Creates an \c{RCC} file from a list of Qt resource files.
|
||||
|
||||
\section1 Synopsis
|
||||
|
||||
\badcode
|
||||
qt5_add_binary_resources(target file1.qrc [file2.qrc ...]
|
||||
[DESTINATION ...]
|
||||
[OPTIONS ...])
|
||||
\endcode
|
||||
|
||||
\section1 Description
|
||||
|
||||
Adds a custom \c target that compiles Qt resource files into a binary \c{.rcc}
|
||||
file.
|
||||
|
||||
\section1 Arguments
|
||||
|
||||
\c{DESTINATION} sets the path of the generated \c{.rcc} file. The default is
|
||||
\c{${CMAKE_CURRENT_BINARY_DIR}/${target}.rcc}.
|
||||
|
||||
You can set additional \c{OPTIONS} that should be added to the \c{rcc} calls.
|
||||
You can find possible options in the \l{rcc}{rcc documentation}.
|
||||
|
||||
\section1 Examples
|
||||
|
||||
\snippet cmake-macros/examples.cmake qt5_add_binary_resources
|
||||
*/
|
||||
|
||||
/*!
|
||||
\page qtcore-cmake-qt5-generate-moc.html
|
||||
\ingroup cmake-macros-qtcore
|
||||
|
||||
\title qt5_generate_moc
|
||||
|
||||
\brief Calls moc on an input file.
|
||||
|
||||
\section1 Synopsis
|
||||
|
||||
\badcode
|
||||
qt5_generate_moc(src_file dest_file
|
||||
[TARGET target])
|
||||
\endcode
|
||||
|
||||
\section1 Description
|
||||
|
||||
Creates a rule to call the \l{moc}{Meta-Object Compiler (moc)} on \c src_file
|
||||
and store the output in \c dest_file.
|
||||
|
||||
\note This is a low-level macro. See the \l{CMake AUTOMOC Documentation} for a
|
||||
more convenient way to let source files be processed with \c{moc}.
|
||||
\l qt5_wrap_cpp is also similar, but automatically generates a temporary file
|
||||
path for you.
|
||||
|
||||
\section1 Arguments
|
||||
|
||||
You can set an explicit \c{TARGET}. This will make sure that the target
|
||||
properties \c{INCLUDE_DIRECTORIES} and \c{COMPILE_DEFINITIONS} are also used
|
||||
when scanning the source files with \c{moc}.
|
||||
|
||||
\section1 Examples
|
||||
|
||||
\snippet cmake-macros/examples.cmake qt5_generate_moc
|
||||
*/
|
@ -230,7 +230,8 @@ public:
|
||||
|
||||
template<typename T> static QMetaEnum fromType() {
|
||||
Q_STATIC_ASSERT_X(QtPrivate::IsQEnumHelper<T>::Value,
|
||||
"QMetaEnum::fromType only works with enums declared as Q_ENUM or Q_FLAG");
|
||||
"QMetaEnum::fromType only works with enums declared as "
|
||||
"Q_ENUM, Q_ENUM_NS, Q_FLAG or Q_FLAG_NS");
|
||||
const QMetaObject *metaObject = qt_getEnumMetaObject(T());
|
||||
const char *name = qt_getEnumName(T());
|
||||
return metaObject->enumerator(metaObject->indexOfEnumerator(name));
|
||||
|
@ -492,5 +492,13 @@ QPoint QHighDpiScaling::origin(const QPlatformScreen *platformScreen)
|
||||
return platformScreen->geometry().topLeft();
|
||||
}
|
||||
|
||||
QPoint QHighDpiScaling::origin(const QWindow *window)
|
||||
{
|
||||
if (window && window->isTopLevel() && window->screen())
|
||||
return window->screen()->geometry().topLeft();
|
||||
|
||||
return QPoint(0, 0);
|
||||
}
|
||||
|
||||
#endif //QT_NO_HIGHDPISCALING
|
||||
QT_END_NAMESPACE
|
||||
|
@ -83,6 +83,7 @@ public:
|
||||
static qreal factor(const QPlatformScreen *platformScreen);
|
||||
static QPoint origin(const QScreen *screen);
|
||||
static QPoint origin(const QPlatformScreen *platformScreen);
|
||||
static QPoint origin(const QWindow *window);
|
||||
static QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen);
|
||||
static QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen);
|
||||
static QPoint mapPositionToGlobal(const QPoint &pos, const QPoint &windowGlobalPosition, const QWindow *window);
|
||||
@ -203,94 +204,42 @@ inline QPointF toNativeLocalPosition(const QPointF &pos, const QWindow *window)
|
||||
return pos * scaleFactor;
|
||||
}
|
||||
|
||||
inline QRect fromNativePixels(const QRect &pixelRect, const QPlatformScreen *platformScreen)
|
||||
template <typename C>
|
||||
inline QRect fromNativePixels(const QRect &pixelRect, const C *context)
|
||||
{
|
||||
const qreal scaleFactor = QHighDpiScaling::factor(platformScreen);
|
||||
const QPoint origin = QHighDpiScaling::origin(platformScreen);
|
||||
const qreal scaleFactor = QHighDpiScaling::factor(context);
|
||||
const QPoint origin = QHighDpiScaling::origin(context);
|
||||
return QRect(fromNative(pixelRect.topLeft(), scaleFactor, origin),
|
||||
fromNative(pixelRect.size(), scaleFactor));
|
||||
}
|
||||
|
||||
inline QRect toNativePixels(const QRect &pointRect, const QPlatformScreen *platformScreen)
|
||||
template <typename C>
|
||||
inline QRect toNativePixels(const QRect &pointRect, const C *context)
|
||||
{
|
||||
const qreal scaleFactor = QHighDpiScaling::factor(platformScreen);
|
||||
const QPoint origin = QHighDpiScaling::origin(platformScreen);
|
||||
const qreal scaleFactor = QHighDpiScaling::factor(context);
|
||||
const QPoint origin = QHighDpiScaling::origin(context);
|
||||
return QRect(toNative(pointRect.topLeft(), scaleFactor, origin),
|
||||
toNative(pointRect.size(), scaleFactor));
|
||||
}
|
||||
|
||||
inline QRect fromNativePixels(const QRect &pixelRect, const QScreen *screen)
|
||||
template <typename C>
|
||||
inline QRectF toNativePixels(const QRectF &pointRect, const C *context)
|
||||
{
|
||||
const qreal scaleFactor = QHighDpiScaling::factor(screen);
|
||||
const QPoint origin = QHighDpiScaling::origin(screen);
|
||||
return QRect(fromNative(pixelRect.topLeft(), scaleFactor, origin),
|
||||
fromNative(pixelRect.size(), scaleFactor));
|
||||
}
|
||||
|
||||
inline QRect toNativePixels(const QRect &pointRect, const QScreen *screen)
|
||||
{
|
||||
const qreal scaleFactor = QHighDpiScaling::factor(screen);
|
||||
const QPoint origin = QHighDpiScaling::origin(screen);
|
||||
return QRect(toNative(pointRect.topLeft(), scaleFactor, origin),
|
||||
toNative(pointRect.size(), scaleFactor));
|
||||
}
|
||||
|
||||
inline QRect fromNativePixels(const QRect &pixelRect, const QWindow *window)
|
||||
{
|
||||
if (window && window->isTopLevel() && window->screen()) {
|
||||
return fromNativePixels(pixelRect, window->screen());
|
||||
} else {
|
||||
const qreal scaleFactor = QHighDpiScaling::factor(window);
|
||||
return QRect(pixelRect.topLeft() / scaleFactor, fromNative(pixelRect.size(), scaleFactor));
|
||||
}
|
||||
}
|
||||
|
||||
inline QRectF toNativePixels(const QRectF &pointRect, const QScreen *screen)
|
||||
{
|
||||
const qreal scaleFactor = QHighDpiScaling::factor(screen);
|
||||
const QPoint origin = QHighDpiScaling::origin(screen);
|
||||
const qreal scaleFactor = QHighDpiScaling::factor(context);
|
||||
const QPoint origin = QHighDpiScaling::origin(context);
|
||||
return QRectF(toNative(pointRect.topLeft(), scaleFactor, origin),
|
||||
toNative(pointRect.size(), scaleFactor));
|
||||
toNative(pointRect.size(), scaleFactor));
|
||||
}
|
||||
|
||||
inline QRect toNativePixels(const QRect &pointRect, const QWindow *window)
|
||||
template <typename C>
|
||||
inline QRectF fromNativePixels(const QRectF &pixelRect, const C *context)
|
||||
{
|
||||
if (window && window->isTopLevel() && window->screen()) {
|
||||
return toNativePixels(pointRect, window->screen());
|
||||
} else {
|
||||
const qreal scaleFactor = QHighDpiScaling::factor(window);
|
||||
return QRect(pointRect.topLeft() * scaleFactor, toNative(pointRect.size(), scaleFactor));
|
||||
}
|
||||
}
|
||||
|
||||
inline QRectF fromNativePixels(const QRectF &pixelRect, const QScreen *screen)
|
||||
{
|
||||
const qreal scaleFactor = QHighDpiScaling::factor(screen);
|
||||
const QPoint origin = QHighDpiScaling::origin(screen);
|
||||
const qreal scaleFactor = QHighDpiScaling::factor(context);
|
||||
const QPoint origin = QHighDpiScaling::origin(context);
|
||||
return QRectF(fromNative(pixelRect.topLeft(), scaleFactor, origin),
|
||||
fromNative(pixelRect.size(), scaleFactor));
|
||||
}
|
||||
|
||||
inline QRectF fromNativePixels(const QRectF &pixelRect, const QWindow *window)
|
||||
{
|
||||
if (window && window->isTopLevel() && window->screen()) {
|
||||
return fromNativePixels(pixelRect, window->screen());
|
||||
} else {
|
||||
const qreal scaleFactor = QHighDpiScaling::factor(window);
|
||||
return QRectF(pixelRect.topLeft() / scaleFactor, pixelRect.size() / scaleFactor);
|
||||
}
|
||||
}
|
||||
|
||||
inline QRectF toNativePixels(const QRectF &pointRect, const QWindow *window)
|
||||
{
|
||||
if (window && window->isTopLevel() && window->screen()) {
|
||||
return toNativePixels(pointRect, window->screen());
|
||||
} else {
|
||||
const qreal scaleFactor = QHighDpiScaling::factor(window);
|
||||
return QRectF(pointRect.topLeft() * scaleFactor, pointRect.size() * scaleFactor);
|
||||
}
|
||||
}
|
||||
|
||||
inline QSize fromNativePixels(const QSize &pixelSize, const QWindow *window)
|
||||
{
|
||||
return pixelSize / QHighDpiScaling::factor(window);
|
||||
@ -311,56 +260,28 @@ inline QSizeF toNativePixels(const QSizeF &pointSize, const QWindow *window)
|
||||
return pointSize * QHighDpiScaling::factor(window);
|
||||
}
|
||||
|
||||
inline QPoint fromNativePixels(const QPoint &pixelPoint, const QScreen *screen)
|
||||
template <typename C>
|
||||
inline QPoint fromNativePixels(const QPoint &pixelPoint, const C *context)
|
||||
{
|
||||
return fromNative(pixelPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen));
|
||||
return fromNative(pixelPoint, QHighDpiScaling::factor(context), QHighDpiScaling::origin(context));
|
||||
}
|
||||
|
||||
inline QPoint fromNativePixels(const QPoint &pixelPoint, const QWindow *window)
|
||||
template <typename C>
|
||||
inline QPoint toNativePixels(const QPoint &pointPoint, const C *context)
|
||||
{
|
||||
if (window && window->isTopLevel() && window->screen())
|
||||
return fromNativePixels(pixelPoint, window->screen());
|
||||
else
|
||||
return pixelPoint / QHighDpiScaling::factor(window);
|
||||
return toNative(pointPoint, QHighDpiScaling::factor(context), QHighDpiScaling::origin(context));
|
||||
}
|
||||
|
||||
inline QPoint toNativePixels(const QPoint &pointPoint, const QScreen *screen)
|
||||
template <typename C>
|
||||
inline QPointF fromNativePixels(const QPointF &pixelPoint, const C *context)
|
||||
{
|
||||
return toNative(pointPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen));
|
||||
return fromNative(pixelPoint, QHighDpiScaling::factor(context), QHighDpiScaling::origin(context));
|
||||
}
|
||||
|
||||
inline QPoint toNativePixels(const QPoint &pointPoint, const QWindow *window)
|
||||
template <typename C>
|
||||
inline QPointF toNativePixels(const QPointF &pointPoint, const C *context)
|
||||
{
|
||||
if (window && window->isTopLevel() && window->screen())
|
||||
return toNativePixels(pointPoint, window->screen());
|
||||
else
|
||||
return pointPoint * QHighDpiScaling::factor(window);
|
||||
}
|
||||
|
||||
inline QPointF fromNativePixels(const QPointF &pixelPoint, const QScreen *screen)
|
||||
{
|
||||
return fromNative(pixelPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen));
|
||||
}
|
||||
|
||||
inline QPointF fromNativePixels(const QPointF &pixelPoint, const QWindow *window)
|
||||
{
|
||||
if (window && window->isTopLevel() && window->screen())
|
||||
return fromNativePixels(pixelPoint, window->screen());
|
||||
else
|
||||
return pixelPoint / QHighDpiScaling::factor(window);
|
||||
}
|
||||
|
||||
inline QPointF toNativePixels(const QPointF &pointPoint, const QScreen *screen)
|
||||
{
|
||||
return toNative(pointPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen));
|
||||
}
|
||||
|
||||
inline QPointF toNativePixels(const QPointF &pointPoint, const QWindow *window)
|
||||
{
|
||||
if (window && window->isTopLevel() && window->screen())
|
||||
return toNativePixels(pointPoint, window->screen());
|
||||
else
|
||||
return pointPoint * QHighDpiScaling::factor(window);
|
||||
return toNative(pointPoint, QHighDpiScaling::factor(context), QHighDpiScaling::origin(context));
|
||||
}
|
||||
|
||||
inline QMargins fromNativePixels(const QMargins &pixelMargins, const QWindow *window)
|
||||
@ -425,47 +346,26 @@ inline QRegion toNativeLocalRegion(const QRegion &pointRegion, const QWindow *wi
|
||||
}
|
||||
|
||||
// Any T that has operator/()
|
||||
template <typename T>
|
||||
T fromNativePixels(const T &pixelValue, const QWindow *window)
|
||||
template <typename T, typename C>
|
||||
T fromNativePixels(const T &pixelValue, const C *context)
|
||||
{
|
||||
if (!QHighDpiScaling::isActive())
|
||||
return pixelValue;
|
||||
|
||||
return pixelValue / QHighDpiScaling::factor(window);
|
||||
|
||||
}
|
||||
|
||||
//##### ?????
|
||||
template <typename T>
|
||||
T fromNativePixels(const T &pixelValue, const QScreen *screen)
|
||||
{
|
||||
if (!QHighDpiScaling::isActive())
|
||||
return pixelValue;
|
||||
|
||||
return pixelValue / QHighDpiScaling::factor(screen);
|
||||
return pixelValue / QHighDpiScaling::factor(context);
|
||||
|
||||
}
|
||||
|
||||
// Any T that has operator*()
|
||||
template <typename T>
|
||||
T toNativePixels(const T &pointValue, const QWindow *window)
|
||||
template <typename T, typename C>
|
||||
T toNativePixels(const T &pointValue, const C *context)
|
||||
{
|
||||
if (!QHighDpiScaling::isActive())
|
||||
return pointValue;
|
||||
|
||||
return pointValue * QHighDpiScaling::factor(window);
|
||||
return pointValue * QHighDpiScaling::factor(context);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T toNativePixels(const T &pointValue, const QScreen *screen)
|
||||
{
|
||||
if (!QHighDpiScaling::isActive())
|
||||
return pointValue;
|
||||
|
||||
return pointValue * QHighDpiScaling::factor(screen);
|
||||
}
|
||||
|
||||
|
||||
// Any QVector<T> where T has operator/()
|
||||
template <typename T>
|
||||
QVector<T> fromNativePixels(const QVector<T> &pixelValues, const QWindow *window)
|
||||
|
@ -705,14 +705,20 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w,
|
||||
w, defaultWidth, defaultHeight);
|
||||
return QRect(initialGeometry.topLeft(), QHighDpi::toNative(size, factor));
|
||||
}
|
||||
const QScreen *screen = effectiveScreen(w);
|
||||
const auto *wp = qt_window_private(const_cast<QWindow*>(w));
|
||||
const bool position = wp->positionAutomatic && w->type() != Qt::Popup;
|
||||
if (!position && !wp->resizeAutomatic)
|
||||
return initialGeometry;
|
||||
const QScreen *screen = wp->positionAutomatic
|
||||
? effectiveScreen(w)
|
||||
: QGuiApplication::screenAt(initialGeometry.center());
|
||||
if (!screen)
|
||||
return initialGeometry;
|
||||
const auto *wp = qt_window_private(const_cast<QWindow*>(w));
|
||||
// initialGeometry refers to window's screen
|
||||
QRect rect(QHighDpi::fromNativePixels(initialGeometry, w));
|
||||
if (wp->resizeAutomatic)
|
||||
rect.setSize(fixInitialSize(rect.size(), w, defaultWidth, defaultHeight));
|
||||
if (wp->positionAutomatic && w->type() != Qt::Popup) {
|
||||
if (position) {
|
||||
const QRect availableGeometry = screen->availableGeometry();
|
||||
// Center unless the geometry ( + unknown window frame) is too large for the screen).
|
||||
if (rect.height() < (availableGeometry.height() * 8) / 9
|
||||
|
@ -43,6 +43,7 @@
|
||||
|
||||
#include "qtextodfwriter_p.h"
|
||||
|
||||
#include <QImageReader>
|
||||
#include <QImageWriter>
|
||||
#include <QTextListFormat>
|
||||
#include <QTextList>
|
||||
@ -410,6 +411,29 @@ void QTextOdfWriter::writeBlock(QXmlStreamWriter &writer, const QTextBlock &bloc
|
||||
writer.writeEndElement(); // list-item
|
||||
}
|
||||
|
||||
static bool probeImageData(QIODevice *device, QImage *image, QString *mimeType, qreal *width, qreal *height)
|
||||
{
|
||||
QImageReader reader(device);
|
||||
const QByteArray format = reader.format().toLower();
|
||||
if (format == "png") {
|
||||
*mimeType = QStringLiteral("image/png");
|
||||
} else if (format == "jpg") {
|
||||
*mimeType = QStringLiteral("image/jpg");
|
||||
} else if (format == "svg") {
|
||||
*mimeType = QStringLiteral("image/svg+xml");
|
||||
} else {
|
||||
*image = reader.read();
|
||||
return false;
|
||||
}
|
||||
|
||||
const QSize size = reader.size();
|
||||
|
||||
*width = size.width();
|
||||
*height = size.height();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QTextOdfWriter::writeInlineCharacter(QXmlStreamWriter &writer, const QTextFragment &fragment) const
|
||||
{
|
||||
writer.writeStartElement(drawNS, QString::fromLatin1("frame"));
|
||||
@ -420,47 +444,73 @@ void QTextOdfWriter::writeInlineCharacter(QXmlStreamWriter &writer, const QTextF
|
||||
QTextImageFormat imageFormat = fragment.charFormat().toImageFormat();
|
||||
writer.writeAttribute(drawNS, QString::fromLatin1("name"), imageFormat.name());
|
||||
|
||||
QByteArray data;
|
||||
QString mimeType;
|
||||
qreal width = 0;
|
||||
qreal height = 0;
|
||||
|
||||
QImage image;
|
||||
QString name = imageFormat.name();
|
||||
if (name.startsWith(QLatin1String(":/"))) // auto-detect resources
|
||||
name.prepend(QLatin1String("qrc"));
|
||||
QUrl url = QUrl(name);
|
||||
const QVariant data = m_document->resource(QTextDocument::ImageResource, url);
|
||||
if (data.type() == QVariant::Image) {
|
||||
image = qvariant_cast<QImage>(data);
|
||||
} else if (data.type() == QVariant::ByteArray) {
|
||||
image.loadFromData(data.toByteArray());
|
||||
}
|
||||
const QVariant variant = m_document->resource(QTextDocument::ImageResource, url);
|
||||
if (variant.type() == QVariant::Image) {
|
||||
image = qvariant_cast<QImage>(variant);
|
||||
} else if (variant.type() == QVariant::ByteArray) {
|
||||
data = variant.toByteArray();
|
||||
|
||||
if (image.isNull()) {
|
||||
if (image.isNull()) { // try direct loading
|
||||
name = imageFormat.name(); // remove qrc:/ prefix again
|
||||
image.load(name);
|
||||
QBuffer buffer(&data);
|
||||
buffer.open(QIODevice::ReadOnly);
|
||||
probeImageData(&buffer, &image, &mimeType, &width, &height);
|
||||
} else {
|
||||
// try direct loading
|
||||
QFile file(imageFormat.name());
|
||||
if (file.open(QIODevice::ReadOnly) && !probeImageData(&file, &image, &mimeType, &width, &height)) {
|
||||
file.seek(0);
|
||||
data = file.readAll();
|
||||
}
|
||||
}
|
||||
|
||||
if (! image.isNull()) {
|
||||
QBuffer imageBytes;
|
||||
QString filename = m_strategy->createUniqueImageName();
|
||||
|
||||
int imgQuality = imageFormat.quality();
|
||||
if (imgQuality >= 100 || imgQuality < 0 || image.hasAlphaChannel()) {
|
||||
QImageWriter imageWriter(&imageBytes, "png");
|
||||
imageWriter.write(image);
|
||||
m_strategy->addFile(filename, QString::fromLatin1("image/png"), imageBytes.data());
|
||||
|
||||
data = imageBytes.data();
|
||||
mimeType = QStringLiteral("image/png");
|
||||
} else {
|
||||
// Write images without alpha channel as jpg with quality set by QTextImageFormat
|
||||
QImageWriter imageWriter(&imageBytes, "jpg");
|
||||
imageWriter.setQuality(imgQuality);
|
||||
imageWriter.write(image);
|
||||
m_strategy->addFile(filename, QString::fromLatin1("image/jpg"), imageBytes.data());
|
||||
|
||||
data = imageBytes.data();
|
||||
mimeType = QStringLiteral("image/jpg");
|
||||
}
|
||||
// get the width/height from the format.
|
||||
qreal width = imageFormat.hasProperty(QTextFormat::ImageWidth)
|
||||
? imageFormat.width() : image.width();
|
||||
|
||||
width = image.width();
|
||||
height = image.height();
|
||||
}
|
||||
|
||||
if (!data.isEmpty()) {
|
||||
if (imageFormat.hasProperty(QTextFormat::ImageWidth)) {
|
||||
width = imageFormat.width();
|
||||
}
|
||||
if (imageFormat.hasProperty(QTextFormat::ImageHeight)) {
|
||||
height = imageFormat.height();
|
||||
}
|
||||
|
||||
QString filename = m_strategy->createUniqueImageName();
|
||||
|
||||
m_strategy->addFile(filename, mimeType, data);
|
||||
|
||||
writer.writeAttribute(svgNS, QString::fromLatin1("width"), pixelToPoint(width));
|
||||
qreal height = imageFormat.hasProperty(QTextFormat::ImageHeight)
|
||||
? imageFormat.height() : image.height();
|
||||
writer.writeAttribute(svgNS, QString::fromLatin1("height"), pixelToPoint(height));
|
||||
writer.writeAttribute(textNS, QStringLiteral("anchor-type"), QStringLiteral("as-char"));
|
||||
writer.writeStartElement(drawNS, QString::fromLatin1("image"));
|
||||
writer.writeAttribute(xlinkNS, QString::fromLatin1("href"), filename);
|
||||
writer.writeEndElement(); // image
|
||||
|
@ -435,8 +435,23 @@ QList<QByteArray> QMacPasteboardMimeUnicodeText::convertFromMime(const QString &
|
||||
if (flavor == QLatin1String("public.utf8-plain-text"))
|
||||
ret.append(string.toUtf8());
|
||||
#if QT_CONFIG(textcodec)
|
||||
else if (flavor == QLatin1String("public.utf16-plain-text"))
|
||||
ret.append(QTextCodec::codecForName("UTF-16")->fromUnicode(string));
|
||||
else if (flavor == QLatin1String("public.utf16-plain-text")) {
|
||||
QTextCodec::ConverterState state;
|
||||
#if defined(Q_OS_MACOS)
|
||||
// Some applications such as Microsoft Excel, don't deal well with
|
||||
// a BOM present, so we follow the traditional approach of Qt on
|
||||
// macOS to not generate public.utf16-plain-text with a BOM.
|
||||
state.flags = QTextCodec::IgnoreHeader;
|
||||
#else
|
||||
// Whereas iOS applications will fail to paste if we do _not_
|
||||
// include a BOM in the public.utf16-plain-text content, most
|
||||
// likely due to converting the data using NSUTF16StringEncoding
|
||||
// which assumes big-endian byte order if there is no BOM.
|
||||
state.flags = QTextCodec::DefaultConversion;
|
||||
#endif
|
||||
ret.append(QTextCodec::codecForName("UTF-16")->fromUnicode(
|
||||
string.constData(), string.length(), &state));
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
@ -360,4 +360,27 @@ __CRT_UUID_DECL(IGridItemProvider, 0xd02541f1, 0xfb81, 0x4d64, 0xae,0x32, 0xf5,0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __IWindowProvider_INTERFACE_DEFINED__
|
||||
#define __IWindowProvider_INTERFACE_DEFINED__
|
||||
DEFINE_GUID(IID_IWindowProvider, 0x987df77b, 0xdb06, 0x4d77, 0x8f,0x8a, 0x86,0xa9,0xc3,0xbb,0x90,0xb9);
|
||||
MIDL_INTERFACE("987df77b-db06-4d77-8f8a-86a9c3bb90b9")
|
||||
IWindowProvider : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE SetVisualState(enum WindowVisualState state) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE Close( void) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE WaitForInputIdle(int milliseconds, __RPC__out BOOL *pRetVal) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE get_CanMaximize(__RPC__out BOOL *pRetVal) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE get_CanMinimize(__RPC__out BOOL *pRetVal) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE get_IsModal(__RPC__out BOOL *pRetVal) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE get_WindowVisualState(__RPC__out enum WindowVisualState *pRetVal) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE get_WindowInteractionState(__RPC__out enum WindowInteractionState *pRetVal) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE get_IsTopmost(__RPC__out BOOL *pRetVal) = 0;
|
||||
};
|
||||
#ifdef __CRT_UUID_DECL
|
||||
__CRT_UUID_DECL(IWindowProvider, 0x987df77b, 0xdb06, 0x4d77, 0x8f,0x8a, 0x86,0xa9,0xc3,0xbb,0x90,0xb9)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -141,6 +141,20 @@ enum PropertyConditionFlags {
|
||||
PropertyConditionFlags_IgnoreCase = 1
|
||||
};
|
||||
|
||||
enum WindowVisualState {
|
||||
WindowVisualState_Normal = 0,
|
||||
WindowVisualState_Maximized = 1,
|
||||
WindowVisualState_Minimized = 2
|
||||
};
|
||||
|
||||
enum WindowInteractionState {
|
||||
WindowInteractionState_Running = 0,
|
||||
WindowInteractionState_Closing = 1,
|
||||
WindowInteractionState_ReadyForUserInteraction = 2,
|
||||
WindowInteractionState_BlockedByModalWindow = 3,
|
||||
WindowInteractionState_NotResponding = 4
|
||||
};
|
||||
|
||||
struct UiaRect {
|
||||
double left;
|
||||
double top;
|
||||
|
@ -1129,46 +1129,63 @@ QString QAndroidInputContext::getSelectedText(jint /*flags*/)
|
||||
|
||||
QString QAndroidInputContext::getTextAfterCursor(jint length, jint /*flags*/)
|
||||
{
|
||||
//### the preedit text could theoretically be after the cursor
|
||||
QVariant textAfter = QInputMethod::queryFocusObject(Qt::ImTextAfterCursor, QVariant(length));
|
||||
if (textAfter.isValid()) {
|
||||
return textAfter.toString().left(length);
|
||||
}
|
||||
|
||||
//compatibility code for old controls that do not implement the new API
|
||||
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
|
||||
if (query.isNull())
|
||||
if (length <= 0)
|
||||
return QString();
|
||||
|
||||
QString text = query->value(Qt::ImSurroundingText).toString();
|
||||
if (!text.length())
|
||||
return text;
|
||||
QString text;
|
||||
|
||||
int cursorPos = query->value(Qt::ImCursorPosition).toInt();
|
||||
return text.mid(cursorPos, length);
|
||||
QVariant reportedTextAfter = QInputMethod::queryFocusObject(Qt::ImTextAfterCursor, length);
|
||||
if (reportedTextAfter.isValid()) {
|
||||
text = reportedTextAfter.toString();
|
||||
} else {
|
||||
// Compatibility code for old controls that do not implement the new API
|
||||
QSharedPointer<QInputMethodQueryEvent> query =
|
||||
focusObjectInputMethodQuery(Qt::ImCursorPosition | Qt::ImSurroundingText);
|
||||
if (query) {
|
||||
const int cursorPos = query->value(Qt::ImCursorPosition).toInt();
|
||||
text = query->value(Qt::ImSurroundingText).toString().mid(cursorPos);
|
||||
}
|
||||
}
|
||||
|
||||
// Controls do not report preedit text, so we have to add it
|
||||
if (!m_composingText.isEmpty()) {
|
||||
const int cursorPosInsidePreedit = m_composingCursor - m_composingTextStart;
|
||||
text = m_composingText.midRef(cursorPosInsidePreedit) + text;
|
||||
}
|
||||
|
||||
text.truncate(length);
|
||||
return text;
|
||||
}
|
||||
|
||||
QString QAndroidInputContext::getTextBeforeCursor(jint length, jint /*flags*/)
|
||||
{
|
||||
QVariant textBefore = QInputMethod::queryFocusObject(Qt::ImTextBeforeCursor, QVariant(length));
|
||||
if (textBefore.isValid())
|
||||
return textBefore.toString().rightRef(length) + m_composingText;
|
||||
|
||||
//compatibility code for old controls that do not implement the new API
|
||||
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
|
||||
if (query.isNull())
|
||||
if (length <= 0)
|
||||
return QString();
|
||||
|
||||
int cursorPos = query->value(Qt::ImCursorPosition).toInt();
|
||||
QString text = query->value(Qt::ImSurroundingText).toString();
|
||||
if (!text.length())
|
||||
return text;
|
||||
QString text;
|
||||
|
||||
//### the preedit text does not need to be immediately before the cursor
|
||||
if (cursorPos <= length)
|
||||
return text.leftRef(cursorPos) + m_composingText;
|
||||
else
|
||||
return text.midRef(cursorPos - length, length) + m_composingText;
|
||||
QVariant reportedTextBefore = QInputMethod::queryFocusObject(Qt::ImTextBeforeCursor, length);
|
||||
if (reportedTextBefore.isValid()) {
|
||||
text = reportedTextBefore.toString();
|
||||
} else {
|
||||
// Compatibility code for old controls that do not implement the new API
|
||||
QSharedPointer<QInputMethodQueryEvent> query =
|
||||
focusObjectInputMethodQuery(Qt::ImCursorPosition | Qt::ImSurroundingText);
|
||||
if (query) {
|
||||
const int cursorPos = query->value(Qt::ImCursorPosition).toInt();
|
||||
text = query->value(Qt::ImSurroundingText).toString().left(cursorPos);
|
||||
}
|
||||
}
|
||||
|
||||
// Controls do not report preedit text, so we have to add it
|
||||
if (!m_composingText.isEmpty()) {
|
||||
const int cursorPosInsidePreedit = m_composingCursor - m_composingTextStart;
|
||||
text += m_composingText.leftRef(cursorPosInsidePreedit);
|
||||
}
|
||||
|
||||
if (text.length() > length)
|
||||
text = text.right(length);
|
||||
return text;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1231,6 +1248,8 @@ jboolean QAndroidInputContext::setComposingRegion(jint start, jint end)
|
||||
if (query.isNull())
|
||||
return JNI_FALSE;
|
||||
|
||||
if (start == end)
|
||||
return JNI_TRUE;
|
||||
if (start > end)
|
||||
qSwap(start, end);
|
||||
|
||||
|
@ -221,7 +221,7 @@ EGLNativeWindowType QEglFSOpenWFDIntegration::createNativeWindow(QPlatformWindow
|
||||
|
||||
QSurfaceFormat QEglFSOpenWFDIntegration::surfaceFormatFor(const QSurfaceFormat &inputFormat) const
|
||||
{
|
||||
QSurfaceFormat format;
|
||||
QSurfaceFormat format = inputFormat;
|
||||
format.setRedBufferSize(8);
|
||||
format.setGreenBufferSize(8);
|
||||
format.setBlueBufferSize(8);
|
||||
|
@ -1488,6 +1488,10 @@ void QWindowsContext::handleExitSizeMove(QWindow *window)
|
||||
keyboardModifiers);
|
||||
}
|
||||
}
|
||||
if (d->m_systemInfo & QWindowsContext::SI_SupportsPointer)
|
||||
d->m_pointerHandler.clearEvents();
|
||||
else
|
||||
d->m_mouseHandler.clearEvents();
|
||||
}
|
||||
|
||||
bool QWindowsContext::asyncExpose() const
|
||||
|
@ -157,6 +157,12 @@ QTouchDevice *QWindowsMouseHandler::ensureTouchDevice()
|
||||
return m_touchDevice;
|
||||
}
|
||||
|
||||
void QWindowsMouseHandler::clearEvents()
|
||||
{
|
||||
m_lastEventType = QEvent::None;
|
||||
m_lastEventButton = Qt::NoButton;
|
||||
}
|
||||
|
||||
Qt::MouseButtons QWindowsMouseHandler::queryMouseButtons()
|
||||
{
|
||||
Qt::MouseButtons result = nullptr;
|
||||
@ -287,8 +293,6 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
|
||||
|
||||
Qt::MouseEventSource source = Qt::MouseEventNotSynthesized;
|
||||
|
||||
const MouseEvent mouseEvent = eventFromMsg(msg);
|
||||
|
||||
// Check for events synthesized from touch. Lower byte is touch index, 0 means pen.
|
||||
static const bool passSynthesizedMouseEvents =
|
||||
!(QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch);
|
||||
@ -305,13 +309,40 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
|
||||
}
|
||||
}
|
||||
|
||||
const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
|
||||
const MouseEvent mouseEvent = eventFromMsg(msg);
|
||||
Qt::MouseButtons buttons;
|
||||
|
||||
if (mouseEvent.type >= QEvent::NonClientAreaMouseMove && mouseEvent.type <= QEvent::NonClientAreaMouseButtonDblClick)
|
||||
buttons = queryMouseButtons();
|
||||
else
|
||||
buttons = keyStateToMouseButtons(msg.wParam);
|
||||
|
||||
// When the left/right mouse buttons are pressed over the window title bar
|
||||
// WM_NCLBUTTONDOWN/WM_NCRBUTTONDOWN messages are received. But no UP
|
||||
// messages are received on release, only WM_NCMOUSEMOVE/WM_MOUSEMOVE.
|
||||
// We detect it and generate the missing release events here. (QTBUG-75678)
|
||||
// The last event vars are cleared on QWindowsContext::handleExitSizeMove()
|
||||
// to avoid generating duplicated release events.
|
||||
if (m_lastEventType == QEvent::NonClientAreaMouseButtonPress
|
||||
&& (mouseEvent.type == QEvent::NonClientAreaMouseMove || mouseEvent.type == QEvent::MouseMove)
|
||||
&& (m_lastEventButton & buttons) == 0) {
|
||||
if (mouseEvent.type == QEvent::NonClientAreaMouseMove) {
|
||||
QWindowSystemInterface::handleFrameStrutMouseEvent(window, clientPosition, globalPosition, buttons, m_lastEventButton,
|
||||
QEvent::NonClientAreaMouseButtonRelease, keyModifiers, source);
|
||||
} else {
|
||||
QWindowSystemInterface::handleMouseEvent(window, clientPosition, globalPosition, buttons, m_lastEventButton,
|
||||
QEvent::MouseButtonRelease, keyModifiers, source);
|
||||
}
|
||||
}
|
||||
m_lastEventType = mouseEvent.type;
|
||||
m_lastEventButton = mouseEvent.button;
|
||||
|
||||
if (mouseEvent.type >= QEvent::NonClientAreaMouseMove && mouseEvent.type <= QEvent::NonClientAreaMouseButtonDblClick) {
|
||||
const Qt::MouseButtons buttons = QWindowsMouseHandler::queryMouseButtons();
|
||||
QWindowSystemInterface::handleFrameStrutMouseEvent(window, clientPosition,
|
||||
globalPosition, buttons,
|
||||
mouseEvent.button, mouseEvent.type,
|
||||
QWindowsKeyMapper::queryKeyboardModifiers(),
|
||||
source);
|
||||
keyModifiers, source);
|
||||
return false; // Allow further event processing (dragging of windows).
|
||||
}
|
||||
|
||||
@ -334,7 +365,6 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
|
||||
}
|
||||
|
||||
QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle());
|
||||
const Qt::MouseButtons buttons = keyStateToMouseButtons(int(msg.wParam));
|
||||
|
||||
// If the window was recently resized via mouse doubleclick on the frame or title bar,
|
||||
// we don't get WM_LBUTTONDOWN or WM_LBUTTONDBLCLK for the second click,
|
||||
@ -461,8 +491,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
|
||||
if (!discardEvent && mouseEvent.type != QEvent::None) {
|
||||
QWindowSystemInterface::handleMouseEvent(window, winEventPosition, globalPosition, buttons,
|
||||
mouseEvent.button, mouseEvent.type,
|
||||
QWindowsKeyMapper::queryKeyboardModifiers(),
|
||||
source);
|
||||
keyModifiers, source);
|
||||
}
|
||||
m_previousCaptureWindow = hasCapture ? window : nullptr;
|
||||
// QTBUG-48117, force synchronous handling for the extra buttons so that WM_APPCOMMAND
|
||||
|
@ -45,6 +45,7 @@
|
||||
|
||||
#include <QtCore/qpointer.h>
|
||||
#include <QtCore/qhash.h>
|
||||
#include <QtGui/qevent.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -72,13 +73,14 @@ public:
|
||||
bool translateScrollEvent(QWindow *window, HWND hwnd,
|
||||
MSG msg, LRESULT *result);
|
||||
|
||||
static inline Qt::MouseButtons keyStateToMouseButtons(int);
|
||||
static inline Qt::MouseButtons keyStateToMouseButtons(WPARAM);
|
||||
static inline Qt::KeyboardModifiers keyStateToModifiers(int);
|
||||
static inline int mouseButtonsToKeyState(Qt::MouseButtons);
|
||||
|
||||
static Qt::MouseButtons queryMouseButtons();
|
||||
QWindow *windowUnderMouse() const { return m_windowUnderMouse.data(); }
|
||||
void clearWindowUnderMouse() { m_windowUnderMouse = 0; }
|
||||
void clearEvents();
|
||||
|
||||
private:
|
||||
inline bool translateMouseWheelEvent(QWindow *window, HWND hwnd,
|
||||
@ -91,9 +93,11 @@ private:
|
||||
QTouchDevice *m_touchDevice = nullptr;
|
||||
bool m_leftButtonDown = false;
|
||||
QWindow *m_previousCaptureWindow = nullptr;
|
||||
QEvent::Type m_lastEventType = QEvent::None;
|
||||
Qt::MouseButton m_lastEventButton = Qt::NoButton;
|
||||
};
|
||||
|
||||
Qt::MouseButtons QWindowsMouseHandler::keyStateToMouseButtons(int wParam)
|
||||
Qt::MouseButtons QWindowsMouseHandler::keyStateToMouseButtons(WPARAM wParam)
|
||||
{
|
||||
Qt::MouseButtons mb(Qt::NoButton);
|
||||
if (wParam & MK_LBUTTON)
|
||||
|
@ -336,6 +336,12 @@ QTouchDevice *QWindowsPointerHandler::ensureTouchDevice()
|
||||
return m_touchDevice;
|
||||
}
|
||||
|
||||
void QWindowsPointerHandler::clearEvents()
|
||||
{
|
||||
m_lastEventType = QEvent::None;
|
||||
m_lastEventButton = Qt::NoButton;
|
||||
}
|
||||
|
||||
void QWindowsPointerHandler::handleCaptureRelease(QWindow *window,
|
||||
QWindow *currentWindowUnderPointer,
|
||||
HWND hwnd,
|
||||
@ -726,10 +732,35 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
|
||||
}
|
||||
|
||||
const MouseEvent mouseEvent = eventFromMsg(msg);
|
||||
Qt::MouseButtons mouseButtons;
|
||||
|
||||
if (mouseEvent.type >= QEvent::NonClientAreaMouseMove && mouseEvent.type <= QEvent::NonClientAreaMouseButtonDblClick)
|
||||
mouseButtons = queryMouseButtons();
|
||||
else
|
||||
mouseButtons = mouseButtonsFromKeyState(msg.wParam);
|
||||
|
||||
// When the left/right mouse buttons are pressed over the window title bar
|
||||
// WM_NCLBUTTONDOWN/WM_NCRBUTTONDOWN messages are received. But no UP
|
||||
// messages are received on release, only WM_NCMOUSEMOVE/WM_MOUSEMOVE.
|
||||
// We detect it and generate the missing release events here. (QTBUG-75678)
|
||||
// The last event vars are cleared on QWindowsContext::handleExitSizeMove()
|
||||
// to avoid generating duplicated release events.
|
||||
if (m_lastEventType == QEvent::NonClientAreaMouseButtonPress
|
||||
&& (mouseEvent.type == QEvent::NonClientAreaMouseMove || mouseEvent.type == QEvent::MouseMove)
|
||||
&& (m_lastEventButton & mouseButtons) == 0) {
|
||||
if (mouseEvent.type == QEvent::NonClientAreaMouseMove) {
|
||||
QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, mouseButtons, m_lastEventButton,
|
||||
QEvent::NonClientAreaMouseButtonRelease, keyModifiers, source);
|
||||
} else {
|
||||
QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons, m_lastEventButton,
|
||||
QEvent::MouseButtonRelease, keyModifiers, source);
|
||||
}
|
||||
}
|
||||
m_lastEventType = mouseEvent.type;
|
||||
m_lastEventButton = mouseEvent.button;
|
||||
|
||||
if (mouseEvent.type >= QEvent::NonClientAreaMouseMove && mouseEvent.type <= QEvent::NonClientAreaMouseButtonDblClick) {
|
||||
const Qt::MouseButtons nonclientButtons = queryMouseButtons();
|
||||
QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, nonclientButtons,
|
||||
QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, mouseButtons,
|
||||
mouseEvent.button, mouseEvent.type, keyModifiers, source);
|
||||
return false; // Allow further event processing
|
||||
}
|
||||
@ -745,8 +776,6 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
|
||||
return true;
|
||||
}
|
||||
|
||||
const Qt::MouseButtons mouseButtons = mouseButtonsFromKeyState(msg.wParam);
|
||||
|
||||
handleCaptureRelease(window, currentWindowUnderPointer, hwnd, mouseEvent.type, mouseButtons);
|
||||
handleEnterLeave(window, currentWindowUnderPointer, globalPos);
|
||||
|
||||
|
@ -46,7 +46,7 @@
|
||||
#include <QtCore/qpointer.h>
|
||||
#include <QtCore/qscopedpointer.h>
|
||||
#include <QtCore/qhash.h>
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
#include <QtGui/qevent.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -64,6 +64,7 @@ public:
|
||||
QTouchDevice *ensureTouchDevice();
|
||||
QWindow *windowUnderMouse() const { return m_windowUnderPointer.data(); }
|
||||
void clearWindowUnderMouse() { m_windowUnderPointer = nullptr; }
|
||||
void clearEvents();
|
||||
|
||||
private:
|
||||
bool translateTouchEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vTouchInfo, unsigned int count);
|
||||
@ -79,6 +80,8 @@ private:
|
||||
QPointer<QWindow> m_currentWindow;
|
||||
QWindow *m_previousCaptureWindow = nullptr;
|
||||
bool m_needsEnterOnPointerUpdate = false;
|
||||
QEvent::Type m_lastEventType = QEvent::None;
|
||||
Qt::MouseButton m_lastEventButton = Qt::NoButton;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include "qwindowsuiatableitemprovider.h"
|
||||
#include "qwindowsuiagridprovider.h"
|
||||
#include "qwindowsuiagriditemprovider.h"
|
||||
#include "qwindowsuiawindowprovider.h"
|
||||
#include "qwindowscombase.h"
|
||||
#include "qwindowscontext.h"
|
||||
#include "qwindowsuiautils.h"
|
||||
@ -263,6 +264,11 @@ HRESULT QWindowsUiaMainProvider::GetPatternProvider(PATTERNID idPattern, IUnknow
|
||||
return UIA_E_ELEMENTNOTAVAILABLE;
|
||||
|
||||
switch (idPattern) {
|
||||
case UIA_WindowPatternId:
|
||||
if (accessible->parent() && (accessible->parent()->role() == QAccessible::Application)) {
|
||||
*pRetVal = new QWindowsUiaWindowProvider(id());
|
||||
}
|
||||
break;
|
||||
case UIA_TextPatternId:
|
||||
case UIA_TextPattern2Id:
|
||||
// All text controls.
|
||||
@ -352,8 +358,7 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR
|
||||
if (!accessible)
|
||||
return UIA_E_ELEMENTNOTAVAILABLE;
|
||||
|
||||
bool clientTopLevel = (accessible->role() == QAccessible::Client)
|
||||
&& accessible->parent() && (accessible->parent()->role() == QAccessible::Application);
|
||||
bool topLevelWindow = accessible->parent() && (accessible->parent()->role() == QAccessible::Application);
|
||||
|
||||
switch (idProp) {
|
||||
case UIA_ProcessIdPropertyId:
|
||||
@ -379,7 +384,7 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR
|
||||
setVariantString(QStringLiteral("Qt"), pRetVal);
|
||||
break;
|
||||
case UIA_ControlTypePropertyId:
|
||||
if (clientTopLevel) {
|
||||
if (topLevelWindow) {
|
||||
// Reports a top-level widget as a window, instead of "custom".
|
||||
setVariantI4(UIA_WindowControlTypeId, pRetVal);
|
||||
} else {
|
||||
@ -391,10 +396,20 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR
|
||||
setVariantString(accessible->text(QAccessible::Help), pRetVal);
|
||||
break;
|
||||
case UIA_HasKeyboardFocusPropertyId:
|
||||
setVariantBool(accessible->state().focused, pRetVal);
|
||||
if (topLevelWindow) {
|
||||
// Windows set the active state to true when they are focused
|
||||
setVariantBool(accessible->state().active, pRetVal);
|
||||
} else {
|
||||
setVariantBool(accessible->state().focused, pRetVal);
|
||||
}
|
||||
break;
|
||||
case UIA_IsKeyboardFocusablePropertyId:
|
||||
setVariantBool(accessible->state().focusable, pRetVal);
|
||||
if (topLevelWindow) {
|
||||
// Windows should always be focusable
|
||||
setVariantBool(true, pRetVal);
|
||||
} else {
|
||||
setVariantBool(accessible->state().focusable, pRetVal);
|
||||
}
|
||||
break;
|
||||
case UIA_IsOffscreenPropertyId:
|
||||
setVariantBool(accessible->state().offscreen, pRetVal);
|
||||
@ -424,7 +439,7 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR
|
||||
break;
|
||||
case UIA_NamePropertyId: {
|
||||
QString name = accessible->text(QAccessible::Name);
|
||||
if (name.isEmpty() && clientTopLevel)
|
||||
if (name.isEmpty() && topLevelWindow)
|
||||
name = QCoreApplication::applicationName();
|
||||
setVariantString(name, pRetVal);
|
||||
break;
|
||||
|
@ -0,0 +1,168 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 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 <QtGui/qtguiglobal.h>
|
||||
#if QT_CONFIG(accessibility)
|
||||
|
||||
#include "qwindowsuiawindowprovider.h"
|
||||
#include "qwindowsuiautils.h"
|
||||
#include "qwindowscontext.h"
|
||||
|
||||
#include <QtGui/qaccessible.h>
|
||||
#include <QtGui/private/qwindow_p.h>
|
||||
#include <QtCore/qloggingcategory.h>
|
||||
#include <QtCore/qstring.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QWindowsUiAutomation;
|
||||
|
||||
|
||||
QWindowsUiaWindowProvider::QWindowsUiaWindowProvider(QAccessible::Id id) :
|
||||
QWindowsUiaBaseProvider(id)
|
||||
{
|
||||
}
|
||||
|
||||
QWindowsUiaWindowProvider::~QWindowsUiaWindowProvider()
|
||||
{
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::SetVisualState(WindowVisualState state) {
|
||||
qCDebug(lcQpaUiAutomation) << __FUNCTION__;
|
||||
QAccessibleInterface *accessible = accessibleInterface();
|
||||
if (!accessible || !accessible->window())
|
||||
return UIA_E_ELEMENTNOTAVAILABLE;
|
||||
auto window = accessible->window();
|
||||
switch (state) {
|
||||
case WindowVisualState_Normal:
|
||||
window->showNormal();
|
||||
break;
|
||||
case WindowVisualState_Maximized:
|
||||
window->showMaximized();
|
||||
break;
|
||||
case WindowVisualState_Minimized:
|
||||
window->showMinimized();
|
||||
break;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::Close() {
|
||||
qCDebug(lcQpaUiAutomation) << __FUNCTION__;
|
||||
QAccessibleInterface *accessible = accessibleInterface();
|
||||
if (!accessible || !accessible->window())
|
||||
return UIA_E_ELEMENTNOTAVAILABLE;
|
||||
accessible->window()->close();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::WaitForInputIdle(int milliseconds, __RPC__out BOOL *pRetVal) {
|
||||
Q_UNUSED(milliseconds);
|
||||
Q_UNUSED(pRetVal);
|
||||
return UIA_E_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::get_CanMaximize(__RPC__out BOOL *pRetVal) {
|
||||
qCDebug(lcQpaUiAutomation) << __FUNCTION__;
|
||||
QAccessibleInterface *accessible = accessibleInterface();
|
||||
if (!accessible || !accessible->window())
|
||||
return UIA_E_ELEMENTNOTAVAILABLE;
|
||||
|
||||
auto window = accessible->window();
|
||||
auto flags = window->flags();
|
||||
|
||||
*pRetVal = (!(flags & Qt::MSWindowsFixedSizeDialogHint)
|
||||
&& (flags & Qt::WindowMaximizeButtonHint)
|
||||
&& ((flags & Qt::CustomizeWindowHint)
|
||||
|| window->maximumSize() == QSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX)));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::get_CanMinimize(__RPC__out BOOL *pRetVal) {
|
||||
qCDebug(lcQpaUiAutomation) << __FUNCTION__;
|
||||
QAccessibleInterface *accessible = accessibleInterface();
|
||||
if (!accessible || !accessible->window())
|
||||
return UIA_E_ELEMENTNOTAVAILABLE;
|
||||
*pRetVal = accessible->window()->flags() & Qt::WindowMinimizeButtonHint;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::get_IsModal(__RPC__out BOOL *pRetVal) {
|
||||
qCDebug(lcQpaUiAutomation) << __FUNCTION__;
|
||||
QAccessibleInterface *accessible = accessibleInterface();
|
||||
if (!accessible || !accessible->window())
|
||||
return UIA_E_ELEMENTNOTAVAILABLE;
|
||||
*pRetVal = accessible->window()->isModal();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::get_WindowVisualState(__RPC__out enum WindowVisualState *pRetVal) {
|
||||
qCDebug(lcQpaUiAutomation) << __FUNCTION__;
|
||||
QAccessibleInterface *accessible = accessibleInterface();
|
||||
if (!accessible || !accessible->window())
|
||||
return UIA_E_ELEMENTNOTAVAILABLE;
|
||||
auto visibility = accessible->window()->visibility();
|
||||
switch (visibility) {
|
||||
case QWindow::FullScreen:
|
||||
case QWindow::Maximized:
|
||||
*pRetVal = WindowVisualState_Maximized;
|
||||
break;
|
||||
case QWindow::Minimized:
|
||||
*pRetVal = WindowVisualState_Minimized;
|
||||
break;
|
||||
default:
|
||||
*pRetVal = WindowVisualState_Normal;
|
||||
break;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::get_WindowInteractionState(__RPC__out enum WindowInteractionState *pRetVal) {
|
||||
Q_UNUSED(pRetVal);
|
||||
return UIA_E_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::get_IsTopmost(__RPC__out BOOL *pRetVal) {
|
||||
Q_UNUSED(pRetVal);
|
||||
return UIA_E_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_CONFIG(accessibility)
|
@ -0,0 +1,73 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 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 QWINDOWSUIAWINDOWPROVIDER_H
|
||||
#define QWINDOWSUIAWINDOWPROVIDER_H
|
||||
|
||||
#include <QtGui/qtguiglobal.h>
|
||||
#if QT_CONFIG(accessibility)
|
||||
|
||||
#include "qwindowsuiabaseprovider.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QWindowsUiaWindowProvider : public QWindowsUiaBaseProvider,
|
||||
public QWindowsComBase<IWindowProvider>
|
||||
{
|
||||
Q_DISABLE_COPY(QWindowsUiaWindowProvider)
|
||||
public:
|
||||
explicit QWindowsUiaWindowProvider(QAccessible::Id id);
|
||||
~QWindowsUiaWindowProvider() override;
|
||||
|
||||
HRESULT STDMETHODCALLTYPE SetVisualState(WindowVisualState state) override;
|
||||
HRESULT STDMETHODCALLTYPE Close( void) override;
|
||||
HRESULT STDMETHODCALLTYPE WaitForInputIdle(int milliseconds, __RPC__out BOOL *pRetVal) override;
|
||||
HRESULT STDMETHODCALLTYPE get_CanMaximize(__RPC__out BOOL *pRetVal) override;
|
||||
HRESULT STDMETHODCALLTYPE get_CanMinimize(__RPC__out BOOL *pRetVal) override;
|
||||
HRESULT STDMETHODCALLTYPE get_IsModal(__RPC__out BOOL *pRetVal) override;
|
||||
HRESULT STDMETHODCALLTYPE get_WindowVisualState(__RPC__out WindowVisualState *pRetVal) override;
|
||||
HRESULT STDMETHODCALLTYPE get_WindowInteractionState(__RPC__out WindowInteractionState *pRetVal) override;
|
||||
HRESULT STDMETHODCALLTYPE get_IsTopmost(__RPC__out BOOL *pRetVal) override;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_CONFIG(accessibility)
|
||||
|
||||
#endif // QWINDOWSUIAWINDOWPROVIDER_H
|
@ -18,6 +18,7 @@ SOURCES += \
|
||||
$$PWD/qwindowsuiatableitemprovider.cpp \
|
||||
$$PWD/qwindowsuiagridprovider.cpp \
|
||||
$$PWD/qwindowsuiagriditemprovider.cpp \
|
||||
$$PWD/qwindowsuiawindowprovider.cpp \
|
||||
$$PWD/qwindowsuiautils.cpp
|
||||
|
||||
HEADERS += \
|
||||
@ -37,6 +38,7 @@ HEADERS += \
|
||||
$$PWD/qwindowsuiatableitemprovider.h \
|
||||
$$PWD/qwindowsuiagridprovider.h \
|
||||
$$PWD/qwindowsuiagriditemprovider.h \
|
||||
$$PWD/qwindowsuiawindowprovider.h \
|
||||
$$PWD/qwindowsuiautils.h
|
||||
|
||||
mingw: LIBS *= -luuid
|
||||
|
@ -202,7 +202,7 @@ void QXcbDrag::startDrag()
|
||||
if (connection()->mouseGrabber() == nullptr)
|
||||
shapedPixmapWindow()->setMouseGrabEnabled(true);
|
||||
|
||||
auto nativePixelPos = QHighDpi::toNativePixels(QCursor::pos(), initiatorWindow);
|
||||
auto nativePixelPos = QHighDpi::toNativePixels(QCursor::pos(), initiatorWindow.data());
|
||||
move(nativePixelPos, QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
|
||||
}
|
||||
|
||||
|
@ -1859,6 +1859,9 @@ void QColorDialogPrivate::_q_addCustom()
|
||||
|
||||
void QColorDialogPrivate::retranslateStrings()
|
||||
{
|
||||
if (nativeDialogInUse)
|
||||
return;
|
||||
|
||||
if (!smallDisplay) {
|
||||
lblBasicColors->setText(QColorDialog::tr("&Basic colors"));
|
||||
lblCustomColors->setText(QColorDialog::tr("&Custom colors"));
|
||||
|
5
src/widgets/doc/snippets/cmake-macros/examples.cmake
Normal file
5
src/widgets/doc/snippets/cmake-macros/examples.cmake
Normal file
@ -0,0 +1,5 @@
|
||||
#! [qt5_wrap_ui]
|
||||
set(SOURCES mainwindow.cpp main.cpp)
|
||||
qt5_wrap_ui(SOURCES mainwindow.ui)
|
||||
add_executable(myapp ${SOURCES})
|
||||
#! [qt5_wrap_ui]
|
60
src/widgets/doc/src/cmake-macros.qdoc
Normal file
60
src/widgets/doc/src/cmake-macros.qdoc
Normal file
@ -0,0 +1,60 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:FDL$
|
||||
** 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 Free Documentation License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Free
|
||||
** Documentation License version 1.3 as published by the Free Software
|
||||
** Foundation and appearing in the file included in the packaging of
|
||||
** this file. Please review the following information to ensure
|
||||
** the GNU Free Documentation License version 1.3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\page qtwidgets-cmake-qt5-wrap-ui.html
|
||||
\ingroup cmake-macros-qtwidgets
|
||||
|
||||
\title qt5_wrap_ui
|
||||
|
||||
\brief Creates sources for \c{.ui} files.
|
||||
|
||||
\section1 Synopsis
|
||||
|
||||
\badcode
|
||||
qt5_wrap_ui(<VAR> ui_file1 [ui_file2 ...]
|
||||
[OPTIONS ...])
|
||||
\endcode
|
||||
|
||||
\section1 Description
|
||||
|
||||
Creates rules for calling \l{uic}{User Interface Compiler (uic)} on the given
|
||||
\c{.ui} files. For each input file, an header file is generated in the build
|
||||
directory. The paths of the generated header files are added to\c{<VAR>}.
|
||||
|
||||
\note This is a low-level macro. See the \l{CMake AUTOUIC Documentation} for a
|
||||
more convenient way to process \c{.ui} files with \c{uic}.
|
||||
|
||||
\section1 Options
|
||||
|
||||
You can set additional \c{OPTIONS} that should be added to the \c{uic} calls.
|
||||
You can find possible options in the \l{uic}{uic documentation}.
|
||||
|
||||
\section1 Examples
|
||||
|
||||
\snippet cmake-macros/examples.cmake qt5_wrap_ui
|
||||
*/
|
@ -9795,9 +9795,9 @@ QRectF QGraphicsPixmapItem::boundingRect() const
|
||||
return QRectF();
|
||||
if (d->flags & ItemIsSelectable) {
|
||||
qreal pw = 1.0;
|
||||
return QRectF(d->offset, d->pixmap.size() / d->pixmap.devicePixelRatio()).adjusted(-pw/2, -pw/2, pw/2, pw/2);
|
||||
return QRectF(d->offset, QSizeF(d->pixmap.size()) / d->pixmap.devicePixelRatio()).adjusted(-pw/2, -pw/2, pw/2, pw/2);
|
||||
} else {
|
||||
return QRectF(d->offset, d->pixmap.size() / d->pixmap.devicePixelRatio());
|
||||
return QRectF(d->offset, QSizeF(d->pixmap.size()) / d->pixmap.devicePixelRatio());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2583,14 +2583,15 @@ void QWidgetPrivate::createWinId()
|
||||
/*!
|
||||
\internal
|
||||
Ensures that the widget is set on the screen point is on. This is handy getting a correct
|
||||
size hint before a resize in e.g QMenu and QToolTip
|
||||
size hint before a resize in e.g QMenu and QToolTip.
|
||||
Returns if the screen was changed.
|
||||
*/
|
||||
|
||||
void QWidgetPrivate::setScreenForPoint(const QPoint &pos)
|
||||
bool QWidgetPrivate::setScreenForPoint(const QPoint &pos)
|
||||
{
|
||||
Q_Q(QWidget);
|
||||
if (!q->isWindow())
|
||||
return;
|
||||
return false;
|
||||
// Find the screen for pos and make the widget undertand it is on that screen.
|
||||
const QScreen *currentScreen = windowHandle() ? windowHandle()->screen() : nullptr;
|
||||
QScreen *actualScreen = QGuiApplication::screenAt(pos);
|
||||
@ -2599,7 +2600,9 @@ void QWidgetPrivate::setScreenForPoint(const QPoint &pos)
|
||||
createWinId();
|
||||
if (windowHandle())
|
||||
windowHandle()->setScreen(actualScreen);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -355,7 +355,7 @@ public:
|
||||
void createRecursively();
|
||||
void createWinId();
|
||||
|
||||
void setScreenForPoint(const QPoint &pos);
|
||||
bool setScreenForPoint(const QPoint &pos);
|
||||
|
||||
void createTLExtra();
|
||||
void createExtra();
|
||||
|
@ -976,18 +976,48 @@ void QCompleterPrivate::showPopup(const QRect& rect)
|
||||
popup->show();
|
||||
}
|
||||
|
||||
#if QT_CONFIG(filesystemmodel)
|
||||
static bool isRoot(const QFileSystemModel *model, const QString &path)
|
||||
{
|
||||
const auto index = model->index(path);
|
||||
return index.isValid() && model->fileInfo(index).isRoot();
|
||||
}
|
||||
|
||||
static bool completeOnLoaded(const QFileSystemModel *model,
|
||||
const QString &nativePrefix,
|
||||
const QString &path,
|
||||
Qt::CaseSensitivity caseSensitivity)
|
||||
{
|
||||
const auto pathSize = path.size();
|
||||
const auto prefixSize = nativePrefix.size();
|
||||
if (prefixSize < pathSize)
|
||||
return false;
|
||||
const QString prefix = QDir::fromNativeSeparators(nativePrefix);
|
||||
if (prefixSize == pathSize)
|
||||
return path.compare(prefix, caseSensitivity) == 0 && isRoot(model, path);
|
||||
// The user is typing something within that directory and is not in a subdirectory yet.
|
||||
const auto separator = QLatin1Char('/');
|
||||
return prefix.startsWith(path, caseSensitivity) && prefix.at(pathSize) == separator
|
||||
&& !prefix.rightRef(prefixSize - pathSize - 1).contains(separator);
|
||||
}
|
||||
|
||||
void QCompleterPrivate::_q_fileSystemModelDirectoryLoaded(const QString &path)
|
||||
{
|
||||
Q_Q(QCompleter);
|
||||
// Slot called when QFileSystemModel has finished loading.
|
||||
// If we hide the popup because there was no match because the model was not loaded yet,
|
||||
// we re-start the completion when we get the results
|
||||
if (hiddenBecauseNoMatch
|
||||
&& prefix.startsWith(path) && prefix != (path + QLatin1Char('/'))
|
||||
&& widget) {
|
||||
q->complete();
|
||||
// we re-start the completion when we get the results (unless triggered by
|
||||
// something else, see QTBUG-14292).
|
||||
if (hiddenBecauseNoMatch && widget) {
|
||||
if (auto model = qobject_cast<const QFileSystemModel *>(proxy->sourceModel())) {
|
||||
if (completeOnLoaded(model, prefix, path, cs))
|
||||
q->complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
#else // QT_CONFIG(filesystemmodel)
|
||||
void QCompleterPrivate::_q_fileSystemModelDirectoryLoaded(const QString &) {}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
Constructs a completer object with the given \a parent.
|
||||
|
@ -73,6 +73,7 @@
|
||||
#endif
|
||||
#include "qpushbutton.h"
|
||||
#include "qtooltip.h"
|
||||
#include <qwindow.h>
|
||||
#include <private/qpushbutton_p.h>
|
||||
#include <private/qaction_p.h>
|
||||
#include <private/qguiapplication_p.h>
|
||||
@ -1485,6 +1486,8 @@ void QMenuPrivate::_q_platformMenuAboutToShow()
|
||||
{
|
||||
Q_Q(QMenu);
|
||||
|
||||
emit q->aboutToShow();
|
||||
|
||||
#ifdef Q_OS_OSX
|
||||
if (platformMenu) {
|
||||
const auto actions = q->actions();
|
||||
@ -1498,8 +1501,6 @@ void QMenuPrivate::_q_platformMenuAboutToShow()
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
emit q->aboutToShow();
|
||||
}
|
||||
|
||||
bool QMenuPrivate::hasMouseMoved(const QPoint &globalPos)
|
||||
@ -2328,8 +2329,10 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
|
||||
d->motions = 0;
|
||||
d->doChildEffects = true;
|
||||
d->updateLayoutDirection();
|
||||
// Ensure that we get correct sizeHints by placing this window on the right screen.
|
||||
d->setScreenForPoint(p);
|
||||
|
||||
// Ensure that we get correct sizeHints by placing this window on the correct screen.
|
||||
if (d->setScreenForPoint(p))
|
||||
d->itemsDirty = true;
|
||||
|
||||
const bool contextMenu = d->isContextMenu();
|
||||
if (d->lastContextMenu != contextMenu) {
|
||||
|
@ -121,7 +121,7 @@ bool QWidgetResizeHandler::eventFilter(QObject *o, QEvent *ee)
|
||||
break;
|
||||
const QRect widgetRect = widget->rect().marginsAdded(QMargins(range, range, range, range));
|
||||
const QPoint cursorPoint = widget->mapFromGlobal(e->globalPos());
|
||||
if (!widgetRect.contains(cursorPoint) || mode == Nowhere)
|
||||
if (!widgetRect.contains(cursorPoint))
|
||||
return false;
|
||||
if (e->button() == Qt::LeftButton) {
|
||||
#if 0 // Used to be included in Qt4 for Q_WS_X11
|
||||
|
@ -317,23 +317,26 @@ private:
|
||||
if (quote)
|
||||
break;
|
||||
commandLine[i] = '\0';
|
||||
if (args.last()[0] != '\0')
|
||||
if (!args.isEmpty() && args.last() && args.last()[0] != '\0')
|
||||
args.append(commandLine.data() + i + 1);
|
||||
// fall through
|
||||
default:
|
||||
if (args.last()[0] == '\0')
|
||||
if (!args.isEmpty() && args.last() && args.last()[0] == '\0')
|
||||
args.last() = commandLine.data() + i;
|
||||
escape = false; // only quotes are escaped
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (args.count() >= 2 && strncmp(args.at(1), "-ServerName:", 12) == 0)
|
||||
if (args.count() >= 2 && args.at(1) && strncmp(args.at(1), "-ServerName:", 12) == 0)
|
||||
args.remove(1);
|
||||
|
||||
bool develMode = false;
|
||||
bool debugWait = false;
|
||||
for (int i = args.count() - 1; i >= 0; --i) {
|
||||
if (!args.at(i))
|
||||
continue;
|
||||
|
||||
const char *arg = args.at(i);
|
||||
if (strcmp(arg, "-qdevel") == 0) {
|
||||
develMode = true;
|
||||
|
@ -30,8 +30,10 @@
|
||||
\title Qt XML
|
||||
\brief The Qt XML module provides C++ implementations of the SAX and DOM standards for XML.
|
||||
|
||||
The module is not actively maintained anymore. Please use
|
||||
the QXmlStreamReader and QXmlStreamWriter classes in Qt Core instead.
|
||||
Note that the module will not receive additional features anymore. For reading or writing XML
|
||||
documents iteratively (SAX), we recommend using Qt Core's QXmlStreamReader and
|
||||
QXmlStreamWriter classes. The classes are both easier to use and more compliant with the
|
||||
XML standard.
|
||||
|
||||
To include the definitions of the module's classes, use the
|
||||
following directive:
|
||||
|
@ -33,8 +33,10 @@
|
||||
|
||||
\brief The Qt XML module provides C++ implementations of the SAX and DOM standards for XML.
|
||||
|
||||
The module is not actively maintained anymore. Please use
|
||||
the \l{QXmlStreamReader} and \l{QXmlStreamWriter} classes in \l{Qt Core} instead.
|
||||
Note that the module will not receive additional features anymore. For reading or writing XML
|
||||
documents iteratively (SAX), we recommend using Qt Core's QXmlStreamReader and
|
||||
QXmlStreamWriter classes. The classes are both easier to use and more compliant with the
|
||||
XML standard.
|
||||
|
||||
To include the definitions of the module's classes, use the
|
||||
following directive:
|
||||
|
@ -17,6 +17,8 @@ android
|
||||
[modalWindowEnterEventOnHide_QTBUG35109]
|
||||
ubuntu-16.04
|
||||
osx ci
|
||||
[spuriousMouseMove]
|
||||
windows ci
|
||||
# QTBUG-69162
|
||||
android
|
||||
[modalDialogClosingOneOfTwoModal]
|
||||
|
@ -45,10 +45,6 @@
|
||||
# include <QtCore/qt_windows.h>
|
||||
#endif
|
||||
|
||||
// For QSignalSpy slot connections.
|
||||
Q_DECLARE_METATYPE(Qt::ScreenOrientation)
|
||||
Q_DECLARE_METATYPE(QWindow::Visibility)
|
||||
|
||||
static bool isPlatformWinRT()
|
||||
{
|
||||
static const bool isWinRT = !QGuiApplication::platformName().compare(QLatin1String("winrt"), Qt::CaseInsensitive);
|
||||
@ -185,7 +181,7 @@ void tst_QWindow::setParent()
|
||||
QVERIFY2(c.children().contains(&d), "Parent should have child in list of children");
|
||||
|
||||
a.create();
|
||||
b.setParent(0);
|
||||
b.setParent(nullptr);
|
||||
QVERIFY2(!b.handle(), "Making window top level shouild not automatically create it");
|
||||
|
||||
QWindow e;
|
||||
@ -228,7 +224,7 @@ void tst_QWindow::setVisible()
|
||||
f.setVisible(true);
|
||||
QVERIFY(!f.handle());
|
||||
QVERIFY(!e.handle());
|
||||
f.setParent(0);
|
||||
f.setParent(nullptr);
|
||||
QVERIFY2(f.handle(), "Making a visible but not created child window top level should create it");
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&f));
|
||||
|
||||
@ -304,7 +300,7 @@ public:
|
||||
m_framePositionsOnMove.clear();
|
||||
}
|
||||
|
||||
bool event(QEvent *event)
|
||||
bool event(QEvent *event) override
|
||||
{
|
||||
m_received[event->type()]++;
|
||||
m_order << event->type();
|
||||
@ -323,6 +319,7 @@ public:
|
||||
|
||||
case QEvent::WindowStateChange:
|
||||
lastReceivedWindowState = windowState();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -363,7 +360,7 @@ private:
|
||||
|
||||
class ColoredWindow : public QRasterWindow {
|
||||
public:
|
||||
explicit ColoredWindow(const QColor &color, QWindow *parent = 0) : QRasterWindow(parent), m_color(color) {}
|
||||
explicit ColoredWindow(const QColor &color, QWindow *parent = nullptr) : QRasterWindow(parent), m_color(color) {}
|
||||
void paintEvent(QPaintEvent *) override
|
||||
{
|
||||
QPainter p(this);
|
||||
@ -381,6 +378,7 @@ void tst_QWindow::eventOrderOnShow()
|
||||
QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize);
|
||||
|
||||
Window window;
|
||||
window.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
window.setGeometry(geometry);
|
||||
window.show();
|
||||
QCoreApplication::processEvents();
|
||||
@ -440,12 +438,12 @@ void tst_QWindow::exposeEventOnShrink_QTBUG54040()
|
||||
|
||||
void tst_QWindow::positioning_data()
|
||||
{
|
||||
QTest::addColumn<int>("windowflags");
|
||||
QTest::addColumn<Qt::WindowFlags>("windowflags");
|
||||
|
||||
QTest::newRow("default") << int(Qt::Window | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint | Qt::WindowFullscreenButtonHint);
|
||||
QTest::newRow("default") << (Qt::Window | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint | Qt::WindowFullscreenButtonHint);
|
||||
|
||||
#ifdef Q_OS_OSX
|
||||
QTest::newRow("fake") << int(Qt::Window | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
|
||||
#ifdef Q_OS_MACOS
|
||||
QTest::newRow("fake") << (Qt::Window | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -500,8 +498,8 @@ void tst_QWindow::positioning()
|
||||
// events, so set the width to suitably large value to avoid those.
|
||||
const QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize);
|
||||
|
||||
QFETCH(int, windowflags);
|
||||
Window window((Qt::WindowFlags)windowflags);
|
||||
QFETCH(Qt::WindowFlags, windowflags);
|
||||
Window window(windowflags);
|
||||
window.setGeometry(QRect(m_availableTopLeft + QPoint(20, 20), m_testWindowSize));
|
||||
window.setFramePosition(m_availableTopLeft + QPoint(40, 40)); // Move window around before show, size must not change.
|
||||
QCOMPARE(window.geometry().size(), m_testWindowSize);
|
||||
@ -628,14 +626,12 @@ void tst_QWindow::childWindowPositioning()
|
||||
|
||||
QFETCH(bool, showInsteadOfCreate);
|
||||
|
||||
QWindow* windows[] = { &topLevelWindowFirst, &childWindowAfter, &childWindowFirst, &topLevelWindowAfter, 0 };
|
||||
for (int i = 0; windows[i]; ++i) {
|
||||
QWindow *window = windows[i];
|
||||
if (showInsteadOfCreate) {
|
||||
QWindow *windows[] = {&topLevelWindowFirst, &childWindowAfter, &childWindowFirst, &topLevelWindowAfter};
|
||||
for (QWindow *window : windows) {
|
||||
if (showInsteadOfCreate)
|
||||
window->showNormal();
|
||||
} else {
|
||||
else
|
||||
window->create();
|
||||
}
|
||||
}
|
||||
|
||||
if (showInsteadOfCreate) {
|
||||
@ -712,7 +708,7 @@ void tst_QWindow::stateChange()
|
||||
// explicitly use non-fullscreen show. show() can be fullscreen on some platforms
|
||||
window.showNormal();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&window));
|
||||
foreach (Qt::WindowState state, stateSequence) {
|
||||
for (Qt::WindowState state : qAsConst(stateSequence)) {
|
||||
window.setWindowState(state);
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
@ -726,15 +722,9 @@ class PlatformWindowFilter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PlatformWindowFilter(QObject *parent = 0)
|
||||
: QObject(parent)
|
||||
, m_window(nullptr)
|
||||
, m_alwaysExisted(true)
|
||||
{}
|
||||
explicit PlatformWindowFilter(Window *window) : m_window(window) {}
|
||||
|
||||
void setWindow(Window *window) { m_window = window; }
|
||||
|
||||
bool eventFilter(QObject *o, QEvent *e)
|
||||
bool eventFilter(QObject *o, QEvent *e) override
|
||||
{
|
||||
// Check that the platform surface events are delivered synchronously.
|
||||
// If they are, the native platform surface should always exist when we
|
||||
@ -749,7 +739,7 @@ public:
|
||||
|
||||
private:
|
||||
Window *m_window;
|
||||
bool m_alwaysExisted;
|
||||
bool m_alwaysExisted = true;
|
||||
};
|
||||
|
||||
void tst_QWindow::platformSurface()
|
||||
@ -757,8 +747,7 @@ void tst_QWindow::platformSurface()
|
||||
QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize);
|
||||
|
||||
Window window;
|
||||
PlatformWindowFilter filter;
|
||||
filter.setWindow(&window);
|
||||
PlatformWindowFilter filter(&window);
|
||||
window.installEventFilter(&filter);
|
||||
|
||||
window.setGeometry(geometry);
|
||||
@ -784,6 +773,7 @@ void tst_QWindow::isExposed()
|
||||
QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize);
|
||||
|
||||
Window window;
|
||||
window.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
window.setGeometry(geometry);
|
||||
QCOMPARE(window.geometry(), geometry);
|
||||
window.show();
|
||||
@ -818,6 +808,7 @@ void tst_QWindow::isActive()
|
||||
QSKIP("QWindow::requestActivate() is not supported.");
|
||||
|
||||
Window window;
|
||||
window.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
// Some platforms enforce minimum widths for windows, which can cause extra resize
|
||||
// events, so set the width to suitably large value to avoid those.
|
||||
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
|
||||
@ -916,13 +907,16 @@ void tst_QWindow::isActive()
|
||||
class InputTestWindow : public ColoredWindow
|
||||
{
|
||||
public:
|
||||
void keyPressEvent(QKeyEvent *event) {
|
||||
void keyPressEvent(QKeyEvent *event) override
|
||||
{
|
||||
keyPressCode = event->key();
|
||||
}
|
||||
void keyReleaseEvent(QKeyEvent *event) {
|
||||
void keyReleaseEvent(QKeyEvent *event) override
|
||||
{
|
||||
keyReleaseCode = event->key();
|
||||
}
|
||||
void mousePressEvent(QMouseEvent *event) {
|
||||
void mousePressEvent(QMouseEvent *event) override
|
||||
{
|
||||
if (ignoreMouse) {
|
||||
event->ignore();
|
||||
} else {
|
||||
@ -935,7 +929,8 @@ public:
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
}
|
||||
void mouseReleaseEvent(QMouseEvent *event) {
|
||||
void mouseReleaseEvent(QMouseEvent *event) override
|
||||
{
|
||||
if (ignoreMouse) {
|
||||
event->ignore();
|
||||
} else {
|
||||
@ -944,7 +939,8 @@ public:
|
||||
mouseReleaseButton = event->button();
|
||||
}
|
||||
}
|
||||
void mouseMoveEvent(QMouseEvent *event) {
|
||||
void mouseMoveEvent(QMouseEvent *event) override
|
||||
{
|
||||
buttonStateInGeneratedMove = event->buttons();
|
||||
if (ignoreMouse) {
|
||||
event->ignore();
|
||||
@ -954,7 +950,8 @@ public:
|
||||
mouseMoveScreenPos = event->screenPos();
|
||||
}
|
||||
}
|
||||
void mouseDoubleClickEvent(QMouseEvent *event) {
|
||||
void mouseDoubleClickEvent(QMouseEvent *event) override
|
||||
{
|
||||
if (ignoreMouse) {
|
||||
event->ignore();
|
||||
} else {
|
||||
@ -962,7 +959,8 @@ public:
|
||||
mouseSequenceSignature += 'd';
|
||||
}
|
||||
}
|
||||
void touchEvent(QTouchEvent *event) {
|
||||
void touchEvent(QTouchEvent *event) override
|
||||
{
|
||||
if (ignoreTouch) {
|
||||
event->ignore();
|
||||
return;
|
||||
@ -987,7 +985,8 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
bool event(QEvent *e) {
|
||||
bool event(QEvent *e) override
|
||||
{
|
||||
switch (e->type()) {
|
||||
case QEvent::Enter:
|
||||
++enterEventCount;
|
||||
@ -998,37 +997,31 @@ public:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QWindow::event(e);
|
||||
return ColoredWindow::event(e);
|
||||
}
|
||||
void resetCounters() {
|
||||
void resetCounters()
|
||||
{
|
||||
mousePressedCount = mouseReleasedCount = mouseMovedCount = mouseDoubleClickedCount = 0;
|
||||
mouseSequenceSignature = QString();
|
||||
mouseSequenceSignature.clear();
|
||||
touchPressedCount = touchReleasedCount = touchMovedCount = 0;
|
||||
enterEventCount = leaveEventCount = 0;
|
||||
}
|
||||
|
||||
explicit InputTestWindow(const QColor &color = Qt::white, QWindow *parent = nullptr)
|
||||
: ColoredWindow(color, parent)
|
||||
{
|
||||
keyPressCode = keyReleaseCode = 0;
|
||||
mousePressButton = mouseReleaseButton = mouseMoveButton = 0;
|
||||
ignoreMouse = ignoreTouch = false;
|
||||
spinLoopWhenPressed = false;
|
||||
resetCounters();
|
||||
}
|
||||
: ColoredWindow(color, parent) {}
|
||||
|
||||
int keyPressCode, keyReleaseCode;
|
||||
int mousePressButton, mouseReleaseButton, mouseMoveButton;
|
||||
int mousePressedCount, mouseReleasedCount, mouseMovedCount, mouseDoubleClickedCount;
|
||||
int keyPressCode = 0, keyReleaseCode = 0;
|
||||
int mousePressButton = 0, mouseReleaseButton = 0, mouseMoveButton = 0;
|
||||
int mousePressedCount = 0, mouseReleasedCount = 0, mouseMovedCount = 0, mouseDoubleClickedCount = 0;
|
||||
QString mouseSequenceSignature;
|
||||
QPointF mousePressScreenPos, mouseMoveScreenPos, mousePressLocalPos;
|
||||
int touchPressedCount, touchReleasedCount, touchMovedCount;
|
||||
QEvent::Type touchEventType;
|
||||
int enterEventCount, leaveEventCount;
|
||||
int touchPressedCount = 0, touchReleasedCount = 0, touchMovedCount = 0;
|
||||
QEvent::Type touchEventType = QEvent::None;
|
||||
int enterEventCount = 0, leaveEventCount = 0;
|
||||
|
||||
bool ignoreMouse, ignoreTouch;
|
||||
bool ignoreMouse = false, ignoreTouch = false;
|
||||
|
||||
bool spinLoopWhenPressed;
|
||||
bool spinLoopWhenPressed = false;
|
||||
Qt::MouseButtons buttonStateInGeneratedMove;
|
||||
};
|
||||
|
||||
@ -1073,15 +1066,15 @@ void tst_QWindow::testInputEvents()
|
||||
window.mousePressButton = window.mouseReleaseButton = 0;
|
||||
const QPointF nonWindowGlobal(window.geometry().topRight() + QPoint(200, 50)); // not inside the window
|
||||
const QPointF deviceNonWindowGlobal = QHighDpi::toNativePixels(nonWindowGlobal, window.screen());
|
||||
QWindowSystemInterface::handleMouseEvent(0, deviceNonWindowGlobal, deviceNonWindowGlobal, Qt::LeftButton);
|
||||
QWindowSystemInterface::handleMouseEvent(0, deviceNonWindowGlobal, deviceNonWindowGlobal, Qt::NoButton);
|
||||
QWindowSystemInterface::handleMouseEvent(nullptr, deviceNonWindowGlobal, deviceNonWindowGlobal, Qt::LeftButton);
|
||||
QWindowSystemInterface::handleMouseEvent(nullptr, deviceNonWindowGlobal, deviceNonWindowGlobal, Qt::NoButton);
|
||||
QCoreApplication::processEvents();
|
||||
QCOMPARE(window.mousePressButton, 0);
|
||||
QCOMPARE(window.mouseReleaseButton, 0);
|
||||
const QPointF windowGlobal = window.mapToGlobal(local.toPoint());
|
||||
const QPointF deviceWindowGlobal = QHighDpi::toNativePixels(windowGlobal, window.screen());
|
||||
QWindowSystemInterface::handleMouseEvent(0, deviceWindowGlobal, deviceWindowGlobal, Qt::LeftButton);
|
||||
QWindowSystemInterface::handleMouseEvent(0, deviceWindowGlobal, deviceWindowGlobal, Qt::NoButton);
|
||||
QWindowSystemInterface::handleMouseEvent(nullptr, deviceWindowGlobal, deviceWindowGlobal, Qt::LeftButton);
|
||||
QWindowSystemInterface::handleMouseEvent(nullptr, deviceWindowGlobal, deviceWindowGlobal, Qt::NoButton);
|
||||
QCoreApplication::processEvents();
|
||||
QCOMPARE(window.mousePressButton, int(Qt::LeftButton));
|
||||
QCOMPARE(window.mouseReleaseButton, int(Qt::LeftButton));
|
||||
@ -1092,6 +1085,7 @@ void tst_QWindow::testInputEvents()
|
||||
void tst_QWindow::touchToMouseTranslation()
|
||||
{
|
||||
InputTestWindow window;
|
||||
window.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
window.ignoreTouch = true;
|
||||
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
|
||||
window.show();
|
||||
@ -1145,7 +1139,7 @@ void tst_QWindow::touchToMouseTranslation()
|
||||
QTRY_COMPARE(window.mousePressButton, 0);
|
||||
QTRY_COMPARE(window.mouseReleaseButton, 0);
|
||||
|
||||
qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, false);
|
||||
QCoreApplication::setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, false);
|
||||
|
||||
window.ignoreTouch = true;
|
||||
points[0].state = Qt::TouchPointPressed;
|
||||
@ -1156,7 +1150,7 @@ void tst_QWindow::touchToMouseTranslation()
|
||||
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true);
|
||||
QCoreApplication::setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true);
|
||||
|
||||
// mouse event synthesizing disabled
|
||||
QTRY_COMPARE(window.mousePressButton, 0);
|
||||
@ -1166,6 +1160,7 @@ void tst_QWindow::touchToMouseTranslation()
|
||||
void tst_QWindow::touchToMouseTranslationForDevices()
|
||||
{
|
||||
InputTestWindow window;
|
||||
window.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
window.ignoreTouch = true;
|
||||
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
|
||||
window.show();
|
||||
@ -1194,9 +1189,10 @@ void tst_QWindow::touchToMouseTranslationForDevices()
|
||||
|
||||
void tst_QWindow::mouseToTouchTranslation()
|
||||
{
|
||||
qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true);
|
||||
QCoreApplication::setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true);
|
||||
|
||||
InputTestWindow window;
|
||||
window.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
window.ignoreMouse = true;
|
||||
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
|
||||
window.show();
|
||||
@ -1206,12 +1202,12 @@ void tst_QWindow::mouseToTouchTranslation()
|
||||
QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::NoButton);
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, false);
|
||||
QCoreApplication::setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, false);
|
||||
|
||||
QTRY_COMPARE(window.touchPressedCount, 1);
|
||||
QTRY_COMPARE(window.touchReleasedCount, 1);
|
||||
|
||||
qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true);
|
||||
QCoreApplication::setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true);
|
||||
|
||||
window.ignoreMouse = false;
|
||||
|
||||
@ -1219,7 +1215,7 @@ void tst_QWindow::mouseToTouchTranslation()
|
||||
QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::NoButton);
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, false);
|
||||
QCoreApplication::setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, false);
|
||||
|
||||
// no new touch events should be generated since the input window handles the mouse events
|
||||
QTRY_COMPARE(window.touchPressedCount, 1);
|
||||
@ -1241,10 +1237,12 @@ void tst_QWindow::mouseToTouchTranslation()
|
||||
void tst_QWindow::mouseToTouchLoop()
|
||||
{
|
||||
// make sure there's no infinite loop when synthesizing both ways
|
||||
qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true);
|
||||
qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true);
|
||||
QCoreApplication::setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true);
|
||||
QCoreApplication::setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true);
|
||||
|
||||
InputTestWindow window;
|
||||
window.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
|
||||
window.ignoreMouse = true;
|
||||
window.ignoreTouch = true;
|
||||
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
|
||||
@ -1255,13 +1253,14 @@ void tst_QWindow::mouseToTouchLoop()
|
||||
QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::NoButton);
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, false);
|
||||
qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true);
|
||||
QCoreApplication::setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, false);
|
||||
QCoreApplication::setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true);
|
||||
}
|
||||
|
||||
void tst_QWindow::touchCancel()
|
||||
{
|
||||
InputTestWindow window;
|
||||
window.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
|
||||
window.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&window));
|
||||
@ -1321,6 +1320,7 @@ void tst_QWindow::touchCancel()
|
||||
void tst_QWindow::touchCancelWithTouchToMouse()
|
||||
{
|
||||
InputTestWindow window;
|
||||
window.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
window.ignoreTouch = true;
|
||||
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
|
||||
window.show();
|
||||
@ -1343,7 +1343,7 @@ void tst_QWindow::touchCancelWithTouchToMouse()
|
||||
|
||||
// Cancel the touch. Should result in a mouse release for windows that have
|
||||
// have an active touch-to-mouse sequence.
|
||||
QWindowSystemInterface::handleTouchCancelEvent(0, touchDevice);
|
||||
QWindowSystemInterface::handleTouchCancelEvent(nullptr, touchDevice);
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
QTRY_COMPARE(window.mouseReleaseButton, int(Qt::LeftButton));
|
||||
@ -1358,7 +1358,7 @@ void tst_QWindow::touchCancelWithTouchToMouse()
|
||||
QTRY_COMPARE(window.mousePressButton, 0);
|
||||
|
||||
// Cancel the touch. It should not result in a mouse release with this window.
|
||||
QWindowSystemInterface::handleTouchCancelEvent(0, touchDevice);
|
||||
QWindowSystemInterface::handleTouchCancelEvent(nullptr, touchDevice);
|
||||
QCoreApplication::processEvents();
|
||||
QTRY_COMPARE(window.mouseReleaseButton, 0);
|
||||
}
|
||||
@ -1369,6 +1369,7 @@ void tst_QWindow::touchInterruptedByPopup()
|
||||
QSKIP("Wayland: This test crashes with xdg-shell unstable v6");
|
||||
|
||||
InputTestWindow window;
|
||||
window.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
|
||||
window.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&window));
|
||||
@ -1489,6 +1490,7 @@ void tst_QWindow::sizes()
|
||||
void tst_QWindow::close()
|
||||
{
|
||||
QWindow a;
|
||||
a.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
QWindow b;
|
||||
QWindow c(&a);
|
||||
|
||||
@ -1506,8 +1508,9 @@ void tst_QWindow::activateAndClose()
|
||||
if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation))
|
||||
QSKIP("QWindow::requestActivate() is not supported.");
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
QWindow window;
|
||||
window.setTitle(QLatin1String(QTest::currentTestFunction()) + QString::number(i));
|
||||
#if defined(Q_OS_QNX)
|
||||
window.setSurfaceType(QSurface::OpenGLSurface);
|
||||
#endif
|
||||
@ -1525,15 +1528,16 @@ void tst_QWindow::activateAndClose()
|
||||
#endif
|
||||
window.requestActivate();
|
||||
QVERIFY(QTest::qWaitForWindowActive(&window));
|
||||
QCOMPARE(qGuiApp->focusWindow(), &window);
|
||||
QCOMPARE(QGuiApplication::focusWindow(), &window);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QWindow::mouseEventSequence()
|
||||
{
|
||||
int doubleClickInterval = qGuiApp->styleHints()->mouseDoubleClickInterval();
|
||||
const auto doubleClickInterval = ulong(QGuiApplication::styleHints()->mouseDoubleClickInterval());
|
||||
|
||||
InputTestWindow window;
|
||||
window.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
|
||||
window.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&window));
|
||||
@ -1655,6 +1659,7 @@ void tst_QWindow::windowModality()
|
||||
void tst_QWindow::inputReentrancy()
|
||||
{
|
||||
InputTestWindow window;
|
||||
window.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
window.spinLoopWhenPressed = true;
|
||||
|
||||
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
|
||||
@ -1700,17 +1705,20 @@ void tst_QWindow::inputReentrancy()
|
||||
class TabletTestWindow : public QWindow
|
||||
{
|
||||
public:
|
||||
TabletTestWindow() : eventType(QEvent::None) { }
|
||||
void tabletEvent(QTabletEvent *ev) {
|
||||
void tabletEvent(QTabletEvent *ev) override
|
||||
{
|
||||
eventType = ev->type();
|
||||
eventGlobal = ev->globalPosF();
|
||||
eventLocal = ev->posF();
|
||||
eventDevice = ev->device();
|
||||
}
|
||||
QEvent::Type eventType;
|
||||
|
||||
QEvent::Type eventType = QEvent::None;
|
||||
QPointF eventGlobal, eventLocal;
|
||||
int eventDevice;
|
||||
bool eventFilter(QObject *obj, QEvent *ev) {
|
||||
int eventDevice = -1;
|
||||
|
||||
bool eventFilter(QObject *obj, QEvent *ev) override
|
||||
{
|
||||
if (ev->type() == QEvent::TabletEnterProximity
|
||||
|| ev->type() == QEvent::TabletLeaveProximity) {
|
||||
eventType = ev->type();
|
||||
@ -1758,6 +1766,7 @@ void tst_QWindow::tabletEvents()
|
||||
void tst_QWindow::windowModality_QTBUG27039()
|
||||
{
|
||||
QWindow parent;
|
||||
parent.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
parent.setGeometry(QRect(m_availableTopLeft + QPoint(10, 10), m_testWindowSize));
|
||||
parent.show();
|
||||
|
||||
@ -1868,6 +1877,7 @@ void tst_QWindow::initialSize()
|
||||
QSize defaultSize(0,0);
|
||||
{
|
||||
Window w;
|
||||
w.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
w.showNormal();
|
||||
QTRY_VERIFY(w.width() > 0);
|
||||
QTRY_VERIFY(w.height() > 0);
|
||||
@ -1875,6 +1885,7 @@ void tst_QWindow::initialSize()
|
||||
}
|
||||
{
|
||||
Window w;
|
||||
w.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
w.setWidth(m_testWindowSize.width());
|
||||
w.showNormal();
|
||||
if (isPlatformWinRT())
|
||||
@ -1884,6 +1895,7 @@ void tst_QWindow::initialSize()
|
||||
}
|
||||
{
|
||||
Window w;
|
||||
w.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
const QSize testSize(m_testWindowSize.width(), 42);
|
||||
w.resize(testSize);
|
||||
w.showNormal();
|
||||
@ -1910,6 +1922,7 @@ void tst_QWindow::modalDialog()
|
||||
QSKIP("Test fails due to QTBUG-61965, and is slow due to QTBUG-61964");
|
||||
|
||||
QWindow normalWindow;
|
||||
normalWindow.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
normalWindow.setFramePosition(m_availableTopLeft + QPoint(80, 80));
|
||||
normalWindow.resize(m_testWindowSize);
|
||||
normalWindow.show();
|
||||
@ -1945,6 +1958,7 @@ void tst_QWindow::modalDialogClosingOneOfTwoModal()
|
||||
QSKIP("QWindow::requestActivate() is not supported.");
|
||||
|
||||
QWindow normalWindow;
|
||||
normalWindow.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
normalWindow.setFramePosition(m_availableTopLeft + QPoint(80, 80));
|
||||
normalWindow.resize(m_testWindowSize);
|
||||
normalWindow.show();
|
||||
@ -1992,6 +2006,7 @@ void tst_QWindow::modalWithChildWindow()
|
||||
QSKIP("QWindow::requestActivate() is not supported.");
|
||||
|
||||
QWindow normalWindow;
|
||||
normalWindow.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
normalWindow.setFramePosition(m_availableTopLeft + QPoint(80, 80));
|
||||
normalWindow.resize(m_testWindowSize);
|
||||
normalWindow.show();
|
||||
@ -2028,6 +2043,7 @@ void tst_QWindow::modalWindowModallity()
|
||||
QSKIP("QWindow::requestActivate() is not supported.");
|
||||
|
||||
QWindow normal_window;
|
||||
normal_window.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
normal_window.setFramePosition(m_availableTopLeft + QPoint(80, 80));
|
||||
normal_window.resize(m_testWindowSize);
|
||||
normal_window.show();
|
||||
@ -2058,6 +2074,7 @@ void tst_QWindow::modalWindowModallity()
|
||||
void tst_QWindow::modalWindowPosition()
|
||||
{
|
||||
QWindow window;
|
||||
window.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
window.setGeometry(QRect(m_availableTopLeft + QPoint(100, 100), m_testWindowSize));
|
||||
// Allow for any potential resizing due to constraints
|
||||
QRect origGeo = window.geometry();
|
||||
@ -2341,6 +2358,7 @@ void tst_QWindow::requestUpdate()
|
||||
QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize);
|
||||
|
||||
Window window;
|
||||
window.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
window.setGeometry(geometry);
|
||||
window.show();
|
||||
QCoreApplication::processEvents();
|
||||
@ -2370,10 +2388,10 @@ void tst_QWindow::flags()
|
||||
class EventWindow : public QWindow
|
||||
{
|
||||
public:
|
||||
EventWindow() : QWindow(), gotBlocked(false) {}
|
||||
bool gotBlocked;
|
||||
bool gotBlocked = false;
|
||||
|
||||
protected:
|
||||
bool event(QEvent *e)
|
||||
bool event(QEvent *e) override
|
||||
{
|
||||
if (e->type() == QEvent::WindowBlocked)
|
||||
gotBlocked = true;
|
||||
@ -2384,6 +2402,7 @@ protected:
|
||||
void tst_QWindow::testBlockingWindowShownAfterModalDialog()
|
||||
{
|
||||
EventWindow normalWindow;
|
||||
normalWindow.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
normalWindow.setFramePosition(m_availableTopLeft + QPoint(80, 80));
|
||||
normalWindow.resize(m_testWindowSize);
|
||||
normalWindow.show();
|
||||
@ -2411,6 +2430,7 @@ void tst_QWindow::testBlockingWindowShownAfterModalDialog()
|
||||
void tst_QWindow::generatedMouseMove()
|
||||
{
|
||||
InputTestWindow w;
|
||||
w.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
w.setGeometry(QRect(m_availableTopLeft + QPoint(100, 100), m_testWindowSize));
|
||||
w.setFlags(w.flags() | Qt::FramelessWindowHint); // ### FIXME: QTBUG-63542
|
||||
w.show();
|
||||
@ -2422,34 +2442,34 @@ void tst_QWindow::generatedMouseMove()
|
||||
QTest::mouseMove(&w, point);
|
||||
QVERIFY(w.mouseMovedCount == 1);
|
||||
// A press event that does not change position should not generate mouse move
|
||||
QTest::mousePress(&w, Qt::LeftButton, 0, point);
|
||||
QTest::mousePress(&w, Qt::RightButton, 0, point);
|
||||
QTest::mousePress(&w, Qt::LeftButton, Qt::KeyboardModifiers(), point);
|
||||
QTest::mousePress(&w, Qt::RightButton, Qt::KeyboardModifiers(), point);
|
||||
|
||||
QVERIFY(w.mouseMovedCount == 1);
|
||||
|
||||
// Verify that a move event is generated for a mouse release event that changes position
|
||||
point += step;
|
||||
QTest::mouseRelease(&w, Qt::LeftButton, 0, point);
|
||||
QTest::mouseRelease(&w, Qt::LeftButton,Qt::KeyboardModifiers(), point);
|
||||
QVERIFY(w.mouseMovedCount == 2);
|
||||
QVERIFY(w.buttonStateInGeneratedMove == (Qt::LeftButton | Qt::RightButton));
|
||||
point += step;
|
||||
QTest::mouseRelease(&w, Qt::RightButton, 0, point);
|
||||
QTest::mouseRelease(&w, Qt::RightButton, Qt::KeyboardModifiers(), point);
|
||||
QVERIFY(w.mouseMovedCount == 3);
|
||||
QVERIFY(w.buttonStateInGeneratedMove == Qt::RightButton);
|
||||
|
||||
// Verify that a move event is generated for a mouse press event that changes position
|
||||
point += step;
|
||||
QTest::mousePress(&w, Qt::LeftButton, 0, point);
|
||||
QTest::mousePress(&w, Qt::LeftButton, Qt::KeyboardModifiers(), point);
|
||||
QVERIFY(w.mouseMovedCount == 4);
|
||||
QVERIFY(w.buttonStateInGeneratedMove == Qt::NoButton);
|
||||
point += step;
|
||||
QTest::mousePress(&w, Qt::RightButton, 0, point);
|
||||
QTest::mousePress(&w, Qt::RightButton, Qt::KeyboardModifiers(), point);
|
||||
QVERIFY(w.mouseMovedCount == 5);
|
||||
QVERIFY(w.buttonStateInGeneratedMove == Qt::LeftButton);
|
||||
|
||||
// A release event that does not change position should not generate mouse move
|
||||
QTest::mouseRelease(&w, Qt::RightButton, 0, point);
|
||||
QTest::mouseRelease(&w, Qt::LeftButton, 0, point);
|
||||
QTest::mouseRelease(&w, Qt::RightButton, Qt::KeyboardModifiers(), point);
|
||||
QTest::mouseRelease(&w, Qt::LeftButton, Qt::KeyboardModifiers(), point);
|
||||
QVERIFY(w.mouseMovedCount == 5);
|
||||
}
|
||||
|
||||
@ -2458,6 +2478,7 @@ void tst_QWindow::keepPendingUpdateRequests()
|
||||
QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize);
|
||||
|
||||
Window window;
|
||||
window.setTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
window.setGeometry(geometry);
|
||||
window.show();
|
||||
QCoreApplication::processEvents();
|
||||
|
@ -32,9 +32,8 @@ base::base(QWidget *parent) :
|
||||
QWidget(parent)
|
||||
{
|
||||
m_timer = new QTimer(this);
|
||||
m_modalStarted = false;
|
||||
m_timer->setSingleShot(false);
|
||||
connect(m_timer, SIGNAL(timeout()), this, SLOT(periodicTimer()));
|
||||
connect(m_timer, &QTimer::timeout, this, &base::periodicTimer);
|
||||
m_timer->start(5000);
|
||||
}
|
||||
|
||||
@ -43,6 +42,7 @@ void base::periodicTimer()
|
||||
if(m_modalStarted)
|
||||
exit(0);
|
||||
m_modalDialog = new QDialog(this);
|
||||
m_modalDialog->setWindowTitle(QLatin1String("modal"));
|
||||
m_modalDialog->setModal(true);
|
||||
m_modalDialog->show();
|
||||
m_modalStarted = true;
|
||||
|
@ -37,12 +37,10 @@ class base : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
QTimer *m_timer;
|
||||
bool m_modalStarted;
|
||||
QDialog *m_modalDialog;
|
||||
bool m_modalStarted = false;
|
||||
QDialog *m_modalDialog = nullptr;
|
||||
public:
|
||||
explicit base(QWidget *parent = 0);
|
||||
|
||||
signals:
|
||||
explicit base(QWidget *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void periodicTimer();
|
||||
|
@ -26,8 +26,6 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtGui>
|
||||
|
||||
#include <QApplication>
|
||||
#include "base.h"
|
||||
|
||||
@ -35,7 +33,6 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
QApplication::setAttribute(Qt::AA_NativeWindows); //QTBUG-15774
|
||||
base *b = new base();
|
||||
Q_UNUSED(b);
|
||||
base b;
|
||||
return app.exec();
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -54,12 +54,25 @@
|
||||
|
||||
using namespace QTestPrivate;
|
||||
|
||||
// Compare a window position that may go through scaling in the platform plugin with fuzz.
|
||||
static inline bool qFuzzyCompareWindowPosition(const QPoint &p1, const QPoint p2, int fuzz)
|
||||
{
|
||||
return (p1 - p2).manhattanLength() <= fuzz;
|
||||
}
|
||||
|
||||
static QString msgPointMismatch(const QPoint &p1, const QPoint p2)
|
||||
{
|
||||
QString result;
|
||||
QDebug(&result) << p1 << "!=" << p2 << ", manhattanLength=" << (p1 - p2).manhattanLength();
|
||||
return result;
|
||||
}
|
||||
|
||||
class tst_QWidget_window : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
tst_QWidget_window(){};
|
||||
tst_QWidget_window();
|
||||
|
||||
public slots:
|
||||
void initTestCase();
|
||||
@ -110,8 +123,20 @@ private slots:
|
||||
void nativeShow();
|
||||
|
||||
void QTBUG_56277_resize_on_showEvent();
|
||||
|
||||
private:
|
||||
QSize m_testWidgetSize;
|
||||
const int m_fuzz;
|
||||
};
|
||||
|
||||
tst_QWidget_window::tst_QWidget_window() :
|
||||
m_fuzz(int(QHighDpiScaling::factor(QGuiApplication::primaryScreen())))
|
||||
{
|
||||
const int screenWidth = QGuiApplication::primaryScreen()->geometry().width();
|
||||
const int width = qMax(200, 100 * ((screenWidth + 500) / 1000));
|
||||
m_testWidgetSize = QSize(width, width);
|
||||
}
|
||||
|
||||
void tst_QWidget_window::initTestCase()
|
||||
{
|
||||
}
|
||||
@ -162,65 +187,65 @@ void tst_QWidget_window::tst_min_max_size()
|
||||
void tst_QWidget_window::tst_move_show()
|
||||
{
|
||||
QWidget w;
|
||||
w.move(100, 100);
|
||||
const QPoint pos(100, 100);
|
||||
w.move(pos);
|
||||
w.show();
|
||||
#ifdef Q_OS_WINRT
|
||||
QEXPECT_FAIL("", "Winrt does not support move", Abort);
|
||||
#endif
|
||||
QCOMPARE(w.pos(), QPoint(100, 100));
|
||||
// QCoreApplication::processEvents(QEventLoop::AllEvents, 3000);
|
||||
QVERIFY2(qFuzzyCompareWindowPosition(w.pos(), pos, m_fuzz),
|
||||
qPrintable(msgPointMismatch(w.pos(), pos)));
|
||||
}
|
||||
|
||||
void tst_QWidget_window::tst_show_move()
|
||||
{
|
||||
QWidget w;
|
||||
w.show();
|
||||
w.move(100, 100);
|
||||
QCOMPARE(w.pos(), QPoint(100, 100));
|
||||
// QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
|
||||
const QPoint pos(100, 100);
|
||||
w.move(pos);
|
||||
QVERIFY2(qFuzzyCompareWindowPosition(w.pos(), pos, m_fuzz),
|
||||
qPrintable(msgPointMismatch(w.pos(), pos)));
|
||||
}
|
||||
|
||||
void tst_QWidget_window::tst_show_move_hide_show()
|
||||
{
|
||||
QWidget w;
|
||||
w.show();
|
||||
w.move(100, 100);
|
||||
const QPoint pos(100, 100);
|
||||
w.move(pos);
|
||||
w.hide();
|
||||
w.show();
|
||||
QCOMPARE(w.pos(), QPoint(100, 100));
|
||||
// QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
|
||||
QVERIFY2(qFuzzyCompareWindowPosition(w.pos(), pos, m_fuzz),
|
||||
qPrintable(msgPointMismatch(w.pos(), pos)));
|
||||
}
|
||||
|
||||
void tst_QWidget_window::tst_resize_show()
|
||||
{
|
||||
QWidget w;
|
||||
w.resize(200, 200);
|
||||
w.resize(m_testWidgetSize);
|
||||
w.show();
|
||||
#ifdef Q_OS_WINRT
|
||||
QEXPECT_FAIL("", "Winrt does not support resize", Abort);
|
||||
#endif
|
||||
QCOMPARE(w.size(), QSize(200, 200));
|
||||
// QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
|
||||
QCOMPARE(w.size(), m_testWidgetSize);
|
||||
}
|
||||
|
||||
void tst_QWidget_window::tst_show_resize()
|
||||
{
|
||||
QWidget w;
|
||||
w.show();
|
||||
w.resize(200, 200);
|
||||
QCOMPARE(w.size(), QSize(200, 200));
|
||||
// QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
|
||||
w.resize(m_testWidgetSize);
|
||||
QCOMPARE(w.size(), m_testWidgetSize);
|
||||
}
|
||||
|
||||
void tst_QWidget_window::tst_show_resize_hide_show()
|
||||
{
|
||||
QWidget w;
|
||||
w.show();
|
||||
w.resize(200, 200);
|
||||
w.resize(m_testWidgetSize);
|
||||
w.hide();
|
||||
w.show();
|
||||
QCOMPARE(w.size(), QSize(200, 200));
|
||||
// QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
|
||||
QCOMPARE(w.size(), m_testWidgetSize);
|
||||
}
|
||||
|
||||
class PaintTestWidget : public QWidget
|
||||
@ -857,7 +882,7 @@ void tst_QWidget_window::tst_updateWinId_QTBUG40681()
|
||||
lbl->setAttribute(Qt::WA_NativeWindow);
|
||||
lbl->setObjectName("label1");
|
||||
vl->addWidget(lbl);
|
||||
w.setMinimumWidth(200);
|
||||
w.setMinimumWidth(m_testWidgetSize.width());
|
||||
|
||||
w.show();
|
||||
|
||||
@ -880,6 +905,7 @@ void tst_QWidget_window::tst_updateWinId_QTBUG40681()
|
||||
void tst_QWidget_window::tst_recreateWindow_QTBUG40817()
|
||||
{
|
||||
QTabWidget tab;
|
||||
tab.setMinimumWidth(m_testWidgetSize.width());
|
||||
|
||||
QWidget *w = new QWidget;
|
||||
tab.addTab(w, "Tab1");
|
||||
@ -946,7 +972,7 @@ void tst_QWidget_window::tst_resize_count()
|
||||
resize.resizeCount = 0;
|
||||
|
||||
ResizeWidget child(&resize);
|
||||
child.resize(200,200);
|
||||
child.resize(m_testWidgetSize);
|
||||
child.winId();
|
||||
child.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&child));
|
||||
@ -963,7 +989,7 @@ void tst_QWidget_window::tst_resize_count()
|
||||
{
|
||||
ResizeWidget parent;
|
||||
ResizeWidget child(&parent);
|
||||
child.resize(200,200);
|
||||
child.resize(m_testWidgetSize);
|
||||
child.winId();
|
||||
parent.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&parent));
|
||||
@ -1076,6 +1102,7 @@ void tst_QWidget_window::QTBUG_50561_QCocoaBackingStore_paintDevice_crash()
|
||||
ApplicationStateSaver as;
|
||||
|
||||
QMainWindow w;
|
||||
w.setMinimumWidth(m_testWidgetSize.width());
|
||||
w.addToolBar(new QToolBar(&w));
|
||||
w.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&w));
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user