Merge remote-tracking branch 'origin/5.13' into dev

Change-Id: Ia279fc4a8226626041c772902a07b2f90f37b53b
This commit is contained in:
Friedemann Kleint 2019-05-27 15:34:10 +02:00
commit 518cf3312c
79 changed files with 2480 additions and 1543 deletions

View File

@ -71,6 +71,16 @@
\title CMake AUTOMOC Documentation \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 \externalpage https://cmake.org/cmake/help/latest/prop_tgt/LOCATION.html
\title CMake LOCATION Documentation \title CMake LOCATION Documentation

View File

@ -50,10 +50,7 @@ builtin_resources {
# Install rules # Install rules
qmldir.base = $$qmldir_path qmldir.base = $$qmldir_path
# Tools need qmldir and plugins.qmltypes always installed on the file system
qmldir.files = $$qmldir_file qmldir.files = $$qmldir_file
install_qml_files: qmldir.files += $$fq_qml_files
qmldir.path = $$[QT_INSTALL_QML]/$$TARGETPATH qmldir.path = $$[QT_INSTALL_QML]/$$TARGETPATH
INSTALLS += qmldir INSTALLS += qmldir
@ -65,12 +62,12 @@ INSTALLS += qmlfiles
!debug_and_release|!build_all|CONFIG(release, debug|release) { !debug_and_release|!build_all|CONFIG(release, debug|release) {
!prefix_build { !prefix_build {
COPIES += qmldir COPIES += qmldir qmlfiles
} else { } else {
# For non-installed static builds, tools need qmldir and plugins.qmltypes # For non-installed static builds, tools need qmldir and plugins.qmltypes
# files in the build dir # files in the build dir
qmldir2build.files = $$qmldir_file $$fq_aux_qml_files qml2build.files = $$qmldir_file $$fq_aux_qml_files
qmldir2build.path = $$DESTDIR qml2build.path = $$DESTDIR
COPIES += qmldir2build COPIES += qml2build
} }
} }

View File

@ -67,7 +67,7 @@ contains(TEMPLATE, .*app) {
# replacing the app name placeholder with the actual app name. # replacing the app name placeholder with the actual app name.
apphtml.name = application main html file apphtml.name = application main html file
apphtml.output = $$DESTDIR/$$TARGET_HTML apphtml.output = $$DESTDIR/$$TARGET_HTML
apphtml.commands = sed -e s/APPNAME/$$TARGET_BASE/g $$WASM_PLUGIN_PATH/wasm_shell.html > $$DESTDIR/$$TARGET_HTML apphtml.commands = sed -e s/@APPNAME@/$$TARGET_BASE/g $$WASM_PLUGIN_PATH/wasm_shell.html > $$DESTDIR/$$TARGET_HTML
apphtml.input = $$WASM_PLUGIN_PATH/wasm_shell.html apphtml.input = $$WASM_PLUGIN_PATH/wasm_shell.html
apphtml.depends = $$apphtml.input apphtml.depends = $$apphtml.input
QMAKE_EXTRA_COMPILERS += apphtml QMAKE_EXTRA_COMPILERS += apphtml

View File

@ -1154,8 +1154,9 @@
\target DEPENDPATH \target DEPENDPATH
\section1 DEPENDPATH \section1 DEPENDPATH
Specifies a list of all directories to look in to resolve dependencies. This Specifies a list of directories for qmake to scan, to resolve dependencies.
variable is used when crawling through \c included files. This variable is used when qmake crawls through the header files that you
\c{#include} in your source code.
\target DESTDIR \target DESTDIR
\section1 DESTDIR \section1 DESTDIR

View File

@ -1995,14 +1995,11 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t)
QString dep_cmd = replaceExtraCompilerVariables(tmp_dep_cmd, inpf, tmp_out, LocalShell); QString dep_cmd = replaceExtraCompilerVariables(tmp_dep_cmd, inpf, tmp_out, LocalShell);
dep_cmd = dep_cd_cmd + fixEnvVariables(dep_cmd); dep_cmd = dep_cd_cmd + fixEnvVariables(dep_cmd);
if (FILE *proc = QT_POPEN(dep_cmd.toLatin1().constData(), QT_POPEN_READ)) { if (FILE *proc = QT_POPEN(dep_cmd.toLatin1().constData(), QT_POPEN_READ)) {
QString indeps; QByteArray depData;
while(!feof(proc)) { while (int read_in = feof(proc) ? 0 : (int)fread(buff, 1, 255, proc))
int read_in = (int)fread(buff, 1, 255, proc); depData.append(buff, read_in);
if(!read_in)
break;
indeps += QByteArray(buff, read_in);
}
QT_PCLOSE(proc); QT_PCLOSE(proc);
const QString indeps = QString::fromLocal8Bit(depData);
if(!indeps.isEmpty()) { if(!indeps.isEmpty()) {
QDir outDir(Option::output_dir); QDir outDir(Option::output_dir);
QStringList dep_cmd_deps = splitDeps(indeps, dep_lines); QStringList dep_cmd_deps = splitDeps(indeps, dep_lines);
@ -2083,14 +2080,11 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t)
QString dep_cmd = replaceExtraCompilerVariables(tmp_dep_cmd, inpf, out, LocalShell); QString dep_cmd = replaceExtraCompilerVariables(tmp_dep_cmd, inpf, out, LocalShell);
dep_cmd = dep_cd_cmd + fixEnvVariables(dep_cmd); dep_cmd = dep_cd_cmd + fixEnvVariables(dep_cmd);
if (FILE *proc = QT_POPEN(dep_cmd.toLatin1().constData(), QT_POPEN_READ)) { if (FILE *proc = QT_POPEN(dep_cmd.toLatin1().constData(), QT_POPEN_READ)) {
QString indeps; QByteArray depData;
while(!feof(proc)) { while (int read_in = feof(proc) ? 0 : (int)fread(buff, 1, 255, proc))
int read_in = (int)fread(buff, 1, 255, proc); depData.append(buff, read_in);
if(!read_in)
break;
indeps += QByteArray(buff, read_in);
}
QT_PCLOSE(proc); QT_PCLOSE(proc);
const QString indeps = QString::fromLocal8Bit(depData);
if(!indeps.isEmpty()) { if(!indeps.isEmpty()) {
QDir outDir(Option::output_dir); QDir outDir(Option::output_dir);
QStringList dep_cmd_deps = splitDeps(indeps, dep_lines); 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

@ -695,52 +695,36 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry,
Q_UNUSED(data); Q_UNUSED(data);
return QFileSystemEntry(slowCanonicalized(absoluteName(entry).filePath())); return QFileSystemEntry(slowCanonicalized(absoluteName(entry).filePath()));
#else #else
char *ret = 0; char stack_result[PATH_MAX+1];
# if defined(Q_OS_DARWIN) char *resolved_name = nullptr;
ret = (char*)malloc(PATH_MAX + 1); # if defined(Q_OS_DARWIN) || defined(Q_OS_ANDROID)
if (ret && realpath(entry.nativeFilePath().constData(), (char*)ret) == 0) { // On some Android and macOS versions, realpath() will return a path even if
const int savedErrno = errno; // errno is checked below, and free() might change it // it does not exist. To work around this, we check existence in advance.
free(ret);
errno = savedErrno;
ret = 0;
}
# elif defined(Q_OS_ANDROID)
// On some Android versions, realpath() will return a path even if it does not exist
// To work around this, we check existence in advance.
if (!data.hasFlags(QFileSystemMetaData::ExistsAttribute)) if (!data.hasFlags(QFileSystemMetaData::ExistsAttribute))
fillMetaData(entry, data, QFileSystemMetaData::ExistsAttribute); fillMetaData(entry, data, QFileSystemMetaData::ExistsAttribute);
if (!data.exists()) { if (!data.exists()) {
ret = 0;
errno = ENOENT; errno = ENOENT;
} else { } else {
ret = (char*)malloc(PATH_MAX + 1); resolved_name = stack_result;
if (realpath(entry.nativeFilePath().constData(), (char*)ret) == 0) {
const int savedErrno = errno; // errno is checked below, and free() might change it
free(ret);
errno = savedErrno;
ret = 0;
} }
} if (resolved_name && realpath(entry.nativeFilePath().constData(), resolved_name) == nullptr)
resolved_name = nullptr;
# else # else
# if _POSIX_VERSION >= 200801L # if _POSIX_VERSION >= 200801L // ask realpath to allocate memory
ret = realpath(entry.nativeFilePath().constData(), (char*)0); resolved_name = realpath(entry.nativeFilePath().constData(), nullptr);
# else # else
ret = (char*)malloc(PATH_MAX + 1); resolved_name = stack_result;
if (realpath(entry.nativeFilePath().constData(), (char*)ret) == 0) { if (realpath(entry.nativeFilePath().constData(), resolved_name) == nullptr)
const int savedErrno = errno; // errno is checked below, and free() might change it resolved_name = nullptr;
free(ret);
errno = savedErrno;
ret = 0;
}
# endif # endif
# endif # endif
if (ret) { if (resolved_name) {
data.knownFlagsMask |= QFileSystemMetaData::ExistsAttribute; data.knownFlagsMask |= QFileSystemMetaData::ExistsAttribute;
data.entryFlags |= QFileSystemMetaData::ExistsAttribute; data.entryFlags |= QFileSystemMetaData::ExistsAttribute;
QString canonicalPath = QDir::cleanPath(QFile::decodeName(ret)); QString canonicalPath = QDir::cleanPath(QFile::decodeName(resolved_name));
free(ret); if (resolved_name != stack_result)
free(resolved_name);
return QFileSystemEntry(canonicalPath); return QFileSystemEntry(canonicalPath);
} else if (errno == ENOENT || errno == ENOTDIR) { // file doesn't exist } else if (errno == ENOENT || errno == ENOTDIR) { // file doesn't exist
data.knownFlagsMask |= QFileSystemMetaData::ExistsAttribute; data.knownFlagsMask |= QFileSystemMetaData::ExistsAttribute;

View File

@ -46,6 +46,7 @@
#include "qcoreevent.h" #include "qcoreevent.h"
#include "qeventloop.h" #include "qeventloop.h"
#endif #endif
#include "qmetaobject.h"
#include "qcorecmdlineargs_p.h" #include "qcorecmdlineargs_p.h"
#include <qdatastream.h> #include <qdatastream.h>
#include <qdebug.h> #include <qdebug.h>
@ -952,6 +953,10 @@ bool QCoreApplication::isSetuidAllowed()
Sets the attribute \a attribute if \a on is true; Sets the attribute \a attribute if \a on is true;
otherwise clears the attribute. otherwise clears the attribute.
\note Some application attributes must be set \b before creating a
QCoreApplication instance. Refer to the Qt::ApplicationAttribute
documentation for more information.
\sa testAttribute() \sa testAttribute()
*/ */
void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on) void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on)
@ -960,6 +965,27 @@ void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on)
QCoreApplicationPrivate::attribs |= 1 << attribute; QCoreApplicationPrivate::attribs |= 1 << attribute;
else else
QCoreApplicationPrivate::attribs &= ~(1 << attribute); QCoreApplicationPrivate::attribs &= ~(1 << attribute);
if (Q_UNLIKELY(qApp)) {
switch (attribute) {
case Qt::AA_EnableHighDpiScaling:
case Qt::AA_DisableHighDpiScaling:
case Qt::AA_PluginApplication:
case Qt::AA_UseDesktopOpenGL:
case Qt::AA_UseOpenGLES:
case Qt::AA_UseSoftwareOpenGL:
case Qt::AA_ShareOpenGLContexts:
#ifdef QT_BOOTSTRAPPED
qWarning("Attribute %d must be set before QCoreApplication is created.",
attribute);
#else
qWarning("Attribute Qt::%s must be set before QCoreApplication is created.",
QMetaEnum::fromType<Qt::ApplicationAttribute>().valueToKey(attribute));
#endif
break;
default:
break;
}
}
} }
/*! /*!

View File

@ -230,7 +230,8 @@ public:
template<typename T> static QMetaEnum fromType() { template<typename T> static QMetaEnum fromType() {
Q_STATIC_ASSERT_X(QtPrivate::IsQEnumHelper<T>::Value, 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 QMetaObject *metaObject = qt_getEnumMetaObject(T());
const char *name = qt_getEnumName(T()); const char *name = qt_getEnumName(T());
return metaObject->enumerator(metaObject->indexOfEnumerator(name)); return metaObject->enumerator(metaObject->indexOfEnumerator(name));

View File

@ -74,7 +74,7 @@ QT_BEGIN_NAMESPACE
# define QLIBRARY_AS_DEBUG true # define QLIBRARY_AS_DEBUG true
#endif #endif
#if defined(Q_OS_UNIX) #if defined(Q_OS_UNIX) || defined(Q_CC_MINGW)
// We don't use separate debug and release libs on UNIX, so we want // We don't use separate debug and release libs on UNIX, so we want
// to allow loading plugins, regardless of how they were built. // to allow loading plugins, regardless of how they were built.
# define QT_NO_DEBUG_PLUGIN_CHECK # define QT_NO_DEBUG_PLUGIN_CHECK

View File

@ -50,8 +50,8 @@
//! [0] //! [0]
QStandardItemModel model(4, 4); QStandardItemModel model(4, 4);
for (int row = 0; row < 4; ++row) { for (int row = 0; row < model.rowCount(); ++row) {
for (int column = 0; column < 4; ++column) { for (int column = 0; column < model.columnCount(); ++column) {
QStandardItem *item = new QStandardItem(QString("row %0, column %1").arg(row).arg(column)); QStandardItem *item = new QStandardItem(QString("row %0, column %1").arg(row).arg(column));
model.setItem(row, column, item); model.setItem(row, column, item);
} }

View File

@ -492,5 +492,13 @@ QPoint QHighDpiScaling::origin(const QPlatformScreen *platformScreen)
return platformScreen->geometry().topLeft(); 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 #endif //QT_NO_HIGHDPISCALING
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -83,6 +83,7 @@ public:
static qreal factor(const QPlatformScreen *platformScreen); static qreal factor(const QPlatformScreen *platformScreen);
static QPoint origin(const QScreen *screen); static QPoint origin(const QScreen *screen);
static QPoint origin(const QPlatformScreen *platformScreen); static QPoint origin(const QPlatformScreen *platformScreen);
static QPoint origin(const QWindow *window);
static QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen); static QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen);
static QPoint mapPositionFromNative(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); 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; 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 qreal scaleFactor = QHighDpiScaling::factor(context);
const QPoint origin = QHighDpiScaling::origin(platformScreen); const QPoint origin = QHighDpiScaling::origin(context);
return QRect(fromNative(pixelRect.topLeft(), scaleFactor, origin), return QRect(fromNative(pixelRect.topLeft(), scaleFactor, origin),
fromNative(pixelRect.size(), scaleFactor)); 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 qreal scaleFactor = QHighDpiScaling::factor(context);
const QPoint origin = QHighDpiScaling::origin(platformScreen); const QPoint origin = QHighDpiScaling::origin(context);
return QRect(toNative(pointRect.topLeft(), scaleFactor, origin), return QRect(toNative(pointRect.topLeft(), scaleFactor, origin),
toNative(pointRect.size(), scaleFactor)); 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 qreal scaleFactor = QHighDpiScaling::factor(context);
const QPoint origin = QHighDpiScaling::origin(screen); const QPoint origin = QHighDpiScaling::origin(context);
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);
return QRectF(toNative(pointRect.topLeft(), scaleFactor, origin), 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()) { const qreal scaleFactor = QHighDpiScaling::factor(context);
return toNativePixels(pointRect, window->screen()); const QPoint origin = QHighDpiScaling::origin(context);
} 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);
return QRectF(fromNative(pixelRect.topLeft(), scaleFactor, origin), return QRectF(fromNative(pixelRect.topLeft(), scaleFactor, origin),
fromNative(pixelRect.size(), scaleFactor)); 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) inline QSize fromNativePixels(const QSize &pixelSize, const QWindow *window)
{ {
return pixelSize / QHighDpiScaling::factor(window); return pixelSize / QHighDpiScaling::factor(window);
@ -311,56 +260,28 @@ inline QSizeF toNativePixels(const QSizeF &pointSize, const QWindow *window)
return pointSize * QHighDpiScaling::factor(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 toNative(pointPoint, QHighDpiScaling::factor(context), QHighDpiScaling::origin(context));
return fromNativePixels(pixelPoint, window->screen());
else
return pixelPoint / QHighDpiScaling::factor(window);
} }
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 toNative(pointPoint, QHighDpiScaling::factor(context), QHighDpiScaling::origin(context));
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);
} }
inline QMargins fromNativePixels(const QMargins &pixelMargins, const QWindow *window) 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/() // Any T that has operator/()
template <typename T> template <typename T, typename C>
T fromNativePixels(const T &pixelValue, const QWindow *window) T fromNativePixels(const T &pixelValue, const C *context)
{ {
if (!QHighDpiScaling::isActive()) if (!QHighDpiScaling::isActive())
return pixelValue; return pixelValue;
return pixelValue / QHighDpiScaling::factor(window); return pixelValue / QHighDpiScaling::factor(context);
}
//##### ?????
template <typename T>
T fromNativePixels(const T &pixelValue, const QScreen *screen)
{
if (!QHighDpiScaling::isActive())
return pixelValue;
return pixelValue / QHighDpiScaling::factor(screen);
} }
// Any T that has operator*() // Any T that has operator*()
template <typename T> template <typename T, typename C>
T toNativePixels(const T &pointValue, const QWindow *window) T toNativePixels(const T &pointValue, const C *context)
{ {
if (!QHighDpiScaling::isActive()) if (!QHighDpiScaling::isActive())
return pointValue; 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/() // Any QVector<T> where T has operator/()
template <typename T> template <typename T>
QVector<T> fromNativePixels(const QVector<T> &pixelValues, const QWindow *window) QVector<T> fromNativePixels(const QVector<T> &pixelValues, const QWindow *window)

View File

@ -471,6 +471,8 @@ QVariant QPlatformTheme::themeHint(ThemeHint hint) const
return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::ItemViewActivateItemOnSingleClick); return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::ItemViewActivateItemOnSingleClick);
case QPlatformTheme::UiEffects: case QPlatformTheme::UiEffects:
return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::UiEffects); return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::UiEffects);
case QPlatformTheme::ShowShortcutsInContextMenus:
return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::ShowShortcutsInContextMenus);
default: default:
return QPlatformTheme::defaultThemeHint(hint); return QPlatformTheme::defaultThemeHint(hint);
} }
@ -521,7 +523,7 @@ QVariant QPlatformTheme::defaultThemeHint(ThemeHint hint)
case QPlatformTheme::StyleNames: case QPlatformTheme::StyleNames:
return QVariant(QStringList()); return QVariant(QStringList());
case QPlatformTheme::ShowShortcutsInContextMenus: case QPlatformTheme::ShowShortcutsInContextMenus:
return QVariant(false); return QVariant(true);
case TextCursorWidth: case TextCursorWidth:
return QVariant(1); return QVariant(1);
case DropShadow: case DropShadow:

View File

@ -705,14 +705,20 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w,
w, defaultWidth, defaultHeight); w, defaultWidth, defaultHeight);
return QRect(initialGeometry.topLeft(), QHighDpi::toNative(size, factor)); 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) if (!screen)
return initialGeometry; return initialGeometry;
const auto *wp = qt_window_private(const_cast<QWindow*>(w)); // initialGeometry refers to window's screen
QRect rect(QHighDpi::fromNativePixels(initialGeometry, w)); QRect rect(QHighDpi::fromNativePixels(initialGeometry, w));
if (wp->resizeAutomatic) if (wp->resizeAutomatic)
rect.setSize(fixInitialSize(rect.size(), w, defaultWidth, defaultHeight)); rect.setSize(fixInitialSize(rect.size(), w, defaultWidth, defaultHeight));
if (wp->positionAutomatic && w->type() != Qt::Popup) { if (position) {
const QRect availableGeometry = screen->availableGeometry(); const QRect availableGeometry = screen->availableGeometry();
// Center unless the geometry ( + unknown window frame) is too large for the screen). // Center unless the geometry ( + unknown window frame) is too large for the screen).
if (rect.height() < (availableGeometry.height() * 8) / 9 if (rect.height() < (availableGeometry.height() * 8) / 9

View File

@ -434,7 +434,7 @@ public:
QImage::Format prepare(QImage *image); QImage::Format prepare(QImage *image);
uchar *scanLine(int y) { Q_ASSERT(y>=0); Q_ASSERT(y<m_height); return m_buffer + y * bytes_per_line; } uchar *scanLine(int y) { Q_ASSERT(y>=0); Q_ASSERT(y<m_height); return m_buffer + y * qsizetype(bytes_per_line); }
int width() const { return m_width; } int width() const { return m_width; }
int height() const { return m_height; } int height() const { return m_height; }

View File

@ -43,6 +43,7 @@
#include "qtextodfwriter_p.h" #include "qtextodfwriter_p.h"
#include <QImageReader>
#include <QImageWriter> #include <QImageWriter>
#include <QTextListFormat> #include <QTextListFormat>
#include <QTextList> #include <QTextList>
@ -410,6 +411,29 @@ void QTextOdfWriter::writeBlock(QXmlStreamWriter &writer, const QTextBlock &bloc
writer.writeEndElement(); // list-item 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 void QTextOdfWriter::writeInlineCharacter(QXmlStreamWriter &writer, const QTextFragment &fragment) const
{ {
writer.writeStartElement(drawNS, QString::fromLatin1("frame")); writer.writeStartElement(drawNS, QString::fromLatin1("frame"));
@ -420,47 +444,73 @@ void QTextOdfWriter::writeInlineCharacter(QXmlStreamWriter &writer, const QTextF
QTextImageFormat imageFormat = fragment.charFormat().toImageFormat(); QTextImageFormat imageFormat = fragment.charFormat().toImageFormat();
writer.writeAttribute(drawNS, QString::fromLatin1("name"), imageFormat.name()); writer.writeAttribute(drawNS, QString::fromLatin1("name"), imageFormat.name());
QByteArray data;
QString mimeType;
qreal width = 0;
qreal height = 0;
QImage image; QImage image;
QString name = imageFormat.name(); QString name = imageFormat.name();
if (name.startsWith(QLatin1String(":/"))) // auto-detect resources if (name.startsWith(QLatin1String(":/"))) // auto-detect resources
name.prepend(QLatin1String("qrc")); name.prepend(QLatin1String("qrc"));
QUrl url = QUrl(name); QUrl url = QUrl(name);
const QVariant data = m_document->resource(QTextDocument::ImageResource, url); const QVariant variant = m_document->resource(QTextDocument::ImageResource, url);
if (data.type() == QVariant::Image) { if (variant.type() == QVariant::Image) {
image = qvariant_cast<QImage>(data); image = qvariant_cast<QImage>(variant);
} else if (data.type() == QVariant::ByteArray) { } else if (variant.type() == QVariant::ByteArray) {
image.loadFromData(data.toByteArray()); data = variant.toByteArray();
}
if (image.isNull()) { QBuffer buffer(&data);
if (image.isNull()) { // try direct loading buffer.open(QIODevice::ReadOnly);
name = imageFormat.name(); // remove qrc:/ prefix again probeImageData(&buffer, &image, &mimeType, &width, &height);
image.load(name); } 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()) { if (! image.isNull()) {
QBuffer imageBytes; QBuffer imageBytes;
QString filename = m_strategy->createUniqueImageName();
int imgQuality = imageFormat.quality(); int imgQuality = imageFormat.quality();
if (imgQuality >= 100 || imgQuality < 0 || image.hasAlphaChannel()) { if (imgQuality >= 100 || imgQuality < 0 || image.hasAlphaChannel()) {
QImageWriter imageWriter(&imageBytes, "png"); QImageWriter imageWriter(&imageBytes, "png");
imageWriter.write(image); imageWriter.write(image);
m_strategy->addFile(filename, QString::fromLatin1("image/png"), imageBytes.data());
data = imageBytes.data();
mimeType = QStringLiteral("image/png");
} else { } else {
// Write images without alpha channel as jpg with quality set by QTextImageFormat // Write images without alpha channel as jpg with quality set by QTextImageFormat
QImageWriter imageWriter(&imageBytes, "jpg"); QImageWriter imageWriter(&imageBytes, "jpg");
imageWriter.setQuality(imgQuality); imageWriter.setQuality(imgQuality);
imageWriter.write(image); 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) width = image.width();
? imageFormat.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)); 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(svgNS, QString::fromLatin1("height"), pixelToPoint(height));
writer.writeAttribute(textNS, QStringLiteral("anchor-type"), QStringLiteral("as-char"));
writer.writeStartElement(drawNS, QString::fromLatin1("image")); writer.writeStartElement(drawNS, QString::fromLatin1("image"));
writer.writeAttribute(xlinkNS, QString::fromLatin1("href"), filename); writer.writeAttribute(xlinkNS, QString::fromLatin1("href"), filename);
writer.writeEndElement(); // image writer.writeEndElement(); // image

View File

@ -235,7 +235,7 @@ void QNetworkReplyWasmImpl::close()
void QNetworkReplyWasmImpl::abort() void QNetworkReplyWasmImpl::abort()
{ {
Q_D(const QNetworkReplyWasmImpl); Q_D(const QNetworkReplyWasmImpl);
setError( QNetworkReply::OperationCanceledError, "Operation canceled" ); setError( QNetworkReply::OperationCanceledError, QStringLiteral("Operation canceled"));
d->doAbort(); d->doAbort();
close(); close();
@ -328,8 +328,6 @@ void QNetworkReplyWasmImplPrivate::doSendRequest()
m_xhr = val::global("XMLHttpRequest").new_(); m_xhr = val::global("XMLHttpRequest").new_();
std::string verb = q->methodName().toStdString(); std::string verb = q->methodName().toStdString();
QString extraDataString;
m_xhr.call<void>("open", verb, request.url().toString().toStdString()); m_xhr.call<void>("open", verb, request.url().toString().toStdString());
m_xhr.set("onerror", val::module_property("qt_QNetworkReplyWasmImplPrivate_requestErrorCallback")); m_xhr.set("onerror", val::module_property("qt_QNetworkReplyWasmImplPrivate_requestErrorCallback"));
@ -348,30 +346,12 @@ void QNetworkReplyWasmImplPrivate::doSendRequest()
if (outgoingData) // data from post request if (outgoingData) // data from post request
extraData = outgoingData->readAll(); extraData = outgoingData->readAll();
if (contentType.contains("text") || if (!extraData.isEmpty()) {
contentType.contains("json") || dataToSend = val(typed_memory_view(extraData.size(),
contentType.contains("form")) { reinterpret_cast<const unsigned char *>
if (extraData.size() > 0) (extraData.constData())));
extraDataString.fromUtf8(extraData);
} }
if (contentType.contains("json")) {
if (!extraDataString.isEmpty()) {
m_xhr.set("responseType", val("json"));
dataToSend = val(extraDataString.toStdString());
}
} else if (contentType.contains("form")) { //construct form data
if (!extraDataString.isEmpty()) {
val formData = val::global("FormData").new_();
QStringList formList = extraDataString.split('&');
for (auto formEntry : formList) {
formData.call<void>("append", formEntry.split('=')[0].toStdString(), formEntry.split('=')[1].toStdString());
}
dataToSend = formData;
}
} else {
m_xhr.set("responseType", val("blob")); m_xhr.set("responseType", val("blob"));
}
// set request headers // set request headers
for (auto header : request.rawHeaderList()) { for (auto header : request.rawHeaderList()) {
m_xhr.call<void>("setRequestHeader", header.toStdString(), request.rawHeader(header).toStdString()); m_xhr.call<void>("setRequestHeader", header.toStdString(), request.rawHeader(header).toStdString());

View File

@ -66,10 +66,10 @@
#include <QtGui/qopengl.h> #include <QtGui/qopengl.h>
class QOpenGLContext;
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QOpenGLContext;
#if 0 #if 0
// silence syncqt warnings // silence syncqt warnings
#pragma qt_class(QOpenGLExtensions) #pragma qt_class(QOpenGLExtensions)

View File

@ -435,8 +435,23 @@ QList<QByteArray> QMacPasteboardMimeUnicodeText::convertFromMime(const QString &
if (flavor == QLatin1String("public.utf8-plain-text")) if (flavor == QLatin1String("public.utf8-plain-text"))
ret.append(string.toUtf8()); ret.append(string.toUtf8());
#if QT_CONFIG(textcodec) #if QT_CONFIG(textcodec)
else if (flavor == QLatin1String("public.utf16-plain-text")) else if (flavor == QLatin1String("public.utf16-plain-text")) {
ret.append(QTextCodec::codecForName("UTF-16")->fromUnicode(string)); 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 #endif
return ret; return ret;
} }

View File

@ -984,7 +984,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
|| matrix.xy != 0 || matrix.xy != 0
|| matrix.yx != 0; || matrix.yx != 0;
if (transform || (format != Format_Mono && !isScalableBitmap())) if (transform || obliquen || (format != Format_Mono && !isScalableBitmap()))
load_flags |= FT_LOAD_NO_BITMAP; load_flags |= FT_LOAD_NO_BITMAP;
FT_Error err = FT_Load_Glyph(face, glyph, load_flags); FT_Error err = FT_Load_Glyph(face, glyph, load_flags);

View File

@ -581,10 +581,16 @@ void QKmsDevice::createScreens()
#if QT_CONFIG(drm_atomic) #if QT_CONFIG(drm_atomic)
// check atomic support // check atomic support
m_has_atomic_support = !drmSetClientCap(m_dri_fd, DRM_CLIENT_CAP_ATOMIC, 1) m_has_atomic_support = !drmSetClientCap(m_dri_fd, DRM_CLIENT_CAP_ATOMIC, 1);
&& qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_ATOMIC"); if (m_has_atomic_support) {
if (m_has_atomic_support) qCDebug(qLcKmsDebug, "Atomic reported as supported");
qCDebug(qLcKmsDebug) << "Atomic Support found"; if (qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_ATOMIC")) {
qCDebug(qLcKmsDebug, "Atomic enabled");
} else {
qCDebug(qLcKmsDebug, "Atomic disabled");
m_has_atomic_support = false;
}
}
#endif #endif
drmModeResPtr resources = drmModeGetResources(m_dri_fd); drmModeResPtr resources = drmModeGetResources(m_dri_fd);

View File

@ -71,6 +71,10 @@ DBusConnection::DBusConnection(QObject *parent)
{ {
// Start monitoring if "org.a11y.Bus" is registered as DBus service. // Start monitoring if "org.a11y.Bus" is registered as DBus service.
QDBusConnection c = QDBusConnection::sessionBus(); QDBusConnection c = QDBusConnection::sessionBus();
if (!c.isConnected()) {
return;
}
dbusWatcher = new QDBusServiceWatcher(A11Y_SERVICE, c, QDBusServiceWatcher::WatchForRegistration, this); dbusWatcher = new QDBusServiceWatcher(A11Y_SERVICE, c, QDBusServiceWatcher::WatchForRegistration, this);
connect(dbusWatcher, SIGNAL(serviceRegistered(QString)), this, SLOT(serviceRegistered())); connect(dbusWatcher, SIGNAL(serviceRegistered(QString)), this, SLOT(serviceRegistered()));

View File

@ -360,4 +360,27 @@ __CRT_UUID_DECL(IGridItemProvider, 0xd02541f1, 0xfb81, 0x4d64, 0xae,0x32, 0xf5,0
#endif #endif
#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 #endif

View File

@ -141,6 +141,20 @@ enum PropertyConditionFlags {
PropertyConditionFlags_IgnoreCase = 1 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 { struct UiaRect {
double left; double left;
double top; double top;

View File

@ -1129,46 +1129,63 @@ QString QAndroidInputContext::getSelectedText(jint /*flags*/)
QString QAndroidInputContext::getTextAfterCursor(jint length, jint /*flags*/) QString QAndroidInputContext::getTextAfterCursor(jint length, jint /*flags*/)
{ {
//### the preedit text could theoretically be after the cursor if (length <= 0)
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())
return QString(); return QString();
QString text = query->value(Qt::ImSurroundingText).toString(); QString text;
if (!text.length())
return text;
int cursorPos = query->value(Qt::ImCursorPosition).toInt(); QVariant reportedTextAfter = QInputMethod::queryFocusObject(Qt::ImTextAfterCursor, length);
return text.mid(cursorPos, 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*/) QString QAndroidInputContext::getTextBeforeCursor(jint length, jint /*flags*/)
{ {
QVariant textBefore = QInputMethod::queryFocusObject(Qt::ImTextBeforeCursor, QVariant(length)); if (length <= 0)
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())
return QString(); return QString();
int cursorPos = query->value(Qt::ImCursorPosition).toInt(); QString text;
QString text = query->value(Qt::ImSurroundingText).toString();
if (!text.length())
return text;
//### the preedit text does not need to be immediately before the cursor QVariant reportedTextBefore = QInputMethod::queryFocusObject(Qt::ImTextBeforeCursor, length);
if (cursorPos <= length) if (reportedTextBefore.isValid()) {
return text.leftRef(cursorPos) + m_composingText; text = reportedTextBefore.toString();
else } else {
return text.midRef(cursorPos - length, length) + m_composingText; // 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()) if (query.isNull())
return JNI_FALSE; return JNI_FALSE;
if (start == end)
return JNI_TRUE;
if (start > end) if (start > end)
qSwap(start, end); qSwap(start, end);

View File

@ -403,8 +403,13 @@ QCocoaServices *QCocoaIntegration::services() const
QVariant QCocoaIntegration::styleHint(StyleHint hint) const QVariant QCocoaIntegration::styleHint(StyleHint hint) const
{ {
if (hint == QPlatformIntegration::FontSmoothingGamma) switch (hint) {
case FontSmoothingGamma:
return QCoreTextFontEngine::fontSmoothingGamma(); return QCoreTextFontEngine::fontSmoothingGamma();
case ShowShortcutsInContextMenus:
return QVariant(false);
default: break;
}
return QPlatformIntegration::styleHint(hint); return QPlatformIntegration::styleHint(hint);
} }

View File

@ -489,19 +489,16 @@ QMacPasteboard::retrieveData(const QString &format, QVariant::Type) const
QMacInternalPasteboardMime *c = mimes.at(mime); QMacInternalPasteboardMime *c = mimes.at(mime);
QString c_flavor = c->flavorFor(format); QString c_flavor = c->flavorFor(format);
if (!c_flavor.isEmpty()) { if (!c_flavor.isEmpty()) {
// Handle text/plain a little differently. Try handling Unicode first. // Converting via PasteboardCopyItemFlavorData below will for some UITs result
bool checkForUtf16 = (c_flavor == QLatin1String("com.apple.traditional-mac-plain-text") // in newlines mapping to '\r' instead of '\n'. To work around this we shortcut
|| c_flavor == QLatin1String("public.utf8-plain-text")); // the conversion via NSPasteboard's NSStringPboardType if possible.
if (checkForUtf16 || c_flavor == QLatin1String("public.utf16-plain-text")) { if (c_flavor == QLatin1String("com.apple.traditional-mac-plain-text")
// Try to get the NSStringPboardType from NSPasteboard, newlines are mapped || c_flavor == QLatin1String("public.utf8-plain-text")
// correctly (as '\n') in this data. The 'public.utf16-plain-text' type || c_flavor == QLatin1String("public.utf16-plain-text")) {
// usually maps newlines to '\r' instead.
QString str = qt_mac_get_pasteboardString(paste); QString str = qt_mac_get_pasteboardString(paste);
if (!str.isEmpty()) if (!str.isEmpty())
return str; return str;
} }
if (checkForUtf16 && hasFlavor(QLatin1String("public.utf16-plain-text")))
c_flavor = QLatin1String("public.utf16-plain-text");
QVariant ret; QVariant ret;
QList<QByteArray> retList; QList<QByteArray> retList;

View File

@ -221,7 +221,7 @@ EGLNativeWindowType QEglFSOpenWFDIntegration::createNativeWindow(QPlatformWindow
QSurfaceFormat QEglFSOpenWFDIntegration::surfaceFormatFor(const QSurfaceFormat &inputFormat) const QSurfaceFormat QEglFSOpenWFDIntegration::surfaceFormatFor(const QSurfaceFormat &inputFormat) const
{ {
QSurfaceFormat format; QSurfaceFormat format = inputFormat;
format.setRedBufferSize(8); format.setRedBufferSize(8);
format.setGreenBufferSize(8); format.setGreenBufferSize(8);
format.setBlueBufferSize(8); format.setBlueBufferSize(8);

View File

@ -834,9 +834,14 @@ static void executeBlockWithoutAnimation(Block block)
- (void)updateSelection - (void)updateSelection
{ {
if (!hasSelection()) { if (!hasSelection()) {
if (_cursorLayer.visible) {
_cursorLayer.visible = NO; _cursorLayer.visible = NO;
_anchorLayer.visible = NO; _anchorLayer.visible = NO;
// Only hide the edit menu if we had a selection from before, since
// the edit menu can also be used for other purposes by others (in
// which case we try our best not to interfere).
QIOSTextInputOverlay::s_editMenu.visible = NO; QIOSTextInputOverlay::s_editMenu.visible = NO;
}
return; return;
} }

View File

@ -48,6 +48,7 @@
#include <QtGui/qscreen.h> #include <QtGui/qscreen.h>
#include <qpa/qwindowsysteminterface.h> #include <qpa/qwindowsysteminterface.h>
#include <QtCore/qcoreapplication.h> #include <QtCore/qcoreapplication.h>
#include <qpa/qplatforminputcontextfactory_p.h>
#include <emscripten/bind.h> #include <emscripten/bind.h>
#include <emscripten/val.h> #include <emscripten/val.h>
@ -180,6 +181,18 @@ QPlatformOpenGLContext *QWasmIntegration::createPlatformOpenGLContext(QOpenGLCon
} }
#endif #endif
void QWasmIntegration::initialize()
{
QString icStr = QPlatformInputContextFactory::requested();
if (!icStr.isNull())
m_inputContext.reset(QPlatformInputContextFactory::create(icStr));
}
QPlatformInputContext *QWasmIntegration::inputContext() const
{
return m_inputContext.data();
}
QPlatformFontDatabase *QWasmIntegration::fontDatabase() const QPlatformFontDatabase *QWasmIntegration::fontDatabase() const
{ {
if (m_fontDb == nullptr) if (m_fontDb == nullptr)

View File

@ -34,6 +34,7 @@
#include <qpa/qplatformintegration.h> #include <qpa/qplatformintegration.h>
#include <qpa/qplatformscreen.h> #include <qpa/qplatformscreen.h>
#include <qpa/qplatforminputcontext.h>
#include <QtCore/qhash.h> #include <QtCore/qhash.h>
@ -73,6 +74,9 @@ public:
QPlatformTheme *createPlatformTheme(const QString &name) const override; QPlatformTheme *createPlatformTheme(const QString &name) const override;
QPlatformServices *services() const override; QPlatformServices *services() const override;
QPlatformClipboard *clipboard() const override; QPlatformClipboard *clipboard() const override;
void initialize() override;
QPlatformInputContext *inputContext() const override;
QWasmClipboard *getWasmClipboard() { return m_clipboard; } QWasmClipboard *getWasmClipboard() { return m_clipboard; }
static QWasmIntegration *get() { return s_instance; } static QWasmIntegration *get() { return s_instance; }
@ -91,6 +95,7 @@ private:
QHash<QString, QWasmScreen *> m_screens; QHash<QString, QWasmScreen *> m_screens;
mutable QWasmClipboard *m_clipboard; mutable QWasmClipboard *m_clipboard;
qreal m_fontDpi = -1; qreal m_fontDpi = -1;
mutable QScopedPointer<QPlatformInputContext> m_inputContext;
static QWasmIntegration *s_instance; static QWasmIntegration *s_instance;
}; };

View File

@ -37,6 +37,14 @@ QWasmOpenGLContext::QWasmOpenGLContext(const QSurfaceFormat &format)
: m_requestedFormat(format) : m_requestedFormat(format)
{ {
m_requestedFormat.setRenderableType(QSurfaceFormat::OpenGLES); m_requestedFormat.setRenderableType(QSurfaceFormat::OpenGLES);
// if we set one, we need to set the other as well since in webgl, these are tied together
if (format.depthBufferSize() < 0 && format.stencilBufferSize() > 0)
m_requestedFormat.setDepthBufferSize(16);
if (format.stencilBufferSize() < 0 && format.depthBufferSize() > 0)
m_requestedFormat.setStencilBufferSize(8);
} }
QWasmOpenGLContext::~QWasmOpenGLContext() QWasmOpenGLContext::~QWasmOpenGLContext()
@ -91,10 +99,14 @@ EMSCRIPTEN_WEBGL_CONTEXT_HANDLE QWasmOpenGLContext::createEmscriptenContext(cons
attributes.majorVersion = 2; attributes.majorVersion = 2;
} }
// WebGL doesn't allow separate attach buffers to STENCIL_ATTACHMENT and DEPTH_ATTACHMENT
// we need both or none
bool useDepthStencil = (format.depthBufferSize() > 0 || format.stencilBufferSize() > 0);
// WebGL offers enable/disable control but not size control for these // WebGL offers enable/disable control but not size control for these
attributes.alpha = format.alphaBufferSize() > 0; attributes.alpha = format.alphaBufferSize() > 0;
attributes.depth = format.depthBufferSize() > 0; attributes.depth = useDepthStencil;
attributes.stencil = format.stencilBufferSize() > 0; attributes.stencil = useDepthStencil;
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context(canvasId.toLocal8Bit().constData(), &attributes); EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context(canvasId.toLocal8Bit().constData(), &attributes);

View File

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>APPNAME</title> <title>@APPNAME@</title>
<style> <style>
html, body { padding: 0; margin : 0; overflow:hidden; height: 100% } html, body { padding: 0; margin : 0; overflow:hidden; height: 100% }
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */ /* the canvas *must not* have any border or padding, or mouse coords will be wrong */
@ -18,7 +18,7 @@
<figure style="overflow:visible;" id="qtspinner"> <figure style="overflow:visible;" id="qtspinner">
<center style="margin-top:1.5em; line-height:150%"> <center style="margin-top:1.5em; line-height:150%">
<img src="qtlogo.svg"; width=320; height=200; style="display:block"> </img> <img src="qtlogo.svg"; width=320; height=200; style="display:block"> </img>
<strong>Qt for WebAssembly: APPNAME</strong> <strong>Qt for WebAssembly: @APPNAME@</strong>
<div id="qtstatus"></div> <div id="qtstatus"></div>
<noscript>JavaScript is disabled. Please enable JavaScript to use this application.</noscript> <noscript>JavaScript is disabled. Please enable JavaScript to use this application.</noscript>
</center> </center>
@ -57,7 +57,7 @@
canvas.style.display = 'block'; canvas.style.display = 'block';
}, },
}); });
qtLoader.loadEmscriptenModule("APPNAME"); qtLoader.loadEmscriptenModule("@APPNAME@");
} }
</script> </script>
<script type="text/javascript" src="qtloader.js"></script> <script type="text/javascript" src="qtloader.js"></script>

View File

@ -1486,6 +1486,10 @@ void QWindowsContext::handleExitSizeMove(QWindow *window)
keyboardModifiers); keyboardModifiers);
} }
} }
if (d->m_systemInfo & QWindowsContext::SI_SupportsPointer)
d->m_pointerHandler.clearEvents();
else
d->m_mouseHandler.clearEvents();
} }
bool QWindowsContext::asyncExpose() const bool QWindowsContext::asyncExpose() const

