Merge "Merge remote-tracking branch 'origin/5.12' into 5.13"

This commit is contained in:
Friedemann Kleint 2019-05-27 09:16:56 +02:00
commit 65cfac73bd
45 changed files with 2239 additions and 1414 deletions

View File

@ -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

View File

@ -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);

View 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]

View 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
*/

View File

@ -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));

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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());
}

View File

@ -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"));

View 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]

View 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
*/

View File

@ -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());
}
}

View File

@ -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;
}
/*!

View File

@ -355,7 +355,7 @@ public:
void createRecursively();
void createWinId();
void setScreenForPoint(const QPoint &pos);
bool setScreenForPoint(const QPoint &pos);
void createTLExtra();
void createExtra();

View File

@ -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.

View File

@ -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) {

View File

@ -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

View File

@ -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;

View File

@ -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:

View File

@ -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:

View File

@ -17,6 +17,8 @@ android
[modalWindowEnterEventOnHide_QTBUG35109]
ubuntu-16.04
osx ci
[spuriousMouseMove]
windows ci
# QTBUG-69162
android
[modalDialogClosingOneOfTwoModal]

View File

@ -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();

View File

@ -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;

View File

@ -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();

View File

@ -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

View File

@ -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));