View File

@ -157,6 +157,12 @@ QTouchDevice *QWindowsMouseHandler::ensureTouchDevice()
return m_touchDevice; return m_touchDevice;
} }
void QWindowsMouseHandler::clearEvents()
{
m_lastEventType = QEvent::None;
m_lastEventButton = Qt::NoButton;
}
Qt::MouseButtons QWindowsMouseHandler::queryMouseButtons() Qt::MouseButtons QWindowsMouseHandler::queryMouseButtons()
{ {
Qt::MouseButtons result = nullptr; Qt::MouseButtons result = nullptr;
@ -293,8 +299,6 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
Qt::MouseEventSource source = Qt::MouseEventNotSynthesized; Qt::MouseEventSource source = Qt::MouseEventNotSynthesized;
const MouseEvent mouseEvent = eventFromMsg(msg);
// Check for events synthesized from touch. Lower byte is touch index, 0 means pen. // Check for events synthesized from touch. Lower byte is touch index, 0 means pen.
static const bool passSynthesizedMouseEvents = static const bool passSynthesizedMouseEvents =
!(QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch); !(QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch);
@ -311,13 +315,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) { if (mouseEvent.type >= QEvent::NonClientAreaMouseMove && mouseEvent.type <= QEvent::NonClientAreaMouseButtonDblClick) {
const Qt::MouseButtons buttons = QWindowsMouseHandler::queryMouseButtons();
QWindowSystemInterface::handleFrameStrutMouseEvent(window, clientPosition, QWindowSystemInterface::handleFrameStrutMouseEvent(window, clientPosition,
globalPosition, buttons, globalPosition, buttons,
mouseEvent.button, mouseEvent.type, mouseEvent.button, mouseEvent.type,
QWindowsKeyMapper::queryKeyboardModifiers(), keyModifiers, source);
source);
return false; // Allow further event processing (dragging of windows). return false; // Allow further event processing (dragging of windows).
} }
@ -340,7 +371,6 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
} }
QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle()); 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, // 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, // we don't get WM_LBUTTONDOWN or WM_LBUTTONDBLCLK for the second click,
@ -467,8 +497,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
if (!discardEvent && mouseEvent.type != QEvent::None) { if (!discardEvent && mouseEvent.type != QEvent::None) {
QWindowSystemInterface::handleMouseEvent(window, winEventPosition, globalPosition, buttons, QWindowSystemInterface::handleMouseEvent(window, winEventPosition, globalPosition, buttons,
mouseEvent.button, mouseEvent.type, mouseEvent.button, mouseEvent.type,
QWindowsKeyMapper::queryKeyboardModifiers(), keyModifiers, source);
source);
} }
m_previousCaptureWindow = hasCapture ? window : nullptr; m_previousCaptureWindow = hasCapture ? window : nullptr;
// QTBUG-48117, force synchronous handling for the extra buttons so that WM_APPCOMMAND // 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/qpointer.h>
#include <QtCore/qhash.h> #include <QtCore/qhash.h>
#include <QtGui/qevent.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -72,13 +73,14 @@ public:
bool translateScrollEvent(QWindow *window, HWND hwnd, bool translateScrollEvent(QWindow *window, HWND hwnd,
MSG msg, LRESULT *result); MSG msg, LRESULT *result);
static inline Qt::MouseButtons keyStateToMouseButtons(int); static inline Qt::MouseButtons keyStateToMouseButtons(WPARAM);
static inline Qt::KeyboardModifiers keyStateToModifiers(int); static inline Qt::KeyboardModifiers keyStateToModifiers(int);
static inline int mouseButtonsToKeyState(Qt::MouseButtons); static inline int mouseButtonsToKeyState(Qt::MouseButtons);
static Qt::MouseButtons queryMouseButtons(); static Qt::MouseButtons queryMouseButtons();
QWindow *windowUnderMouse() const { return m_windowUnderMouse.data(); } QWindow *windowUnderMouse() const { return m_windowUnderMouse.data(); }
void clearWindowUnderMouse() { m_windowUnderMouse = 0; } void clearWindowUnderMouse() { m_windowUnderMouse = 0; }
void clearEvents();
private: private:
inline bool translateMouseWheelEvent(QWindow *window, HWND hwnd, inline bool translateMouseWheelEvent(QWindow *window, HWND hwnd,
@ -91,9 +93,11 @@ private:
QTouchDevice *m_touchDevice = nullptr; QTouchDevice *m_touchDevice = nullptr;
bool m_leftButtonDown = false; bool m_leftButtonDown = false;
QWindow *m_previousCaptureWindow = nullptr; 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); Qt::MouseButtons mb(Qt::NoButton);
if (wParam & MK_LBUTTON) if (wParam & MK_LBUTTON)

View File

@ -336,6 +336,12 @@ QTouchDevice *QWindowsPointerHandler::ensureTouchDevice()
return m_touchDevice; return m_touchDevice;
} }
void QWindowsPointerHandler::clearEvents()
{
m_lastEventType = QEvent::None;
m_lastEventButton = Qt::NoButton;
}
void QWindowsPointerHandler::handleCaptureRelease(QWindow *window, void QWindowsPointerHandler::handleCaptureRelease(QWindow *window,
QWindow *currentWindowUnderPointer, QWindow *currentWindowUnderPointer,
HWND hwnd, HWND hwnd,
@ -732,10 +738,35 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
} }
const MouseEvent mouseEvent = eventFromMsg(msg); 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) { if (mouseEvent.type >= QEvent::NonClientAreaMouseMove && mouseEvent.type <= QEvent::NonClientAreaMouseButtonDblClick) {
const Qt::MouseButtons nonclientButtons = queryMouseButtons(); QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, mouseButtons,
QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, nonclientButtons,
mouseEvent.button, mouseEvent.type, keyModifiers, source); mouseEvent.button, mouseEvent.type, keyModifiers, source);
return false; // Allow further event processing return false; // Allow further event processing
} }
@ -751,8 +782,6 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
return true; return true;
} }
const Qt::MouseButtons mouseButtons = mouseButtonsFromKeyState(msg.wParam);
handleCaptureRelease(window, currentWindowUnderPointer, hwnd, mouseEvent.type, mouseButtons); handleCaptureRelease(window, currentWindowUnderPointer, hwnd, mouseEvent.type, mouseButtons);
handleEnterLeave(window, currentWindowUnderPointer, globalPos); handleEnterLeave(window, currentWindowUnderPointer, globalPos);

View File

@ -46,7 +46,7 @@
#include <QtCore/qpointer.h> #include <QtCore/qpointer.h>
#include <QtCore/qscopedpointer.h> #include <QtCore/qscopedpointer.h>
#include <QtCore/qhash.h> #include <QtCore/qhash.h>
#include <qpa/qwindowsysteminterface.h> #include <QtGui/qevent.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -64,6 +64,7 @@ public:
QTouchDevice *ensureTouchDevice(); QTouchDevice *ensureTouchDevice();
QWindow *windowUnderMouse() const { return m_windowUnderPointer.data(); } QWindow *windowUnderMouse() const { return m_windowUnderPointer.data(); }
void clearWindowUnderMouse() { m_windowUnderPointer = nullptr; } void clearWindowUnderMouse() { m_windowUnderPointer = nullptr; }
void clearEvents();
private: private:
bool translateTouchEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vTouchInfo, unsigned int count); 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; QPointer<QWindow> m_currentWindow;
QWindow *m_previousCaptureWindow = nullptr; QWindow *m_previousCaptureWindow = nullptr;
bool m_needsEnterOnPointerUpdate = false; bool m_needsEnterOnPointerUpdate = false;
QEvent::Type m_lastEventType = QEvent::None;
Qt::MouseButton m_lastEventButton = Qt::NoButton;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -52,6 +52,7 @@
#include "qwindowsuiatableitemprovider.h" #include "qwindowsuiatableitemprovider.h"
#include "qwindowsuiagridprovider.h" #include "qwindowsuiagridprovider.h"
#include "qwindowsuiagriditemprovider.h" #include "qwindowsuiagriditemprovider.h"
#include "qwindowsuiawindowprovider.h"
#include "qwindowscombase.h" #include "qwindowscombase.h"
#include "qwindowscontext.h" #include "qwindowscontext.h"
#include "qwindowsuiautils.h" #include "qwindowsuiautils.h"
@ -263,6 +264,11 @@ HRESULT QWindowsUiaMainProvider::GetPatternProvider(PATTERNID idPattern, IUnknow
return UIA_E_ELEMENTNOTAVAILABLE; return UIA_E_ELEMENTNOTAVAILABLE;
switch (idPattern) { switch (idPattern) {
case UIA_WindowPatternId:
if (accessible->parent() && (accessible->parent()->role() == QAccessible::Application)) {
*pRetVal = new QWindowsUiaWindowProvider(id());
}
break;
case UIA_TextPatternId: case UIA_TextPatternId:
case UIA_TextPattern2Id: case UIA_TextPattern2Id:
// All text controls. // All text controls.
@ -352,8 +358,7 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR
if (!accessible) if (!accessible)
return UIA_E_ELEMENTNOTAVAILABLE; return UIA_E_ELEMENTNOTAVAILABLE;
bool clientTopLevel = (accessible->role() == QAccessible::Client) bool topLevelWindow = accessible->parent() && (accessible->parent()->role() == QAccessible::Application);
&& accessible->parent() && (accessible->parent()->role() == QAccessible::Application);
switch (idProp) { switch (idProp) {
case UIA_ProcessIdPropertyId: case UIA_ProcessIdPropertyId:
@ -379,7 +384,7 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR
setVariantString(QStringLiteral("Qt"), pRetVal); setVariantString(QStringLiteral("Qt"), pRetVal);
break; break;
case UIA_ControlTypePropertyId: case UIA_ControlTypePropertyId:
if (clientTopLevel) { if (topLevelWindow) {
// Reports a top-level widget as a window, instead of "custom". // Reports a top-level widget as a window, instead of "custom".
setVariantI4(UIA_WindowControlTypeId, pRetVal); setVariantI4(UIA_WindowControlTypeId, pRetVal);
} else { } else {
@ -391,10 +396,20 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR
setVariantString(accessible->text(QAccessible::Help), pRetVal); setVariantString(accessible->text(QAccessible::Help), pRetVal);
break; break;
case UIA_HasKeyboardFocusPropertyId: case UIA_HasKeyboardFocusPropertyId:
if (topLevelWindow) {
// Windows set the active state to true when they are focused
setVariantBool(accessible->state().active, pRetVal);
} else {
setVariantBool(accessible->state().focused, pRetVal); setVariantBool(accessible->state().focused, pRetVal);
}
break; break;
case UIA_IsKeyboardFocusablePropertyId: case UIA_IsKeyboardFocusablePropertyId:
if (topLevelWindow) {
// Windows should always be focusable
setVariantBool(true, pRetVal);
} else {
setVariantBool(accessible->state().focusable, pRetVal); setVariantBool(accessible->state().focusable, pRetVal);
}
break; break;
case UIA_IsOffscreenPropertyId: case UIA_IsOffscreenPropertyId:
setVariantBool(accessible->state().offscreen, pRetVal); setVariantBool(accessible->state().offscreen, pRetVal);
@ -424,7 +439,7 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR
break; break;
case UIA_NamePropertyId: { case UIA_NamePropertyId: {
QString name = accessible->text(QAccessible::Name); QString name = accessible->text(QAccessible::Name);
if (name.isEmpty() && clientTopLevel) if (name.isEmpty() && topLevelWindow)
name = QCoreApplication::applicationName(); name = QCoreApplication::applicationName();
setVariantString(name, pRetVal); setVariantString(name, pRetVal);
break; 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/qwindowsuiatableitemprovider.cpp \
$$PWD/qwindowsuiagridprovider.cpp \ $$PWD/qwindowsuiagridprovider.cpp \
$$PWD/qwindowsuiagriditemprovider.cpp \ $$PWD/qwindowsuiagriditemprovider.cpp \
$$PWD/qwindowsuiawindowprovider.cpp \
$$PWD/qwindowsuiautils.cpp $$PWD/qwindowsuiautils.cpp
HEADERS += \ HEADERS += \
@ -37,6 +38,7 @@ HEADERS += \
$$PWD/qwindowsuiatableitemprovider.h \ $$PWD/qwindowsuiatableitemprovider.h \
$$PWD/qwindowsuiagridprovider.h \ $$PWD/qwindowsuiagridprovider.h \
$$PWD/qwindowsuiagriditemprovider.h \ $$PWD/qwindowsuiagriditemprovider.h \
$$PWD/qwindowsuiawindowprovider.h \
$$PWD/qwindowsuiautils.h $$PWD/qwindowsuiautils.h
mingw: QMAKE_USE *= uuid mingw: QMAKE_USE *= uuid

View File

@ -44,6 +44,8 @@
#include <QtCore/qfunctions_winrt.h> #include <QtCore/qfunctions_winrt.h>
#include <QtGui/QPalette> #include <QtGui/QPalette>
#include <QtFontDatabaseSupport/private/qwinrtfontdatabase_p.h>
#include <wrl.h> #include <wrl.h>
#include <windows.ui.h> #include <windows.ui.h>
#include <windows.ui.viewmanagement.h> #include <windows.ui.viewmanagement.h>
@ -96,7 +98,13 @@ static IUISettings *uiSettings()
class QWinRTThemePrivate class QWinRTThemePrivate
{ {
public: public:
QWinRTThemePrivate()
: monospaceFont(QWinRTFontDatabase::familyForStyleHint(QFont::Monospace))
{
}
QPalette palette; QPalette palette;
QFont monospaceFont;
}; };
static inline QColor fromColor(const Color &color) static inline QColor fromColor(const Color &color)
@ -321,4 +329,14 @@ const QPalette *QWinRTTheme::palette(Palette type) const
return QPlatformTheme::palette(type); return QPlatformTheme::palette(type);
} }
const QFont *QWinRTTheme::font(QPlatformTheme::Font type) const
{
Q_D(const QWinRTTheme);
qCDebug(lcQpaTheme) << __FUNCTION__ << type;
if (type == QPlatformTheme::FixedFont)
return &d->monospaceFont;
return QPlatformTheme::font(type);
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -58,6 +58,7 @@ public:
QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const override; QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const override;
const QPalette *palette(Palette type = SystemPalette) const override; const QPalette *palette(Palette type = SystemPalette) const override;
const QFont *font(Font type = SystemFont) const override;
static QVariant styleHint(QPlatformIntegration::StyleHint hint); static QVariant styleHint(QPlatformIntegration::StyleHint hint);
QVariant themeHint(ThemeHint hint) const override; QVariant themeHint(ThemeHint hint) const override;

View File

@ -202,7 +202,7 @@ void QXcbDrag::startDrag()
if (connection()->mouseGrabber() == nullptr) if (connection()->mouseGrabber() == nullptr)
shapedPixmapWindow()->setMouseGrabEnabled(true); shapedPixmapWindow()->setMouseGrabEnabled(true);
auto nativePixelPos = QHighDpi::toNativePixels(QCursor::pos(), initiatorWindow); auto nativePixelPos = QHighDpi::toNativePixels(QCursor::pos(), initiatorWindow.data());
move(nativePixelPos, QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers()); move(nativePixelPos, QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
} }

View File

@ -150,6 +150,16 @@ static QWindow *qt_getWindow(const QWidget *widget)
QT_NAMESPACE_ALIAS_OBJC_CLASS(NotificationReceiver); QT_NAMESPACE_ALIAS_OBJC_CLASS(NotificationReceiver);
@implementation NotificationReceiver @implementation NotificationReceiver
{
QMacStylePrivate *privateStyle;
}
- (instancetype)initWithPrivateStyle:(QMacStylePrivate *)style
{
if (self = [super init])
privateStyle = style;
return self;
}
- (void)scrollBarStyleDidChange:(NSNotification *)notification - (void)scrollBarStyleDidChange:(NSNotification *)notification
{ {
@ -162,6 +172,23 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(NotificationReceiver);
for (const auto &o : QMacStylePrivate::scrollBars) for (const auto &o : QMacStylePrivate::scrollBars)
QCoreApplication::sendEvent(o, &event); QCoreApplication::sendEvent(o, &event);
} }
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary<NSKeyValueChangeKey, id> *)change context:(void *)context
{
Q_UNUSED(keyPath);
Q_UNUSED(object);
Q_UNUSED(change);
Q_UNUSED(context);
Q_ASSERT([keyPath isEqualToString:@"effectiveAppearance"]);
Q_ASSERT(object == NSApp);
for (NSView *b : privateStyle->cocoaControls)
[b release];
privateStyle->cocoaControls.clear();
}
@end @end
@interface QT_MANGLE_NAMESPACE(QIndeterminateProgressIndicator) : NSProgressIndicator @interface QT_MANGLE_NAMESPACE(QIndeterminateProgressIndicator) : NSProgressIndicator
@ -2068,11 +2095,17 @@ QMacStyle::QMacStyle()
Q_D(QMacStyle); Q_D(QMacStyle);
QMacAutoReleasePool pool; QMacAutoReleasePool pool;
d->receiver = [[NotificationReceiver alloc] init]; d->receiver = [[NotificationReceiver alloc] initWithPrivateStyle:d];
[[NSNotificationCenter defaultCenter] addObserver:d->receiver [[NSNotificationCenter defaultCenter] addObserver:d->receiver
selector:@selector(scrollBarStyleDidChange:) selector:@selector(scrollBarStyleDidChange:)
name:NSPreferredScrollerStyleDidChangeNotification name:NSPreferredScrollerStyleDidChangeNotification
object:nil]; object:nil];
#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14)
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave) {
[NSApplication.sharedApplication addObserver:d->receiver forKeyPath:@"effectiveAppearance"
options:NSKeyValueObservingOptionNew context:nullptr];
}
#endif
} }
QMacStyle::~QMacStyle() QMacStyle::~QMacStyle()
@ -2081,6 +2114,10 @@ QMacStyle::~QMacStyle()
QMacAutoReleasePool pool; QMacAutoReleasePool pool;
[[NSNotificationCenter defaultCenter] removeObserver:d->receiver]; [[NSNotificationCenter defaultCenter] removeObserver:d->receiver];
#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14)
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave)
[NSApplication.sharedApplication removeObserver:d->receiver forKeyPath:@"effectiveAppearance"];
#endif
[d->receiver release]; [d->receiver release];
} }
@ -6129,8 +6166,9 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
switch (ct) { switch (ct) {
#if QT_CONFIG(spinbox) #if QT_CONFIG(spinbox)
case CT_SpinBox: case CT_SpinBox:
if (qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) { if (const QStyleOptionSpinBox *vopt = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
const int buttonWidth = 20; // FIXME Use subControlRect() const bool hasButtons = (vopt->buttonSymbols != QAbstractSpinBox::NoButtons);
const int buttonWidth = hasButtons ? proxy()->subControlRect(CC_SpinBox, vopt, SC_SpinBoxUp, widget).width() : 0;
sz += QSize(buttonWidth, 0); sz += QSize(buttonWidth, 0);
} }
break; break;

View File

@ -1864,6 +1864,9 @@ void QColorDialogPrivate::_q_addCustom()
void QColorDialogPrivate::retranslateStrings() void QColorDialogPrivate::retranslateStrings()
{ {
if (nativeDialogInUse)
return;
if (!smallDisplay) { if (!smallDisplay) {
lblBasicColors->setText(QColorDialog::tr("&Basic colors")); lblBasicColors->setText(QColorDialog::tr("&Basic colors"));
lblCustomColors->setText(QColorDialog::tr("&Custom 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(); return QRectF();
if (d->flags & ItemIsSelectable) { if (d->flags & ItemIsSelectable) {
qreal pw = 1.0; 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 { } else {
return QRectF(d->offset, d->pixmap.size() / d->pixmap.devicePixelRatio()); return QRectF(d->offset, QSizeF(d->pixmap.size()) / d->pixmap.devicePixelRatio());
} }
} }

View File

@ -1734,6 +1734,7 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option,
} }
// draw background for the branch (selection + alternate row) // draw background for the branch (selection + alternate row)
opt.rect = branches; opt.rect = branches;
if (style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, &opt, this))
style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, this); style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, this);
// draw background of the item (only alternate row). rest of the background // draw background of the item (only alternate row). rest of the background

View File

@ -2578,14 +2578,15 @@ void QWidgetPrivate::createWinId()
/*! /*!
\internal \internal
Ensures that the widget is set on the screen point is on. This is handy getting a correct 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); Q_Q(QWidget);
if (!q->isWindow()) if (!q->isWindow())
return; return false;
// Find the screen for pos and make the widget undertand it is on that screen. // Find the screen for pos and make the widget undertand it is on that screen.
const QScreen *currentScreen = windowHandle() ? windowHandle()->screen() : nullptr; const QScreen *currentScreen = windowHandle() ? windowHandle()->screen() : nullptr;
QScreen *actualScreen = QGuiApplication::screenAt(pos); QScreen *actualScreen = QGuiApplication::screenAt(pos);
@ -2594,7 +2595,9 @@ void QWidgetPrivate::setScreenForPoint(const QPoint &pos)
createWinId(); createWinId();
if (windowHandle()) if (windowHandle())
windowHandle()->setScreen(actualScreen); windowHandle()->setScreen(actualScreen);
return true;
} }
return false;
} }
/*! /*!

View File

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

View File

@ -5029,7 +5029,8 @@ QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
case CT_SpinBox: case CT_SpinBox:
if (const QStyleOptionSpinBox *vopt = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) { if (const QStyleOptionSpinBox *vopt = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
// Add button + frame widths // Add button + frame widths
const int buttonWidth = (vopt->subControls & (QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown)) != 0 ? 20 : 0; const bool hasButtons = (vopt->buttonSymbols != QAbstractSpinBox::NoButtons);
const int buttonWidth = hasButtons ? proxy()->subControlRect(CC_SpinBox, vopt, SC_SpinBoxUp, widget).width() : 0;
const int fw = vopt->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, vopt, widget) : 0; const int fw = vopt->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, vopt, widget) : 0;
sz += QSize(buttonWidth + 2*fw, 2*fw); sz += QSize(buttonWidth + 2*fw, 2*fw);
} }

View File

@ -4992,17 +4992,19 @@ QSize QStyleSheetStyle::sizeFromContents(ContentsType ct, const QStyleOption *op
switch (ct) { switch (ct) {
#if QT_CONFIG(spinbox) #if QT_CONFIG(spinbox)
case CT_SpinBox: // ### hopelessly broken QAbstractSpinBox (part 1) case CT_SpinBox:
if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) { if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
if (spinbox->buttonSymbols != QAbstractSpinBox::NoButtons) {
// Add some space for the up/down buttons // Add some space for the up/down buttons
QRenderRule subRule = renderRule(w, opt, PseudoElement_SpinBoxUpButton); QRenderRule subRule = renderRule(w, opt, PseudoElement_SpinBoxUpButton);
if (subRule.hasDrawable()) { if (subRule.hasDrawable()) {
QRect r = positionRect(w, rule, subRule, PseudoElement_SpinBoxUpButton, QRect r = positionRect(w, rule, subRule, PseudoElement_SpinBoxUpButton,
opt->rect, opt->direction); opt->rect, opt->direction);
sz += QSize(r.width(), 0); sz.rwidth() += r.width();
} else { } else {
QSize defaultUpSize = defaultSize(w, subRule.size(), spinbox->rect, PseudoElement_SpinBoxUpButton); QSize defaultUpSize = defaultSize(w, subRule.size(), spinbox->rect, PseudoElement_SpinBoxUpButton);
sz += QSize(defaultUpSize.width(), 0); sz.rwidth() += defaultUpSize.width();
}
} }
if (rule.hasBox() || rule.hasBorder() || !rule.hasNativeBorder()) if (rule.hasBox() || rule.hasBorder() || !rule.hasNativeBorder())
sz = rule.boxSize(sz); sz = rule.boxSize(sz);
@ -5503,8 +5505,12 @@ QRect QStyleSheetStyle::subControlRect(ComplexControl cc, const QStyleOptionComp
: Qt::Alignment(Qt::AlignRight); : Qt::Alignment(Qt::AlignRight);
downAlign = resolveAlignment(opt->direction, downAlign); downAlign = resolveAlignment(opt->direction, downAlign);
int upSize = subControlRect(CC_SpinBox, opt, SC_SpinBoxUp, w).width(); const bool hasButtons = (spin->buttonSymbols != QAbstractSpinBox::NoButtons);
int downSize = subControlRect(CC_SpinBox, opt, SC_SpinBoxDown, w).width(); const int upSize = hasButtons
? subControlRect(CC_SpinBox, opt, SC_SpinBoxUp, w).width() : 0;
const int downSize = hasButtons
? subControlRect(CC_SpinBox, opt, SC_SpinBoxDown, w).width() : 0;
int widestL = qMax((upAlign & Qt::AlignLeft) ? upSize : 0, int widestL = qMax((upAlign & Qt::AlignLeft) ? upSize : 0,
(downAlign & Qt::AlignLeft) ? downSize : 0); (downAlign & Qt::AlignLeft) ? downSize : 0);
int widestR = qMax((upAlign & Qt::AlignRight) ? upSize : 0, int widestR = qMax((upAlign & Qt::AlignRight) ? upSize : 0,

View File

@ -976,18 +976,48 @@ void QCompleterPrivate::showPopup(const QRect& rect)
popup->show(); 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) void QCompleterPrivate::_q_fileSystemModelDirectoryLoaded(const QString &path)
{ {
Q_Q(QCompleter); Q_Q(QCompleter);
// Slot called when QFileSystemModel has finished loading. // Slot called when QFileSystemModel has finished loading.
// If we hide the popup because there was no match because the model was not loaded yet, // 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 // we re-start the completion when we get the results (unless triggered by
if (hiddenBecauseNoMatch // something else, see QTBUG-14292).
&& prefix.startsWith(path) && prefix != (path + QLatin1Char('/')) if (hiddenBecauseNoMatch && widget) {
&& widget) { if (auto model = qobject_cast<const QFileSystemModel *>(proxy->sourceModel())) {
if (completeOnLoaded(model, prefix, path, cs))
q->complete(); q->complete();
} }
} }
}
#else // QT_CONFIG(filesystemmodel)
void QCompleterPrivate::_q_fileSystemModelDirectoryLoaded(const QString &) {}
#endif
/*! /*!
Constructs a completer object with the given \a parent. Constructs a completer object with the given \a parent.

View File

@ -212,6 +212,7 @@ void QAbstractSpinBox::setButtonSymbols(ButtonSymbols buttonSymbols)
if (d->buttonSymbols != buttonSymbols) { if (d->buttonSymbols != buttonSymbols) {
d->buttonSymbols = buttonSymbols; d->buttonSymbols = buttonSymbols;
d->updateEditFieldGeometry(); d->updateEditFieldGeometry();
updateGeometry();
update(); update();
} }
} }

View File

@ -73,6 +73,7 @@
#endif #endif
#include "qpushbutton.h" #include "qpushbutton.h"
#include "qtooltip.h" #include "qtooltip.h"
#include <qwindow.h>
#include <private/qpushbutton_p.h> #include <private/qpushbutton_p.h>
#include <private/qaction_p.h> #include <private/qaction_p.h>
#include <private/qguiapplication_p.h> #include <private/qguiapplication_p.h>
@ -1485,6 +1486,8 @@ void QMenuPrivate::_q_platformMenuAboutToShow()
{ {
Q_Q(QMenu); Q_Q(QMenu);
emit q->aboutToShow();
#ifdef Q_OS_OSX #ifdef Q_OS_OSX
if (platformMenu) { if (platformMenu) {
const auto actions = q->actions(); const auto actions = q->actions();
@ -1498,8 +1501,6 @@ void QMenuPrivate::_q_platformMenuAboutToShow()
} }
} }
#endif #endif
emit q->aboutToShow();
} }
bool QMenuPrivate::hasMouseMoved(const QPoint &globalPos) bool QMenuPrivate::hasMouseMoved(const QPoint &globalPos)
@ -2328,8 +2329,10 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
d->motions = 0; d->motions = 0;
d->doChildEffects = true; d->doChildEffects = true;
d->updateLayoutDirection(); 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(); const bool contextMenu = d->isContextMenu();
if (d->lastContextMenu != contextMenu) { if (d->lastContextMenu != contextMenu) {

View File

@ -121,7 +121,7 @@ bool QWidgetResizeHandler::eventFilter(QObject *o, QEvent *ee)
break; break;
const QRect widgetRect = widget->rect().marginsAdded(QMargins(range, range, range, range)); const QRect widgetRect = widget->rect().marginsAdded(QMargins(range, range, range, range));
const QPoint cursorPoint = widget->mapFromGlobal(e->globalPos()); const QPoint cursorPoint = widget->mapFromGlobal(e->globalPos());
if (!widgetRect.contains(cursorPoint) || mode == Nowhere) if (!widgetRect.contains(cursorPoint))
return false; return false;
if (e->button() == Qt::LeftButton) { if (e->button() == Qt::LeftButton) {
#if 0 // Used to be included in Qt4 for Q_WS_X11 #if 0 // Used to be included in Qt4 for Q_WS_X11

View File

@ -317,23 +317,26 @@ private:
if (quote) if (quote)
break; break;
commandLine[i] = '\0'; commandLine[i] = '\0';
if (args.last()[0] != '\0') if (!args.isEmpty() && args.last() && args.last()[0] != '\0')
args.append(commandLine.data() + i + 1); args.append(commandLine.data() + i + 1);
// fall through // fall through
default: default:
if (args.last()[0] == '\0') if (!args.isEmpty() && args.last() && args.last()[0] == '\0')
args.last() = commandLine.data() + i; args.last() = commandLine.data() + i;
escape = false; // only quotes are escaped escape = false; // only quotes are escaped
break; 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); args.remove(1);
bool develMode = false; bool develMode = false;
bool debugWait = false; bool debugWait = false;
for (int i = args.count() - 1; i >= 0; --i) { for (int i = args.count() - 1; i >= 0; --i) {
if (!args.at(i))
continue;
const char *arg = args.at(i); const char *arg = args.at(i);
if (strcmp(arg, "-qdevel") == 0) { if (strcmp(arg, "-qdevel") == 0) {
develMode = true; develMode = true;

View File

@ -30,8 +30,10 @@
\title Qt XML \title Qt XML
\brief The Qt XML module provides C++ implementations of the SAX and DOM standards for 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 Note that the module will not receive additional features anymore. For reading or writing XML
the QXmlStreamReader and QXmlStreamWriter classes in Qt Core instead. 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 To include the definitions of the module's classes, use the
following directive: following directive:

View File

@ -33,8 +33,10 @@
\brief The Qt XML module provides C++ implementations of the SAX and DOM standards for 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 Note that the module will not receive additional features anymore. For reading or writing XML
the \l{QXmlStreamReader} and \l{QXmlStreamWriter} classes in \l{Qt Core} instead. 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 To include the definitions of the module's classes, use the
following directive: following directive:

View File

@ -174,6 +174,8 @@ void tst_qfloat16::qNan()
QVERIFY(qIsInf(-inf)); QVERIFY(qIsInf(-inf));
QVERIFY(qIsInf(2.f*inf)); QVERIFY(qIsInf(2.f*inf));
QVERIFY(qIsInf(inf*2.f)); QVERIFY(qIsInf(inf*2.f));
// QTBUG-75812: QEMU's over-optimized arm64 flakily fails 1/inf == 0 :-(
if (qfloat16(9.785e-4f) == qfloat16(9.794e-4f))
QCOMPARE(qfloat16(1.f/inf), qfloat16(0.f)); QCOMPARE(qfloat16(1.f/inf), qfloat16(0.f));
#ifdef Q_CC_INTEL #ifdef Q_CC_INTEL
QEXPECT_FAIL("", "ICC optimizes zero * anything to zero", Continue); QEXPECT_FAIL("", "ICC optimizes zero * anything to zero", Continue);

View File

@ -655,6 +655,8 @@ void tst_QFileInfo::canonicalFilePath()
QVERIFY(tempFile.open(QFile::WriteOnly)); QVERIFY(tempFile.open(QFile::WriteOnly));
QFileInfo fi(tempFile.fileName()); QFileInfo fi(tempFile.fileName());
QCOMPARE(fi.canonicalFilePath(), QDir::currentPath() + "/" + fileName); QCOMPARE(fi.canonicalFilePath(), QDir::currentPath() + "/" + fileName);
fi = QFileInfo(tempFile.fileName() + QString::fromLatin1("/"));
QCOMPARE(fi.canonicalFilePath(), QString::fromLatin1(""));
tempFile.remove(); tempFile.remove();
// This used to crash on Mac, verify that it doesn't anymore. // This used to crash on Mac, verify that it doesn't anymore.

View File

@ -1203,7 +1203,7 @@ void tst_QStringApiSymmetry::trimmed_data()
for (int len = 0; len < latin1Whitespace.size(); ++len) { for (int len = 0; len < latin1Whitespace.size(); ++len) {
for (int pos = 0; pos < latin1Whitespace.size() - len; ++pos) { for (int pos = 0; pos < latin1Whitespace.size() - len; ++pos) {
const QString unicode = latin1Whitespace.mid(pos, len) + str + latin1Whitespace.mid(pos, len); const QString unicode = latin1Whitespace.mid(pos, len) + str + latin1Whitespace.mid(pos, len);
const QScopedPointer<const char> escaped(QTest::toString(unicode)); const QScopedArrayPointer<const char> escaped(QTest::toString(unicode));
QTest::addRow("%s", escaped.data()) << unicode << QStringRef(&str); QTest::addRow("%s", escaped.data()) << unicode << QStringRef(&str);
} }
} }

View File

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

View File

@ -45,10 +45,6 @@
# include <QtCore/qt_windows.h> # include <QtCore/qt_windows.h>
#endif #endif
// For QSignalSpy slot connections.
Q_DECLARE_METATYPE(Qt::ScreenOrientation)
Q_DECLARE_METATYPE(QWindow::Visibility)
static bool isPlatformWinRT() static bool isPlatformWinRT()
{ {
static const bool isWinRT = !QGuiApplication::platformName().compare(QLatin1String("winrt"), Qt::CaseInsensitive); 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"); QVERIFY2(c.children().contains(&d), "Parent should have child in list of children");
a.create(); a.create();
b.setParent(0); b.setParent(nullptr);
QVERIFY2(!b.handle(), "Making window top level shouild not automatically create it"); QVERIFY2(!b.handle(), "Making window top level shouild not automatically create it");
QWindow e; QWindow e;
@ -228,7 +224,7 @@ void tst_QWindow::setVisible()
f.setVisible(true); f.setVisible(true);
QVERIFY(!f.handle()); QVERIFY(!f.handle());
QVERIFY(!e.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"); QVERIFY2(f.handle(), "Making a visible but not created child window top level should create it");
QVERIFY(QTest::qWaitForWindowExposed(&f)); QVERIFY(QTest::qWaitForWindowExposed(&f));
@ -304,7 +300,7 @@ public:
m_framePositionsOnMove.clear(); m_framePositionsOnMove.clear();
} }
bool event(QEvent *event) bool event(QEvent *event) override
{ {
m_received[event->type()]++; m_received[event->type()]++;
m_order << event->type(); m_order << event->type();
@ -323,6 +319,7 @@ public:
case QEvent::WindowStateChange: case QEvent::WindowStateChange:
lastReceivedWindowState = windowState(); lastReceivedWindowState = windowState();
break;
default: default:
break; break;
@ -363,7 +360,7 @@ private:
class ColoredWindow : public QRasterWindow { class ColoredWindow : public QRasterWindow {
public: 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 void paintEvent(QPaintEvent *) override
{ {
QPainter p(this); QPainter p(this);
@ -381,6 +378,7 @@ void tst_QWindow::eventOrderOnShow()
QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize); QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize);
Window window; Window window;
window.setTitle(QLatin1String(QTest::currentTestFunction()));
window.setGeometry(geometry); window.setGeometry(geometry);
window.show(); window.show();
QCoreApplication::processEvents(); QCoreApplication::processEvents();
@ -440,12 +438,12 @@ void tst_QWindow::exposeEventOnShrink_QTBUG54040()
void tst_QWindow::positioning_data() 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 #ifdef Q_OS_MACOS
QTest::newRow("fake") << int(Qt::Window | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); QTest::newRow("fake") << (Qt::Window | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
#endif #endif
} }
@ -500,8 +498,8 @@ void tst_QWindow::positioning()
// events, so set the width to suitably large value to avoid those. // events, so set the width to suitably large value to avoid those.
const QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize); const QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize);
QFETCH(int, windowflags); QFETCH(Qt::WindowFlags, windowflags);
Window window((Qt::WindowFlags)windowflags); Window window(windowflags);
window.setGeometry(QRect(m_availableTopLeft + QPoint(20, 20), m_testWindowSize)); 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. window.setFramePosition(m_availableTopLeft + QPoint(40, 40)); // Move window around before show, size must not change.
QCOMPARE(window.geometry().size(), m_testWindowSize); QCOMPARE(window.geometry().size(), m_testWindowSize);
@ -628,15 +626,13 @@ void tst_QWindow::childWindowPositioning()
QFETCH(bool, showInsteadOfCreate); QFETCH(bool, showInsteadOfCreate);
QWindow* windows[] = { &topLevelWindowFirst, &childWindowAfter, &childWindowFirst, &topLevelWindowAfter, 0 }; QWindow *windows[] = {&topLevelWindowFirst, &childWindowAfter, &childWindowFirst, &topLevelWindowAfter};
for (int i = 0; windows[i]; ++i) { for (QWindow *window : windows) {
QWindow *window = windows[i]; if (showInsteadOfCreate)
if (showInsteadOfCreate) {
window->showNormal(); window->showNormal();
} else { else
window->create(); window->create();
} }
}
if (showInsteadOfCreate) { if (showInsteadOfCreate) {
QVERIFY(QTest::qWaitForWindowExposed(&topLevelWindowFirst)); QVERIFY(QTest::qWaitForWindowExposed(&topLevelWindowFirst));
@ -712,7 +708,7 @@ void tst_QWindow::stateChange()
// explicitly use non-fullscreen show. show() can be fullscreen on some platforms // explicitly use non-fullscreen show. show() can be fullscreen on some platforms
window.showNormal(); window.showNormal();
QVERIFY(QTest::qWaitForWindowExposed(&window)); QVERIFY(QTest::qWaitForWindowExposed(&window));
foreach (Qt::WindowState state, stateSequence) { for (Qt::WindowState state : qAsConst(stateSequence)) {
window.setWindowState(state); window.setWindowState(state);
QCoreApplication::processEvents(); QCoreApplication::processEvents();
} }
@ -726,15 +722,9 @@ class PlatformWindowFilter : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
PlatformWindowFilter(QObject *parent = 0) explicit PlatformWindowFilter(Window *window) : m_window(window) {}
: QObject(parent)
, m_window(nullptr)
, m_alwaysExisted(true)
{}
void setWindow(Window *window) { m_window = window; } bool eventFilter(QObject *o, QEvent *e) override
bool eventFilter(QObject *o, QEvent *e)
{ {
// Check that the platform surface events are delivered synchronously. // Check that the platform surface events are delivered synchronously.
// If they are, the native platform surface should always exist when we // If they are, the native platform surface should always exist when we
@ -749,7 +739,7 @@ public:
private: private:
Window *m_window; Window *m_window;
bool m_alwaysExisted; bool m_alwaysExisted = true;
}; };
void tst_QWindow::platformSurface() void tst_QWindow::platformSurface()
@ -757,8 +747,7 @@ void tst_QWindow::platformSurface()
QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize); QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize);
Window window; Window window;
PlatformWindowFilter filter; PlatformWindowFilter filter(&window);
filter.setWindow(&window);
window.installEventFilter(&filter); window.installEventFilter(&filter);
window.setGeometry(geometry); window.setGeometry(geometry);
@ -784,6 +773,7 @@ void tst_QWindow::isExposed()
QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize); QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize);
Window window; Window window;
window.setTitle(QLatin1String(QTest::currentTestFunction()));
window.setGeometry(geometry); window.setGeometry(geometry);
QCOMPARE(window.geometry(), geometry); QCOMPARE(window.geometry(), geometry);
window.show(); window.show();
@ -818,6 +808,7 @@ void tst_QWindow::isActive()
QSKIP("QWindow::requestActivate() is not supported."); QSKIP("QWindow::requestActivate() is not supported.");
Window window; Window window;
window.setTitle(QLatin1String(QTest::currentTestFunction()));
// Some platforms enforce minimum widths for windows, which can cause extra resize // Some platforms enforce minimum widths for windows, which can cause extra resize
// events, so set the width to suitably large value to avoid those. // events, so set the width to suitably large value to avoid those.
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize)); window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
@ -916,13 +907,16 @@ void tst_QWindow::isActive()
class InputTestWindow : public ColoredWindow class InputTestWindow : public ColoredWindow
{ {
public: public:
void keyPressEvent(QKeyEvent *event) { void keyPressEvent(QKeyEvent *event) override
{
keyPressCode = event->key(); keyPressCode = event->key();
} }
void keyReleaseEvent(QKeyEvent *event) { void keyReleaseEvent(QKeyEvent *event) override
{
keyReleaseCode = event->key(); keyReleaseCode = event->key();
} }
void mousePressEvent(QMouseEvent *event) { void mousePressEvent(QMouseEvent *event) override
{
if (ignoreMouse) { if (ignoreMouse) {
event->ignore(); event->ignore();
} else { } else {
@ -935,7 +929,8 @@ public:
QCoreApplication::processEvents(); QCoreApplication::processEvents();
} }
} }
void mouseReleaseEvent(QMouseEvent *event) { void mouseReleaseEvent(QMouseEvent *event) override
{
if (ignoreMouse) { if (ignoreMouse) {
event->ignore(); event->ignore();
} else { } else {
@ -944,7 +939,8 @@ public:
mouseReleaseButton = event->button(); mouseReleaseButton = event->button();
} }
} }
void mouseMoveEvent(QMouseEvent *event) { void mouseMoveEvent(QMouseEvent *event) override
{
buttonStateInGeneratedMove = event->buttons(); buttonStateInGeneratedMove = event->buttons();
if (ignoreMouse) { if (ignoreMouse) {
event->ignore(); event->ignore();
@ -954,7 +950,8 @@ public:
mouseMoveScreenPos = event->screenPos(); mouseMoveScreenPos = event->screenPos();
} }
} }
void mouseDoubleClickEvent(QMouseEvent *event) { void mouseDoubleClickEvent(QMouseEvent *event) override
{
if (ignoreMouse) { if (ignoreMouse) {
event->ignore(); event->ignore();
} else { } else {
@ -962,7 +959,8 @@ public:
mouseSequenceSignature += 'd'; mouseSequenceSignature += 'd';
} }
} }
void touchEvent(QTouchEvent *event) { void touchEvent(QTouchEvent *event) override
{
if (ignoreTouch) { if (ignoreTouch) {
event->ignore(); event->ignore();
return; return;
@ -987,7 +985,8 @@ public:
} }
} }
} }
bool event(QEvent *e) { bool event(QEvent *e) override
{
switch (e->type()) { switch (e->type()) {
case QEvent::Enter: case QEvent::Enter:
++enterEventCount; ++enterEventCount;
@ -998,37 +997,31 @@ public:
default: default:
break; break;
} }
return QWindow::event(e); return ColoredWindow::event(e);
} }
void resetCounters() { void resetCounters()
{
mousePressedCount = mouseReleasedCount = mouseMovedCount = mouseDoubleClickedCount = 0; mousePressedCount = mouseReleasedCount = mouseMovedCount = mouseDoubleClickedCount = 0;
mouseSequenceSignature = QString(); mouseSequenceSignature.clear();
touchPressedCount = touchReleasedCount = touchMovedCount = 0; touchPressedCount = touchReleasedCount = touchMovedCount = 0;
enterEventCount = leaveEventCount = 0; enterEventCount = leaveEventCount = 0;
} }
explicit InputTestWindow(const QColor &color = Qt::white, QWindow *parent = nullptr) explicit InputTestWindow(const QColor &color = Qt::white, QWindow *parent = nullptr)
: ColoredWindow(color, parent) : ColoredWindow(color, parent) {}
{
keyPressCode = keyReleaseCode = 0;
mousePressButton = mouseReleaseButton = mouseMoveButton = 0;
ignoreMouse = ignoreTouch = false;
spinLoopWhenPressed = false;
resetCounters();
}
int keyPressCode, keyReleaseCode; int keyPressCode = 0, keyReleaseCode = 0;
int mousePressButton, mouseReleaseButton, mouseMoveButton; int mousePressButton = 0, mouseReleaseButton = 0, mouseMoveButton = 0;
int mousePressedCount, mouseReleasedCount, mouseMovedCount, mouseDoubleClickedCount; int mousePressedCount = 0, mouseReleasedCount = 0, mouseMovedCount = 0, mouseDoubleClickedCount = 0;
QString mouseSequenceSignature; QString mouseSequenceSignature;
QPointF mousePressScreenPos, mouseMoveScreenPos, mousePressLocalPos; QPointF mousePressScreenPos, mouseMoveScreenPos, mousePressLocalPos;
int touchPressedCount, touchReleasedCount, touchMovedCount; int touchPressedCount = 0, touchReleasedCount = 0, touchMovedCount = 0;
QEvent::Type touchEventType; QEvent::Type touchEventType = QEvent::None;
int enterEventCount, leaveEventCount; int enterEventCount = 0, leaveEventCount = 0;
bool ignoreMouse, ignoreTouch; bool ignoreMouse = false, ignoreTouch = false;
bool spinLoopWhenPressed; bool spinLoopWhenPressed = false;
Qt::MouseButtons buttonStateInGeneratedMove; Qt::MouseButtons buttonStateInGeneratedMove;
}; };
@ -1073,15 +1066,15 @@ void tst_QWindow::testInputEvents()
window.mousePressButton = window.mouseReleaseButton = 0; window.mousePressButton = window.mouseReleaseButton = 0;
const QPointF nonWindowGlobal(window.geometry().topRight() + QPoint(200, 50)); // not inside the window const QPointF nonWindowGlobal(window.geometry().topRight() + QPoint(200, 50)); // not inside the window
const QPointF deviceNonWindowGlobal = QHighDpi::toNativePixels(nonWindowGlobal, window.screen()); const QPointF deviceNonWindowGlobal = QHighDpi::toNativePixels(nonWindowGlobal, window.screen());
QWindowSystemInterface::handleMouseEvent(0, deviceNonWindowGlobal, deviceNonWindowGlobal, Qt::LeftButton); QWindowSystemInterface::handleMouseEvent(nullptr, deviceNonWindowGlobal, deviceNonWindowGlobal, Qt::LeftButton);
QWindowSystemInterface::handleMouseEvent(0, deviceNonWindowGlobal, deviceNonWindowGlobal, Qt::NoButton); QWindowSystemInterface::handleMouseEvent(nullptr, deviceNonWindowGlobal, deviceNonWindowGlobal, Qt::NoButton);
QCoreApplication::processEvents(); QCoreApplication::processEvents();
QCOMPARE(window.mousePressButton, 0); QCOMPARE(window.mousePressButton, 0);
QCOMPARE(window.mouseReleaseButton, 0); QCOMPARE(window.mouseReleaseButton, 0);
const QPointF windowGlobal = window.mapToGlobal(local.toPoint()); const QPointF windowGlobal = window.mapToGlobal(local.toPoint());
const QPointF deviceWindowGlobal = QHighDpi::toNativePixels(windowGlobal, window.screen()); const QPointF deviceWindowGlobal = QHighDpi::toNativePixels(windowGlobal, window.screen());
QWindowSystemInterface::handleMouseEvent(0, deviceWindowGlobal, deviceWindowGlobal, Qt::LeftButton); QWindowSystemInterface::handleMouseEvent(nullptr, deviceWindowGlobal, deviceWindowGlobal, Qt::LeftButton);
QWindowSystemInterface::handleMouseEvent(0, deviceWindowGlobal, deviceWindowGlobal, Qt::NoButton); QWindowSystemInterface::handleMouseEvent(nullptr, deviceWindowGlobal, deviceWindowGlobal, Qt::NoButton);
QCoreApplication::processEvents(); QCoreApplication::processEvents();
QCOMPARE(window.mousePressButton, int(Qt::LeftButton)); QCOMPARE(window.mousePressButton, int(Qt::LeftButton));
QCOMPARE(window.mouseReleaseButton, int(Qt::LeftButton)); QCOMPARE(window.mouseReleaseButton, int(Qt::LeftButton));
@ -1092,6 +1085,7 @@ void tst_QWindow::testInputEvents()
void tst_QWindow::touchToMouseTranslation() void tst_QWindow::touchToMouseTranslation()
{ {
InputTestWindow window; InputTestWindow window;
window.setTitle(QLatin1String(QTest::currentTestFunction()));
window.ignoreTouch = true; window.ignoreTouch = true;
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize)); window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
window.show(); window.show();
@ -1145,7 +1139,7 @@ void tst_QWindow::touchToMouseTranslation()
QTRY_COMPARE(window.mousePressButton, 0); QTRY_COMPARE(window.mousePressButton, 0);
QTRY_COMPARE(window.mouseReleaseButton, 0); QTRY_COMPARE(window.mouseReleaseButton, 0);
qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, false); QCoreApplication::setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, false);
window.ignoreTouch = true; window.ignoreTouch = true;
points[0].state = Qt::TouchPointPressed; points[0].state = Qt::TouchPointPressed;
@ -1156,7 +1150,7 @@ void tst_QWindow::touchToMouseTranslation()
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points); QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
QCoreApplication::processEvents(); QCoreApplication::processEvents();
qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true); QCoreApplication::setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true);
// mouse event synthesizing disabled // mouse event synthesizing disabled
QTRY_COMPARE(window.mousePressButton, 0); QTRY_COMPARE(window.mousePressButton, 0);
@ -1166,6 +1160,7 @@ void tst_QWindow::touchToMouseTranslation()
void tst_QWindow::touchToMouseTranslationForDevices() void tst_QWindow::touchToMouseTranslationForDevices()
{ {
InputTestWindow window; InputTestWindow window;
window.setTitle(QLatin1String(QTest::currentTestFunction()));
window.ignoreTouch = true; window.ignoreTouch = true;
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize)); window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
window.show(); window.show();
@ -1194,9 +1189,10 @@ void tst_QWindow::touchToMouseTranslationForDevices()
void tst_QWindow::mouseToTouchTranslation() void tst_QWindow::mouseToTouchTranslation()
{ {
qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true); QCoreApplication::setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true);
InputTestWindow window; InputTestWindow window;
window.setTitle(QLatin1String(QTest::currentTestFunction()));
window.ignoreMouse = true; window.ignoreMouse = true;
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize)); window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
window.show(); window.show();
@ -1206,12 +1202,12 @@ void tst_QWindow::mouseToTouchTranslation()
QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::NoButton); QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::NoButton);
QCoreApplication::processEvents(); QCoreApplication::processEvents();
qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, false); QCoreApplication::setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, false);
QTRY_COMPARE(window.touchPressedCount, 1); QTRY_COMPARE(window.touchPressedCount, 1);
QTRY_COMPARE(window.touchReleasedCount, 1); QTRY_COMPARE(window.touchReleasedCount, 1);
qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true); QCoreApplication::setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true);
window.ignoreMouse = false; window.ignoreMouse = false;
@ -1219,7 +1215,7 @@ void tst_QWindow::mouseToTouchTranslation()
QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::NoButton); QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::NoButton);
QCoreApplication::processEvents(); 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 // no new touch events should be generated since the input window handles the mouse events
QTRY_COMPARE(window.touchPressedCount, 1); QTRY_COMPARE(window.touchPressedCount, 1);
@ -1241,10 +1237,12 @@ void tst_QWindow::mouseToTouchTranslation()
void tst_QWindow::mouseToTouchLoop() void tst_QWindow::mouseToTouchLoop()
{ {
// make sure there's no infinite loop when synthesizing both ways // make sure there's no infinite loop when synthesizing both ways
qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true); QCoreApplication::setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true);
qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true); QCoreApplication::setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true);
InputTestWindow window; InputTestWindow window;
window.setTitle(QLatin1String(QTest::currentTestFunction()));
window.ignoreMouse = true; window.ignoreMouse = true;
window.ignoreTouch = true; window.ignoreTouch = true;
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize)); 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); QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::NoButton);
QCoreApplication::processEvents(); QCoreApplication::processEvents();
qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, false); QCoreApplication::setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, false);
qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true); QCoreApplication::setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true);
} }
void tst_QWindow::touchCancel() void tst_QWindow::touchCancel()
{ {
InputTestWindow window; InputTestWindow window;
window.setTitle(QLatin1String(QTest::currentTestFunction()));
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize)); window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
window.show(); window.show();
QVERIFY(QTest::qWaitForWindowExposed(&window)); QVERIFY(QTest::qWaitForWindowExposed(&window));
@ -1321,6 +1320,7 @@ void tst_QWindow::touchCancel()
void tst_QWindow::touchCancelWithTouchToMouse() void tst_QWindow::touchCancelWithTouchToMouse()
{ {
InputTestWindow window; InputTestWindow window;
window.setTitle(QLatin1String(QTest::currentTestFunction()));
window.ignoreTouch = true; window.ignoreTouch = true;
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize)); window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
window.show(); window.show();
@ -1343,7 +1343,7 @@ void tst_QWindow::touchCancelWithTouchToMouse()
// Cancel the touch. Should result in a mouse release for windows that have // Cancel the touch. Should result in a mouse release for windows that have
// have an active touch-to-mouse sequence. // have an active touch-to-mouse sequence.
QWindowSystemInterface::handleTouchCancelEvent(0, touchDevice); QWindowSystemInterface::handleTouchCancelEvent(nullptr, touchDevice);
QCoreApplication::processEvents(); QCoreApplication::processEvents();
QTRY_COMPARE(window.mouseReleaseButton, int(Qt::LeftButton)); QTRY_COMPARE(window.mouseReleaseButton, int(Qt::LeftButton));
@ -1358,7 +1358,7 @@ void tst_QWindow::touchCancelWithTouchToMouse()
QTRY_COMPARE(window.mousePressButton, 0); QTRY_COMPARE(window.mousePressButton, 0);
// Cancel the touch. It should not result in a mouse release with this window. // Cancel the touch. It should not result in a mouse release with this window.
QWindowSystemInterface::handleTouchCancelEvent(0, touchDevice); QWindowSystemInterface::handleTouchCancelEvent(nullptr, touchDevice);
QCoreApplication::processEvents(); QCoreApplication::processEvents();
QTRY_COMPARE(window.mouseReleaseButton, 0); QTRY_COMPARE(window.mouseReleaseButton, 0);
} }
@ -1369,6 +1369,7 @@ void tst_QWindow::touchInterruptedByPopup()
QSKIP("Wayland: This test crashes with xdg-shell unstable v6"); QSKIP("Wayland: This test crashes with xdg-shell unstable v6");
InputTestWindow window; InputTestWindow window;
window.setTitle(QLatin1String(QTest::currentTestFunction()));
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize)); window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
window.show(); window.show();
QVERIFY(QTest::qWaitForWindowExposed(&window)); QVERIFY(QTest::qWaitForWindowExposed(&window));
@ -1489,6 +1490,7 @@ void tst_QWindow::sizes()
void tst_QWindow::close() void tst_QWindow::close()
{ {
QWindow a; QWindow a;
a.setTitle(QLatin1String(QTest::currentTestFunction()));
QWindow b; QWindow b;
QWindow c(&a); QWindow c(&a);
@ -1508,6 +1510,7 @@ void tst_QWindow::activateAndClose()
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
QWindow window; QWindow window;
window.setTitle(QLatin1String(QTest::currentTestFunction()) + QString::number(i));
#if defined(Q_OS_QNX) #if defined(Q_OS_QNX)
window.setSurfaceType(QSurface::OpenGLSurface); window.setSurfaceType(QSurface::OpenGLSurface);
#endif #endif
@ -1525,15 +1528,16 @@ void tst_QWindow::activateAndClose()
#endif #endif
window.requestActivate(); window.requestActivate();
QVERIFY(QTest::qWaitForWindowActive(&window)); QVERIFY(QTest::qWaitForWindowActive(&window));
QCOMPARE(qGuiApp->focusWindow(), &window); QCOMPARE(QGuiApplication::focusWindow(), &window);
} }
} }
void tst_QWindow::mouseEventSequence() void tst_QWindow::mouseEventSequence()
{ {
int doubleClickInterval = qGuiApp->styleHints()->mouseDoubleClickInterval(); const auto doubleClickInterval = ulong(QGuiApplication::styleHints()->mouseDoubleClickInterval());
InputTestWindow window; InputTestWindow window;
window.setTitle(QLatin1String(QTest::currentTestFunction()));
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize)); window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
window.show(); window.show();
QVERIFY(QTest::qWaitForWindowExposed(&window)); QVERIFY(QTest::qWaitForWindowExposed(&window));
@ -1655,6 +1659,7 @@ void tst_QWindow::windowModality()
void tst_QWindow::inputReentrancy() void tst_QWindow::inputReentrancy()
{ {
InputTestWindow window; InputTestWindow window;
window.setTitle(QLatin1String(QTest::currentTestFunction()));
window.spinLoopWhenPressed = true; window.spinLoopWhenPressed = true;
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize)); window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
@ -1700,17 +1705,20 @@ void tst_QWindow::inputReentrancy()
class TabletTestWindow : public QWindow class TabletTestWindow : public QWindow
{ {
public: public:
TabletTestWindow() : eventType(QEvent::None) { } void tabletEvent(QTabletEvent *ev) override
void tabletEvent(QTabletEvent *ev) { {
eventType = ev->type(); eventType = ev->type();
eventGlobal = ev->globalPosF(); eventGlobal = ev->globalPosF();
eventLocal = ev->posF(); eventLocal = ev->posF();
eventDevice = ev->device(); eventDevice = ev->device();
} }
QEvent::Type eventType;
QEvent::Type eventType = QEvent::None;
QPointF eventGlobal, eventLocal; QPointF eventGlobal, eventLocal;
int eventDevice; int eventDevice = -1;
bool eventFilter(QObject *obj, QEvent *ev) {
bool eventFilter(QObject *obj, QEvent *ev) override
{
if (ev->type() == QEvent::TabletEnterProximity if (ev->type() == QEvent::TabletEnterProximity
|| ev->type() == QEvent::TabletLeaveProximity) { || ev->type() == QEvent::TabletLeaveProximity) {
eventType = ev->type(); eventType = ev->type();
@ -1758,6 +1766,7 @@ void tst_QWindow::tabletEvents()
void tst_QWindow::windowModality_QTBUG27039() void tst_QWindow::windowModality_QTBUG27039()
{ {
QWindow parent; QWindow parent;
parent.setTitle(QLatin1String(QTest::currentTestFunction()));
parent.setGeometry(QRect(m_availableTopLeft + QPoint(10, 10), m_testWindowSize)); parent.setGeometry(QRect(m_availableTopLeft + QPoint(10, 10), m_testWindowSize));
parent.show(); parent.show();
@ -1868,6 +1877,7 @@ void tst_QWindow::initialSize()
QSize defaultSize(0,0); QSize defaultSize(0,0);
{ {
Window w; Window w;
w.setTitle(QLatin1String(QTest::currentTestFunction()));
w.showNormal(); w.showNormal();
QTRY_VERIFY(w.width() > 0); QTRY_VERIFY(w.width() > 0);
QTRY_VERIFY(w.height() > 0); QTRY_VERIFY(w.height() > 0);
@ -1875,6 +1885,7 @@ void tst_QWindow::initialSize()
} }
{ {
Window w; Window w;
w.setTitle(QLatin1String(QTest::currentTestFunction()));
w.setWidth(m_testWindowSize.width()); w.setWidth(m_testWindowSize.width());
w.showNormal(); w.showNormal();
if (isPlatformWinRT()) if (isPlatformWinRT())
@ -1884,6 +1895,7 @@ void tst_QWindow::initialSize()
} }
{ {
Window w; Window w;
w.setTitle(QLatin1String(QTest::currentTestFunction()));
const QSize testSize(m_testWindowSize.width(), 42); const QSize testSize(m_testWindowSize.width(), 42);
w.resize(testSize); w.resize(testSize);
w.showNormal(); w.showNormal();
@ -1910,6 +1922,7 @@ void tst_QWindow::modalDialog()
QSKIP("Test fails due to QTBUG-61965, and is slow due to QTBUG-61964"); QSKIP("Test fails due to QTBUG-61965, and is slow due to QTBUG-61964");
QWindow normalWindow; QWindow normalWindow;
normalWindow.setTitle(QLatin1String(QTest::currentTestFunction()));
normalWindow.setFramePosition(m_availableTopLeft + QPoint(80, 80)); normalWindow.setFramePosition(m_availableTopLeft + QPoint(80, 80));
normalWindow.resize(m_testWindowSize); normalWindow.resize(m_testWindowSize);
normalWindow.show(); normalWindow.show();
@ -1945,6 +1958,7 @@ void tst_QWindow::modalDialogClosingOneOfTwoModal()
QSKIP("QWindow::requestActivate() is not supported."); QSKIP("QWindow::requestActivate() is not supported.");
QWindow normalWindow; QWindow normalWindow;
normalWindow.setTitle(QLatin1String(QTest::currentTestFunction()));
normalWindow.setFramePosition(m_availableTopLeft + QPoint(80, 80)); normalWindow.setFramePosition(m_availableTopLeft + QPoint(80, 80));
normalWindow.resize(m_testWindowSize); normalWindow.resize(m_testWindowSize);
normalWindow.show(); normalWindow.show();
@ -1992,6 +2006,7 @@ void tst_QWindow::modalWithChildWindow()
QSKIP("QWindow::requestActivate() is not supported."); QSKIP("QWindow::requestActivate() is not supported.");
QWindow normalWindow; QWindow normalWindow;
normalWindow.setTitle(QLatin1String(QTest::currentTestFunction()));
normalWindow.setFramePosition(m_availableTopLeft + QPoint(80, 80)); normalWindow.setFramePosition(m_availableTopLeft + QPoint(80, 80));
normalWindow.resize(m_testWindowSize); normalWindow.resize(m_testWindowSize);
normalWindow.show(); normalWindow.show();
@ -2028,6 +2043,7 @@ void tst_QWindow::modalWindowModallity()
QSKIP("QWindow::requestActivate() is not supported."); QSKIP("QWindow::requestActivate() is not supported.");
QWindow normal_window; QWindow normal_window;
normal_window.setTitle(QLatin1String(QTest::currentTestFunction()));
normal_window.setFramePosition(m_availableTopLeft + QPoint(80, 80)); normal_window.setFramePosition(m_availableTopLeft + QPoint(80, 80));
normal_window.resize(m_testWindowSize); normal_window.resize(m_testWindowSize);
normal_window.show(); normal_window.show();
@ -2058,6 +2074,7 @@ void tst_QWindow::modalWindowModallity()
void tst_QWindow::modalWindowPosition() void tst_QWindow::modalWindowPosition()
{ {
QWindow window; QWindow window;
window.setTitle(QLatin1String(QTest::currentTestFunction()));
window.setGeometry(QRect(m_availableTopLeft + QPoint(100, 100), m_testWindowSize)); window.setGeometry(QRect(m_availableTopLeft + QPoint(100, 100), m_testWindowSize));
// Allow for any potential resizing due to constraints // Allow for any potential resizing due to constraints
QRect origGeo = window.geometry(); QRect origGeo = window.geometry();
@ -2341,6 +2358,7 @@ void tst_QWindow::requestUpdate()
QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize); QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize);
Window window; Window window;
window.setTitle(QLatin1String(QTest::currentTestFunction()));
window.setGeometry(geometry); window.setGeometry(geometry);
window.show(); window.show();
QCoreApplication::processEvents(); QCoreApplication::processEvents();
@ -2370,10 +2388,10 @@ void tst_QWindow::flags()
class EventWindow : public QWindow class EventWindow : public QWindow
{ {
public: public:
EventWindow() : QWindow(), gotBlocked(false) {} bool gotBlocked = false;
bool gotBlocked;
protected: protected:
bool event(QEvent *e) bool event(QEvent *e) override
{ {
if (e->type() == QEvent::WindowBlocked) if (e->type() == QEvent::WindowBlocked)
gotBlocked = true; gotBlocked = true;
@ -2384,6 +2402,7 @@ protected:
void tst_QWindow::testBlockingWindowShownAfterModalDialog() void tst_QWindow::testBlockingWindowShownAfterModalDialog()
{ {
EventWindow normalWindow; EventWindow normalWindow;
normalWindow.setTitle(QLatin1String(QTest::currentTestFunction()));
normalWindow.setFramePosition(m_availableTopLeft + QPoint(80, 80)); normalWindow.setFramePosition(m_availableTopLeft + QPoint(80, 80));
normalWindow.resize(m_testWindowSize); normalWindow.resize(m_testWindowSize);
normalWindow.show(); normalWindow.show();
@ -2411,6 +2430,7 @@ void tst_QWindow::testBlockingWindowShownAfterModalDialog()
void tst_QWindow::generatedMouseMove() void tst_QWindow::generatedMouseMove()
{ {
InputTestWindow w; InputTestWindow w;
w.setTitle(QLatin1String(QTest::currentTestFunction()));
w.setGeometry(QRect(m_availableTopLeft + QPoint(100, 100), m_testWindowSize)); w.setGeometry(QRect(m_availableTopLeft + QPoint(100, 100), m_testWindowSize));
w.setFlags(w.flags() | Qt::FramelessWindowHint); // ### FIXME: QTBUG-63542 w.setFlags(w.flags() | Qt::FramelessWindowHint); // ### FIXME: QTBUG-63542
w.show(); w.show();
@ -2422,34 +2442,34 @@ void tst_QWindow::generatedMouseMove()
QTest::mouseMove(&w, point); QTest::mouseMove(&w, point);
QVERIFY(w.mouseMovedCount == 1); QVERIFY(w.mouseMovedCount == 1);
// A press event that does not change position should not generate mouse move // A press event that does not change position should not generate mouse move
QTest::mousePress(&w, Qt::LeftButton, 0, point); QTest::mousePress(&w, Qt::LeftButton, Qt::KeyboardModifiers(), point);
QTest::mousePress(&w, Qt::RightButton, 0, point); QTest::mousePress(&w, Qt::RightButton, Qt::KeyboardModifiers(), point);
QVERIFY(w.mouseMovedCount == 1); QVERIFY(w.mouseMovedCount == 1);
// Verify that a move event is generated for a mouse release event that changes position // Verify that a move event is generated for a mouse release event that changes position
point += step; point += step;
QTest::mouseRelease(&w, Qt::LeftButton, 0, point); QTest::mouseRelease(&w, Qt::LeftButton,Qt::KeyboardModifiers(), point);
QVERIFY(w.mouseMovedCount == 2); QVERIFY(w.mouseMovedCount == 2);
QVERIFY(w.buttonStateInGeneratedMove == (Qt::LeftButton | Qt::RightButton)); QVERIFY(w.buttonStateInGeneratedMove == (Qt::LeftButton | Qt::RightButton));
point += step; point += step;
QTest::mouseRelease(&w, Qt::RightButton, 0, point); QTest::mouseRelease(&w, Qt::RightButton, Qt::KeyboardModifiers(), point);
QVERIFY(w.mouseMovedCount == 3); QVERIFY(w.mouseMovedCount == 3);
QVERIFY(w.buttonStateInGeneratedMove == Qt::RightButton); QVERIFY(w.buttonStateInGeneratedMove == Qt::RightButton);
// Verify that a move event is generated for a mouse press event that changes position // Verify that a move event is generated for a mouse press event that changes position
point += step; point += step;
QTest::mousePress(&w, Qt::LeftButton, 0, point); QTest::mousePress(&w, Qt::LeftButton, Qt::KeyboardModifiers(), point);
QVERIFY(w.mouseMovedCount == 4); QVERIFY(w.mouseMovedCount == 4);
QVERIFY(w.buttonStateInGeneratedMove == Qt::NoButton); QVERIFY(w.buttonStateInGeneratedMove == Qt::NoButton);
point += step; point += step;
QTest::mousePress(&w, Qt::RightButton, 0, point); QTest::mousePress(&w, Qt::RightButton, Qt::KeyboardModifiers(), point);
QVERIFY(w.mouseMovedCount == 5); QVERIFY(w.mouseMovedCount == 5);
QVERIFY(w.buttonStateInGeneratedMove == Qt::LeftButton); QVERIFY(w.buttonStateInGeneratedMove == Qt::LeftButton);
// A release event that does not change position should not generate mouse move // A release event that does not change position should not generate mouse move
QTest::mouseRelease(&w, Qt::RightButton, 0, point); QTest::mouseRelease(&w, Qt::RightButton, Qt::KeyboardModifiers(), point);
QTest::mouseRelease(&w, Qt::LeftButton, 0, point); QTest::mouseRelease(&w, Qt::LeftButton, Qt::KeyboardModifiers(), point);
QVERIFY(w.mouseMovedCount == 5); QVERIFY(w.mouseMovedCount == 5);
} }
@ -2458,6 +2478,7 @@ void tst_QWindow::keepPendingUpdateRequests()
QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize); QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize);
Window window; Window window;
window.setTitle(QLatin1String(QTest::currentTestFunction()));
window.setGeometry(geometry); window.setGeometry(geometry);
window.show(); window.show();
QCoreApplication::processEvents(); QCoreApplication::processEvents();

View File

@ -1,3 +1,2 @@
[systemFixedFont] # QTBUG-54623 [systemFixedFont] # QTBUG-54623
winrt
b2qt b2qt

View File

@ -32,9 +32,8 @@ base::base(QWidget *parent) :
QWidget(parent) QWidget(parent)
{ {
m_timer = new QTimer(this); m_timer = new QTimer(this);
m_modalStarted = false;
m_timer->setSingleShot(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); m_timer->start(5000);
} }
@ -43,6 +42,7 @@ void base::periodicTimer()
if(m_modalStarted) if(m_modalStarted)
exit(0); exit(0);
m_modalDialog = new QDialog(this); m_modalDialog = new QDialog(this);
m_modalDialog->setWindowTitle(QLatin1String("modal"));
m_modalDialog->setModal(true); m_modalDialog->setModal(true);
m_modalDialog->show(); m_modalDialog->show();
m_modalStarted = true; m_modalStarted = true;

View File

@ -37,12 +37,10 @@ class base : public QWidget
{ {
Q_OBJECT Q_OBJECT
QTimer *m_timer; QTimer *m_timer;
bool m_modalStarted; bool m_modalStarted = false;
QDialog *m_modalDialog; QDialog *m_modalDialog = nullptr;
public: public:
explicit base(QWidget *parent = 0); explicit base(QWidget *parent = nullptr);
signals:
public slots: public slots:
void periodicTimer(); void periodicTimer();

View File

@ -26,8 +26,6 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtGui>
#include <QApplication> #include <QApplication>
#include "base.h" #include "base.h"
@ -35,7 +33,6 @@ int main(int argc, char *argv[])
{ {
QApplication app(argc, argv); QApplication app(argc, argv);
QApplication::setAttribute(Qt::AA_NativeWindows); //QTBUG-15774 QApplication::setAttribute(Qt::AA_NativeWindows); //QTBUG-15774
base *b = new base(); base b;
Q_UNUSED(b);
return app.exec(); 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; 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 class tst_QWidget_window : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
tst_QWidget_window(){}; tst_QWidget_window();
public slots: public slots:
void initTestCase(); void initTestCase();
@ -110,8 +123,20 @@ private slots:
void nativeShow(); void nativeShow();
void QTBUG_56277_resize_on_showEvent(); 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() void tst_QWidget_window::initTestCase()
{ {
} }
@ -162,65 +187,65 @@ void tst_QWidget_window::tst_min_max_size()
void tst_QWidget_window::tst_move_show() void tst_QWidget_window::tst_move_show()
{ {
QWidget w; QWidget w;
w.move(100, 100); const QPoint pos(100, 100);
w.move(pos);
w.show(); w.show();
#ifdef Q_OS_WINRT #ifdef Q_OS_WINRT
QEXPECT_FAIL("", "Winrt does not support move", Abort); QEXPECT_FAIL("", "Winrt does not support move", Abort);
#endif #endif
QCOMPARE(w.pos(), QPoint(100, 100)); QVERIFY2(qFuzzyCompareWindowPosition(w.pos(), pos, m_fuzz),
// QCoreApplication::processEvents(QEventLoop::AllEvents, 3000); qPrintable(msgPointMismatch(w.pos(), pos)));
} }
void tst_QWidget_window::tst_show_move() void tst_QWidget_window::tst_show_move()
{ {
QWidget w; QWidget w;
w.show(); w.show();
w.move(100, 100); const QPoint pos(100, 100);
QCOMPARE(w.pos(), QPoint(100, 100)); w.move(pos);
// QCoreApplication::processEvents(QEventLoop::AllEvents, 1000); QVERIFY2(qFuzzyCompareWindowPosition(w.pos(), pos, m_fuzz),
qPrintable(msgPointMismatch(w.pos(), pos)));
} }
void tst_QWidget_window::tst_show_move_hide_show() void tst_QWidget_window::tst_show_move_hide_show()
{ {
QWidget w; QWidget w;
w.show(); w.show();
w.move(100, 100); const QPoint pos(100, 100);
w.move(pos);
w.hide(); w.hide();
w.show(); w.show();
QCOMPARE(w.pos(), QPoint(100, 100)); QVERIFY2(qFuzzyCompareWindowPosition(w.pos(), pos, m_fuzz),
// QCoreApplication::processEvents(QEventLoop::AllEvents, 1000); qPrintable(msgPointMismatch(w.pos(), pos)));
} }
void tst_QWidget_window::tst_resize_show() void tst_QWidget_window::tst_resize_show()
{ {
QWidget w; QWidget w;
w.resize(200, 200); w.resize(m_testWidgetSize);
w.show(); w.show();
#ifdef Q_OS_WINRT #ifdef Q_OS_WINRT
QEXPECT_FAIL("", "Winrt does not support resize", Abort); QEXPECT_FAIL("", "Winrt does not support resize", Abort);
#endif #endif
QCOMPARE(w.size(), QSize(200, 200)); QCOMPARE(w.size(), m_testWidgetSize);
// QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
} }
void tst_QWidget_window::tst_show_resize() void tst_QWidget_window::tst_show_resize()
{ {
QWidget w; QWidget w;
w.show(); w.show();
w.resize(200, 200); w.resize(m_testWidgetSize);
QCOMPARE(w.size(), QSize(200, 200)); QCOMPARE(w.size(), m_testWidgetSize);
// QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
} }
void tst_QWidget_window::tst_show_resize_hide_show() void tst_QWidget_window::tst_show_resize_hide_show()
{ {
QWidget w; QWidget w;
w.show(); w.show();
w.resize(200, 200); w.resize(m_testWidgetSize);
w.hide(); w.hide();
w.show(); w.show();
QCOMPARE(w.size(), QSize(200, 200)); QCOMPARE(w.size(), m_testWidgetSize);
// QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
} }
class PaintTestWidget : public QWidget class PaintTestWidget : public QWidget
@ -857,7 +882,7 @@ void tst_QWidget_window::tst_updateWinId_QTBUG40681()
lbl->setAttribute(Qt::WA_NativeWindow); lbl->setAttribute(Qt::WA_NativeWindow);
lbl->setObjectName("label1"); lbl->setObjectName("label1");
vl->addWidget(lbl); vl->addWidget(lbl);
w.setMinimumWidth(200); w.setMinimumWidth(m_testWidgetSize.width());
w.show(); w.show();
@ -880,6 +905,7 @@ void tst_QWidget_window::tst_updateWinId_QTBUG40681()
void tst_QWidget_window::tst_recreateWindow_QTBUG40817() void tst_QWidget_window::tst_recreateWindow_QTBUG40817()
{ {
QTabWidget tab; QTabWidget tab;
tab.setMinimumWidth(m_testWidgetSize.width());
QWidget *w = new QWidget; QWidget *w = new QWidget;
tab.addTab(w, "Tab1"); tab.addTab(w, "Tab1");
@ -946,7 +972,7 @@ void tst_QWidget_window::tst_resize_count()
resize.resizeCount = 0; resize.resizeCount = 0;
ResizeWidget child(&resize); ResizeWidget child(&resize);
child.resize(200,200); child.resize(m_testWidgetSize);
child.winId(); child.winId();
child.show(); child.show();
QVERIFY(QTest::qWaitForWindowExposed(&child)); QVERIFY(QTest::qWaitForWindowExposed(&child));
@ -963,7 +989,7 @@ void tst_QWidget_window::tst_resize_count()
{ {
ResizeWidget parent; ResizeWidget parent;
ResizeWidget child(&parent); ResizeWidget child(&parent);
child.resize(200,200); child.resize(m_testWidgetSize);
child.winId(); child.winId();
parent.show(); parent.show();
QVERIFY(QTest::qWaitForWindowExposed(&parent)); QVERIFY(QTest::qWaitForWindowExposed(&parent));
@ -1076,6 +1102,7 @@ void tst_QWidget_window::QTBUG_50561_QCocoaBackingStore_paintDevice_crash()
ApplicationStateSaver as; ApplicationStateSaver as;
QMainWindow w; QMainWindow w;
w.setMinimumWidth(m_testWidgetSize.width());
w.addToolBar(new QToolBar(&w)); w.addToolBar(new QToolBar(&w));
w.show(); w.show();
QVERIFY(QTest::qWaitForWindowExposed(&w)); QVERIFY(QTest::qWaitForWindowExposed(&w));

View File

@ -324,7 +324,9 @@ void tst_QDoubleSpinBox::setPrefixSuffix()
QFETCH(QString, expectedCleanText); QFETCH(QString, expectedCleanText);
QFETCH(bool, show); QFETCH(bool, show);
QDoubleSpinBox spin(0); QDoubleSpinBox spin;
if (show)
spin.show();
spin.setDecimals(decimals); spin.setDecimals(decimals);
const QSize size1 = spin.sizeHint(); const QSize size1 = spin.sizeHint();
spin.setPrefix(prefix); spin.setPrefix(prefix);
@ -332,17 +334,17 @@ void tst_QDoubleSpinBox::setPrefixSuffix()
spin.setSuffix(suffix); spin.setSuffix(suffix);
const QSize size3 = spin.sizeHint(); const QSize size3 = spin.sizeHint();
spin.setValue(value); spin.setValue(value);
if (show)
spin.show();
QCOMPARE(spin.text(), expectedText); QCOMPARE(spin.text(), expectedText);
QCOMPARE(spin.cleanText(), expectedCleanText); QCOMPARE(spin.cleanText(), expectedCleanText);
if (!prefix.isEmpty() && !suffix.isEmpty()) { if (!suffix.isEmpty()) {
QVERIFY(size1.width() < size2.width());
QVERIFY(size2.width() < size3.width()); QVERIFY(size2.width() < size3.width());
spin.setSuffix(QString()); spin.setSuffix(QString());
QCOMPARE(spin.sizeHint(), size2); QCOMPARE(spin.sizeHint(), size2);
}
if (!prefix.isEmpty()) {
QVERIFY(size1.width() < size2.width());
spin.setPrefix(QString()); spin.setPrefix(QString());
QCOMPARE(spin.sizeHint(), size1); QCOMPARE(spin.sizeHint(), size1);
} }

View File

@ -461,26 +461,30 @@ void tst_QSpinBox::setPrefixSuffix()
QFETCH(QString, expectedCleanText); QFETCH(QString, expectedCleanText);
QFETCH(bool, show); QFETCH(bool, show);
QSpinBox spin(0); QSpinBox spin;
if (show) {
spin.show();
spin.setPrefix(QString()); // trigger a recalc of sizeHint
}
const QSize size1 = spin.sizeHint(); const QSize size1 = spin.sizeHint();
spin.setPrefix(prefix); spin.setPrefix(prefix);
const QSize size2 = spin.sizeHint(); const QSize size2 = spin.sizeHint();
spin.setSuffix(suffix); spin.setSuffix(suffix);
const QSize size3 = spin.sizeHint(); const QSize size3 = spin.sizeHint();
spin.setValue(value); spin.setValue(value);
if (show)
spin.show();
QCOMPARE(spin.prefix(), prefix); QCOMPARE(spin.prefix(), prefix);
QCOMPARE(spin.suffix(), suffix); QCOMPARE(spin.suffix(), suffix);
QCOMPARE(spin.text(), expectedText); QCOMPARE(spin.text(), expectedText);
QCOMPARE(spin.cleanText(), expectedCleanText); QCOMPARE(spin.cleanText(), expectedCleanText);
if (!prefix.isEmpty() && !suffix.isEmpty()) { if (!suffix.isEmpty()) {
QVERIFY(size1.width() < size2.width());
QVERIFY(size2.width() < size3.width()); QVERIFY(size2.width() < size3.width());
spin.setSuffix(QString()); spin.setSuffix(QString());
QCOMPARE(spin.sizeHint(), size2); QCOMPARE(spin.sizeHint(), size2);
}
if (!prefix.isEmpty()) {
QVERIFY(size1.width() < size2.width());
spin.setPrefix(QString()); spin.setPrefix(QString());
QCOMPARE(spin.sizeHint(), size1); QCOMPARE(spin.sizeHint(), size1);
} }