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
*/
/*!
\externalpage https://cmake.org/cmake/help/latest/manual/cmake-qt.7.html#autorcc
\title CMake AUTORCC Documentation
*/
/*!
\externalpage https://cmake.org/cmake/help/latest/manual/cmake-qt.7.html#autouic
\title CMake AUTOUIC Documentation
*/
/*!
\externalpage https://cmake.org/cmake/help/latest/prop_tgt/LOCATION.html
\title CMake LOCATION Documentation

View File

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

View File

@ -67,7 +67,7 @@ contains(TEMPLATE, .*app) {
# replacing the app name placeholder with the actual app name.
apphtml.name = application main html file
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.depends = $$apphtml.input
QMAKE_EXTRA_COMPILERS += apphtml

View File

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

View File

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

View File

@ -0,0 +1,26 @@
#! [qt5_wrap_cpp]
set(SOURCES myapp.cpp main.cpp)
qt5_wrap_cpp(SOURCES myapp.h)
add_executable(myapp ${SOURCES})
#! [qt5_wrap_cpp]
#! [qt5_add_resources]
set(SOURCES main.cpp)
qt5_add_resources(SOURCES example.qrc)
add_executable(myapp ${SOURCES})
#! [qt5_add_resources]
#! [qt5_add_big_resources]
set(SOURCES main.cpp)
qt5_add_big_resources(SOURCES big_resource.qrc)
add_executable(myapp ${SOURCES})
#! [qt5_add_big_resources]
#! [qt5_add_binary_resources]
qt5_add_binary_resources(resources project.qrc OPTIONS -no-compress)
add_dependencies(myapp resources)
#! [qt5_add_binary_resources]
#! [qt5_generate_moc]
qt5_generate_moc(main.cpp main.moc TARGET myapp)
#! [qt5_generate_moc]

View File

@ -0,0 +1,212 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\page qtcore-cmake-qt5-wrap-cpp.html
\ingroup cmake-macros-qtcore
\title qt5_wrap_cpp
\brief Creates \c{.moc} files from sources.
\section1 Synopsis
\badcode
qt5_wrap_cpp(<VAR> src_file1 [src_file2 ...]
[TARGET target]
[OPTIONS ...]
[DEPENDS ...])
\endcode
\section1 Description
Creates rules for calling \l{moc}{Meta-Object Compiler (moc)} on the given
source files. For each input file, an output file is generated in the build
directory. The paths of the generated files are added to\c{<VAR>}.
\note This is a low-level macro. See the \l{CMake AUTOMOC Documentation} for a
more convenient way to let source files be processed with \c{moc}.
\section1 Options
You can set an explicit \c{TARGET}. This will make sure that the target
properties \c{INCLUDE_DIRECTORIES} and \c{COMPILE_DEFINITIONS} are also used
when scanning the source files with \c{moc}.
You can set additional \c{OPTIONS} that should be added to the \c{moc} calls.
You can find possible options in the \l{moc}{moc documentation}.
\c{DEPENDS} allows you to add additional dependencies for recreation of the
generated files. This is useful when the sources have implicit dependencies,
like code for a Qt plugin that includes a \c{.json} file using the
Q_PLUGIN_METADATA() macro.
\section1 Examples
\snippet cmake-macros/examples.cmake qt5_wrap_cpp
*/
/*!
\page qtcore-cmake-qt5-add-resources.html
\ingroup cmake-macros-qtcore
\title qt5_add_resources
\brief Compiles binary resources into source code.
\section1 Synopsis
\badcode
qt5_add_resources(<VAR> file1.qrc [file2.qrc ...]
[OPTIONS ...])
\endcode
\section1 Description
Creates source code from Qt resource files using the
\l{Resource Compiler (rcc)}. Paths to the generated source files are added to
\c{<VAR>}.
\note This is a low-level macro. See the \l{CMake AUTORCC Documentation} for a
more convenient way to let Qt resource files be processed with \c{rcc}.
For embedding bigger resources, see \l qt5_add_big_resources.
\section1 Arguments
You can set additional \c{OPTIONS} that should be added to the \c{rcc} calls.
You can find possible options in the \l{rcc}{rcc documentation}.
\section1 Examples
\snippet cmake-macros/examples.cmake qt5_add_resources
*/
/*!
\page qtcore-cmake-qt5-add-big-resources.html
\ingroup cmake-macros-qtcore
\title qt5_add_big_resources
\brief Compiles big binary resources into object code.
\section1 Synopsis
\badcode
qt5_add_big_resources(<VAR> file1.qrc [file2.qrc ...]
[OPTIONS ...])
\endcode
\section1 Description
Creates compiled object files from Qt resource files using the
\l{Resource Compiler (rcc)}. Paths to the generated files are added to
\c{<VAR>}.
This is similar to \l qt5_add_resources, but directly generates object
files (\c .o, \c .obj) files instead of C++ source code. This allows to
embed bigger resources, where compiling to C++ sources and then to
binaries would be too time consuming or memory intensive.
\section1 Arguments
You can set additional \c{OPTIONS} that should be added to the \c{rcc} calls.
You can find possible options in the \l{rcc}{rcc documentation}.
\section1 Examples
\snippet cmake-macros/examples.cmake qt5_add_big_resources
*/
/*!
\page qtcore-cmake-qt5_add_binary_resources.html
\ingroup cmake-macros-qtcore
\title qt5_add_binary_resources
\brief Creates an \c{RCC} file from a list of Qt resource files.
\section1 Synopsis
\badcode
qt5_add_binary_resources(target file1.qrc [file2.qrc ...]
[DESTINATION ...]
[OPTIONS ...])
\endcode
\section1 Description
Adds a custom \c target that compiles Qt resource files into a binary \c{.rcc}
file.
\section1 Arguments
\c{DESTINATION} sets the path of the generated \c{.rcc} file. The default is
\c{${CMAKE_CURRENT_BINARY_DIR}/${target}.rcc}.
You can set additional \c{OPTIONS} that should be added to the \c{rcc} calls.
You can find possible options in the \l{rcc}{rcc documentation}.
\section1 Examples
\snippet cmake-macros/examples.cmake qt5_add_binary_resources
*/
/*!
\page qtcore-cmake-qt5-generate-moc.html
\ingroup cmake-macros-qtcore
\title qt5_generate_moc
\brief Calls moc on an input file.
\section1 Synopsis
\badcode
qt5_generate_moc(src_file dest_file
[TARGET target])
\endcode
\section1 Description
Creates a rule to call the \l{moc}{Meta-Object Compiler (moc)} on \c src_file
and store the output in \c dest_file.
\note This is a low-level macro. See the \l{CMake AUTOMOC Documentation} for a
more convenient way to let source files be processed with \c{moc}.
\l qt5_wrap_cpp is also similar, but automatically generates a temporary file
path for you.
\section1 Arguments
You can set an explicit \c{TARGET}. This will make sure that the target
properties \c{INCLUDE_DIRECTORIES} and \c{COMPILE_DEFINITIONS} are also used
when scanning the source files with \c{moc}.
\section1 Examples
\snippet cmake-macros/examples.cmake qt5_generate_moc
*/

View File

@ -695,52 +695,36 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry,
Q_UNUSED(data);
return QFileSystemEntry(slowCanonicalized(absoluteName(entry).filePath()));
#else
char *ret = 0;
# if defined(Q_OS_DARWIN)
ret = (char*)malloc(PATH_MAX + 1);
if (ret && 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;
}
# 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.
char stack_result[PATH_MAX+1];
char *resolved_name = nullptr;
# if defined(Q_OS_DARWIN) || defined(Q_OS_ANDROID)
// On some Android and macOS 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))
fillMetaData(entry, data, QFileSystemMetaData::ExistsAttribute);
if (!data.exists()) {
ret = 0;
errno = ENOENT;
} else {
ret = (char*)malloc(PATH_MAX + 1);
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;
resolved_name = stack_result;
}
}
if (resolved_name && realpath(entry.nativeFilePath().constData(), resolved_name) == nullptr)
resolved_name = nullptr;
# else
# if _POSIX_VERSION >= 200801L
ret = realpath(entry.nativeFilePath().constData(), (char*)0);
# if _POSIX_VERSION >= 200801L // ask realpath to allocate memory
resolved_name = realpath(entry.nativeFilePath().constData(), nullptr);
# else
ret = (char*)malloc(PATH_MAX + 1);
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;
}
resolved_name = stack_result;
if (realpath(entry.nativeFilePath().constData(), resolved_name) == nullptr)
resolved_name = nullptr;
# endif
# endif
if (ret) {
if (resolved_name) {
data.knownFlagsMask |= QFileSystemMetaData::ExistsAttribute;
data.entryFlags |= QFileSystemMetaData::ExistsAttribute;
QString canonicalPath = QDir::cleanPath(QFile::decodeName(ret));
free(ret);
QString canonicalPath = QDir::cleanPath(QFile::decodeName(resolved_name));
if (resolved_name != stack_result)
free(resolved_name);
return QFileSystemEntry(canonicalPath);
} else if (errno == ENOENT || errno == ENOTDIR) { // file doesn't exist
data.knownFlagsMask |= QFileSystemMetaData::ExistsAttribute;

View File

@ -46,6 +46,7 @@
#include "qcoreevent.h"
#include "qeventloop.h"
#endif
#include "qmetaobject.h"
#include "qcorecmdlineargs_p.h"
#include <qdatastream.h>
#include <qdebug.h>
@ -952,6 +953,10 @@ bool QCoreApplication::isSetuidAllowed()
Sets the attribute \a attribute if \a on is true;
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()
*/
void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on)
@ -960,6 +965,27 @@ void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on)
QCoreApplicationPrivate::attribs |= 1 << attribute;
else
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() {
Q_STATIC_ASSERT_X(QtPrivate::IsQEnumHelper<T>::Value,
"QMetaEnum::fromType only works with enums declared as Q_ENUM or Q_FLAG");
"QMetaEnum::fromType only works with enums declared as "
"Q_ENUM, Q_ENUM_NS, Q_FLAG or Q_FLAG_NS");
const QMetaObject *metaObject = qt_getEnumMetaObject(T());
const char *name = qt_getEnumName(T());
return metaObject->enumerator(metaObject->indexOfEnumerator(name));

View File

@ -74,7 +74,7 @@ QT_BEGIN_NAMESPACE
# define QLIBRARY_AS_DEBUG true
#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
// to allow loading plugins, regardless of how they were built.
# define QT_NO_DEBUG_PLUGIN_CHECK

View File

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

View File

@ -492,5 +492,13 @@ QPoint QHighDpiScaling::origin(const QPlatformScreen *platformScreen)
return platformScreen->geometry().topLeft();
}
QPoint QHighDpiScaling::origin(const QWindow *window)
{
if (window && window->isTopLevel() && window->screen())
return window->screen()->geometry().topLeft();
return QPoint(0, 0);
}
#endif //QT_NO_HIGHDPISCALING
QT_END_NAMESPACE

View File

@ -83,6 +83,7 @@ public:
static qreal factor(const QPlatformScreen *platformScreen);
static QPoint origin(const QScreen *screen);
static QPoint origin(const QPlatformScreen *platformScreen);
static QPoint origin(const QWindow *window);
static QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen);
static QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen);
static QPoint mapPositionToGlobal(const QPoint &pos, const QPoint &windowGlobalPosition, const QWindow *window);
@ -203,94 +204,42 @@ inline QPointF toNativeLocalPosition(const QPointF &pos, const QWindow *window)
return pos * scaleFactor;
}
inline QRect fromNativePixels(const QRect &pixelRect, const QPlatformScreen *platformScreen)
template <typename C>
inline QRect fromNativePixels(const QRect &pixelRect, const C *context)
{
const qreal scaleFactor = QHighDpiScaling::factor(platformScreen);
const QPoint origin = QHighDpiScaling::origin(platformScreen);
const qreal scaleFactor = QHighDpiScaling::factor(context);
const QPoint origin = QHighDpiScaling::origin(context);
return QRect(fromNative(pixelRect.topLeft(), scaleFactor, origin),
fromNative(pixelRect.size(), scaleFactor));
}
inline QRect toNativePixels(const QRect &pointRect, const QPlatformScreen *platformScreen)
template <typename C>
inline QRect toNativePixels(const QRect &pointRect, const C *context)
{
const qreal scaleFactor = QHighDpiScaling::factor(platformScreen);
const QPoint origin = QHighDpiScaling::origin(platformScreen);
const qreal scaleFactor = QHighDpiScaling::factor(context);
const QPoint origin = QHighDpiScaling::origin(context);
return QRect(toNative(pointRect.topLeft(), scaleFactor, origin),
toNative(pointRect.size(), scaleFactor));
}
inline QRect fromNativePixels(const QRect &pixelRect, const QScreen *screen)
template <typename C>
inline QRectF toNativePixels(const QRectF &pointRect, const C *context)
{
const qreal scaleFactor = QHighDpiScaling::factor(screen);
const QPoint origin = QHighDpiScaling::origin(screen);
return QRect(fromNative(pixelRect.topLeft(), scaleFactor, origin),
fromNative(pixelRect.size(), scaleFactor));
}
inline QRect toNativePixels(const QRect &pointRect, const QScreen *screen)
{
const qreal scaleFactor = QHighDpiScaling::factor(screen);
const QPoint origin = QHighDpiScaling::origin(screen);
return QRect(toNative(pointRect.topLeft(), scaleFactor, origin),
toNative(pointRect.size(), scaleFactor));
}
inline QRect fromNativePixels(const QRect &pixelRect, const QWindow *window)
{
if (window && window->isTopLevel() && window->screen()) {
return fromNativePixels(pixelRect, window->screen());
} else {
const qreal scaleFactor = QHighDpiScaling::factor(window);
return QRect(pixelRect.topLeft() / scaleFactor, fromNative(pixelRect.size(), scaleFactor));
}
}
inline QRectF toNativePixels(const QRectF &pointRect, const QScreen *screen)
{
const qreal scaleFactor = QHighDpiScaling::factor(screen);
const QPoint origin = QHighDpiScaling::origin(screen);
const qreal scaleFactor = QHighDpiScaling::factor(context);
const QPoint origin = QHighDpiScaling::origin(context);
return QRectF(toNative(pointRect.topLeft(), scaleFactor, origin),
toNative(pointRect.size(), scaleFactor));
}
inline QRect toNativePixels(const QRect &pointRect, const QWindow *window)
template <typename C>
inline QRectF fromNativePixels(const QRectF &pixelRect, const C *context)
{
if (window && window->isTopLevel() && window->screen()) {
return toNativePixels(pointRect, window->screen());
} else {
const qreal scaleFactor = QHighDpiScaling::factor(window);
return QRect(pointRect.topLeft() * scaleFactor, toNative(pointRect.size(), scaleFactor));
}
}
inline QRectF fromNativePixels(const QRectF &pixelRect, const QScreen *screen)
{
const qreal scaleFactor = QHighDpiScaling::factor(screen);
const QPoint origin = QHighDpiScaling::origin(screen);
const qreal scaleFactor = QHighDpiScaling::factor(context);
const QPoint origin = QHighDpiScaling::origin(context);
return QRectF(fromNative(pixelRect.topLeft(), scaleFactor, origin),
fromNative(pixelRect.size(), scaleFactor));
}
inline QRectF fromNativePixels(const QRectF &pixelRect, const QWindow *window)
{
if (window && window->isTopLevel() && window->screen()) {
return fromNativePixels(pixelRect, window->screen());
} else {
const qreal scaleFactor = QHighDpiScaling::factor(window);
return QRectF(pixelRect.topLeft() / scaleFactor, pixelRect.size() / scaleFactor);
}
}
inline QRectF toNativePixels(const QRectF &pointRect, const QWindow *window)
{
if (window && window->isTopLevel() && window->screen()) {
return toNativePixels(pointRect, window->screen());
} else {
const qreal scaleFactor = QHighDpiScaling::factor(window);
return QRectF(pointRect.topLeft() * scaleFactor, pointRect.size() * scaleFactor);
}
}
inline QSize fromNativePixels(const QSize &pixelSize, const QWindow *window)
{
return pixelSize / QHighDpiScaling::factor(window);
@ -311,56 +260,28 @@ inline QSizeF toNativePixels(const QSizeF &pointSize, const QWindow *window)
return pointSize * QHighDpiScaling::factor(window);
}
inline QPoint fromNativePixels(const QPoint &pixelPoint, const QScreen *screen)
template <typename C>
inline QPoint fromNativePixels(const QPoint &pixelPoint, const C *context)
{
return fromNative(pixelPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen));
return fromNative(pixelPoint, QHighDpiScaling::factor(context), QHighDpiScaling::origin(context));
}
inline QPoint fromNativePixels(const QPoint &pixelPoint, const QWindow *window)
template <typename C>
inline QPoint toNativePixels(const QPoint &pointPoint, const C *context)
{
if (window && window->isTopLevel() && window->screen())
return fromNativePixels(pixelPoint, window->screen());
else
return pixelPoint / QHighDpiScaling::factor(window);
return toNative(pointPoint, QHighDpiScaling::factor(context), QHighDpiScaling::origin(context));
}
inline QPoint toNativePixels(const QPoint &pointPoint, const QScreen *screen)
template <typename C>
inline QPointF fromNativePixels(const QPointF &pixelPoint, const C *context)
{
return toNative(pointPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen));
return fromNative(pixelPoint, QHighDpiScaling::factor(context), QHighDpiScaling::origin(context));
}
inline QPoint toNativePixels(const QPoint &pointPoint, const QWindow *window)
template <typename C>
inline QPointF toNativePixels(const QPointF &pointPoint, const C *context)
{
if (window && window->isTopLevel() && window->screen())
return toNativePixels(pointPoint, window->screen());
else
return pointPoint * QHighDpiScaling::factor(window);
}
inline QPointF fromNativePixels(const QPointF &pixelPoint, const QScreen *screen)
{
return fromNative(pixelPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen));
}
inline QPointF fromNativePixels(const QPointF &pixelPoint, const QWindow *window)
{
if (window && window->isTopLevel() && window->screen())
return fromNativePixels(pixelPoint, window->screen());
else
return pixelPoint / QHighDpiScaling::factor(window);
}
inline QPointF toNativePixels(const QPointF &pointPoint, const QScreen *screen)
{
return toNative(pointPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen));
}
inline QPointF toNativePixels(const QPointF &pointPoint, const QWindow *window)
{
if (window && window->isTopLevel() && window->screen())
return toNativePixels(pointPoint, window->screen());
else
return pointPoint * QHighDpiScaling::factor(window);
return toNative(pointPoint, QHighDpiScaling::factor(context), QHighDpiScaling::origin(context));
}
inline QMargins fromNativePixels(const QMargins &pixelMargins, const QWindow *window)
@ -425,47 +346,26 @@ inline QRegion toNativeLocalRegion(const QRegion &pointRegion, const QWindow *wi
}
// Any T that has operator/()
template <typename T>
T fromNativePixels(const T &pixelValue, const QWindow *window)
template <typename T, typename C>
T fromNativePixels(const T &pixelValue, const C *context)
{
if (!QHighDpiScaling::isActive())
return pixelValue;
return pixelValue / QHighDpiScaling::factor(window);
}
//##### ?????
template <typename T>
T fromNativePixels(const T &pixelValue, const QScreen *screen)
{
if (!QHighDpiScaling::isActive())
return pixelValue;
return pixelValue / QHighDpiScaling::factor(screen);
return pixelValue / QHighDpiScaling::factor(context);
}
// Any T that has operator*()
template <typename T>
T toNativePixels(const T &pointValue, const QWindow *window)
template <typename T, typename C>
T toNativePixels(const T &pointValue, const C *context)
{
if (!QHighDpiScaling::isActive())
return pointValue;
return pointValue * QHighDpiScaling::factor(window);
return pointValue * QHighDpiScaling::factor(context);
}
template <typename T>
T toNativePixels(const T &pointValue, const QScreen *screen)
{
if (!QHighDpiScaling::isActive())
return pointValue;
return pointValue * QHighDpiScaling::factor(screen);
}
// Any QVector<T> where T has operator/()
template <typename T>
QVector<T> fromNativePixels(const QVector<T> &pixelValues, const QWindow *window)

View File

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

View File

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

View File

@ -434,7 +434,7 @@ public:
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 height() const { return m_height; }

View File

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

View File

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

View File

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

View File

@ -435,8 +435,23 @@ QList<QByteArray> QMacPasteboardMimeUnicodeText::convertFromMime(const QString &
if (flavor == QLatin1String("public.utf8-plain-text"))
ret.append(string.toUtf8());
#if QT_CONFIG(textcodec)
else if (flavor == QLatin1String("public.utf16-plain-text"))
ret.append(QTextCodec::codecForName("UTF-16")->fromUnicode(string));
else if (flavor == QLatin1String("public.utf16-plain-text")) {
QTextCodec::ConverterState state;
#if defined(Q_OS_MACOS)
// Some applications such as Microsoft Excel, don't deal well with
// a BOM present, so we follow the traditional approach of Qt on
// macOS to not generate public.utf16-plain-text with a BOM.
state.flags = QTextCodec::IgnoreHeader;
#else
// Whereas iOS applications will fail to paste if we do _not_
// include a BOM in the public.utf16-plain-text content, most
// likely due to converting the data using NSUTF16StringEncoding
// which assumes big-endian byte order if there is no BOM.
state.flags = QTextCodec::DefaultConversion;
#endif
ret.append(QTextCodec::codecForName("UTF-16")->fromUnicode(
string.constData(), string.length(), &state));
}
#endif
return ret;
}

View File

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

View File

@ -581,10 +581,16 @@ void QKmsDevice::createScreens()
#if QT_CONFIG(drm_atomic)
// check atomic support
m_has_atomic_support = !drmSetClientCap(m_dri_fd, DRM_CLIENT_CAP_ATOMIC, 1)
&& qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_ATOMIC");
if (m_has_atomic_support)
qCDebug(qLcKmsDebug) << "Atomic Support found";
m_has_atomic_support = !drmSetClientCap(m_dri_fd, DRM_CLIENT_CAP_ATOMIC, 1);
if (m_has_atomic_support) {
qCDebug(qLcKmsDebug, "Atomic reported as supported");
if (qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_ATOMIC")) {
qCDebug(qLcKmsDebug, "Atomic enabled");
} else {
qCDebug(qLcKmsDebug, "Atomic disabled");
m_has_atomic_support = false;
}
}
#endif
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.
QDBusConnection c = QDBusConnection::sessionBus();
if (!c.isConnected()) {
return;
}
dbusWatcher = new QDBusServiceWatcher(A11Y_SERVICE, c, QDBusServiceWatcher::WatchForRegistration, this);
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
#ifndef __IWindowProvider_INTERFACE_DEFINED__
#define __IWindowProvider_INTERFACE_DEFINED__
DEFINE_GUID(IID_IWindowProvider, 0x987df77b, 0xdb06, 0x4d77, 0x8f,0x8a, 0x86,0xa9,0xc3,0xbb,0x90,0xb9);
MIDL_INTERFACE("987df77b-db06-4d77-8f8a-86a9c3bb90b9")
IWindowProvider : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE SetVisualState(enum WindowVisualState state) = 0;
virtual HRESULT STDMETHODCALLTYPE Close( void) = 0;
virtual HRESULT STDMETHODCALLTYPE WaitForInputIdle(int milliseconds, __RPC__out BOOL *pRetVal) = 0;
virtual HRESULT STDMETHODCALLTYPE get_CanMaximize(__RPC__out BOOL *pRetVal) = 0;
virtual HRESULT STDMETHODCALLTYPE get_CanMinimize(__RPC__out BOOL *pRetVal) = 0;
virtual HRESULT STDMETHODCALLTYPE get_IsModal(__RPC__out BOOL *pRetVal) = 0;
virtual HRESULT STDMETHODCALLTYPE get_WindowVisualState(__RPC__out enum WindowVisualState *pRetVal) = 0;
virtual HRESULT STDMETHODCALLTYPE get_WindowInteractionState(__RPC__out enum WindowInteractionState *pRetVal) = 0;
virtual HRESULT STDMETHODCALLTYPE get_IsTopmost(__RPC__out BOOL *pRetVal) = 0;
};
#ifdef __CRT_UUID_DECL
__CRT_UUID_DECL(IWindowProvider, 0x987df77b, 0xdb06, 0x4d77, 0x8f,0x8a, 0x86,0xa9,0xc3,0xbb,0x90,0xb9)
#endif
#endif
#endif

View File

@ -141,6 +141,20 @@ enum PropertyConditionFlags {
PropertyConditionFlags_IgnoreCase = 1
};
enum WindowVisualState {
WindowVisualState_Normal = 0,
WindowVisualState_Maximized = 1,
WindowVisualState_Minimized = 2
};
enum WindowInteractionState {
WindowInteractionState_Running = 0,
WindowInteractionState_Closing = 1,
WindowInteractionState_ReadyForUserInteraction = 2,
WindowInteractionState_BlockedByModalWindow = 3,
WindowInteractionState_NotResponding = 4
};
struct UiaRect {
double left;
double top;

View File

@ -1129,46 +1129,63 @@ QString QAndroidInputContext::getSelectedText(jint /*flags*/)
QString QAndroidInputContext::getTextAfterCursor(jint length, jint /*flags*/)
{
//### the preedit text could theoretically be after the cursor
QVariant textAfter = QInputMethod::queryFocusObject(Qt::ImTextAfterCursor, QVariant(length));
if (textAfter.isValid()) {
return textAfter.toString().left(length);
}
//compatibility code for old controls that do not implement the new API
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (query.isNull())
if (length <= 0)
return QString();
QString text = query->value(Qt::ImSurroundingText).toString();
if (!text.length())
return text;
QString text;
int cursorPos = query->value(Qt::ImCursorPosition).toInt();
return text.mid(cursorPos, length);
QVariant reportedTextAfter = QInputMethod::queryFocusObject(Qt::ImTextAfterCursor, length);
if (reportedTextAfter.isValid()) {
text = reportedTextAfter.toString();
} else {
// Compatibility code for old controls that do not implement the new API
QSharedPointer<QInputMethodQueryEvent> query =
focusObjectInputMethodQuery(Qt::ImCursorPosition | Qt::ImSurroundingText);
if (query) {
const int cursorPos = query->value(Qt::ImCursorPosition).toInt();
text = query->value(Qt::ImSurroundingText).toString().mid(cursorPos);
}
}
// Controls do not report preedit text, so we have to add it
if (!m_composingText.isEmpty()) {
const int cursorPosInsidePreedit = m_composingCursor - m_composingTextStart;
text = m_composingText.midRef(cursorPosInsidePreedit) + text;
}
text.truncate(length);
return text;
}
QString QAndroidInputContext::getTextBeforeCursor(jint length, jint /*flags*/)
{
QVariant textBefore = QInputMethod::queryFocusObject(Qt::ImTextBeforeCursor, QVariant(length));
if (textBefore.isValid())
return textBefore.toString().rightRef(length) + m_composingText;
//compatibility code for old controls that do not implement the new API
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (query.isNull())
if (length <= 0)
return QString();
int cursorPos = query->value(Qt::ImCursorPosition).toInt();
QString text = query->value(Qt::ImSurroundingText).toString();
if (!text.length())
return text;
QString text;
//### the preedit text does not need to be immediately before the cursor
if (cursorPos <= length)
return text.leftRef(cursorPos) + m_composingText;
else
return text.midRef(cursorPos - length, length) + m_composingText;
QVariant reportedTextBefore = QInputMethod::queryFocusObject(Qt::ImTextBeforeCursor, length);
if (reportedTextBefore.isValid()) {
text = reportedTextBefore.toString();
} else {
// Compatibility code for old controls that do not implement the new API
QSharedPointer<QInputMethodQueryEvent> query =
focusObjectInputMethodQuery(Qt::ImCursorPosition | Qt::ImSurroundingText);
if (query) {
const int cursorPos = query->value(Qt::ImCursorPosition).toInt();
text = query->value(Qt::ImSurroundingText).toString().left(cursorPos);
}
}
// Controls do not report preedit text, so we have to add it
if (!m_composingText.isEmpty()) {
const int cursorPosInsidePreedit = m_composingCursor - m_composingTextStart;
text += m_composingText.leftRef(cursorPosInsidePreedit);
}
if (text.length() > length)
text = text.right(length);
return text;
}
/*
@ -1231,6 +1248,8 @@ jboolean QAndroidInputContext::setComposingRegion(jint start, jint end)
if (query.isNull())
return JNI_FALSE;
if (start == end)
return JNI_TRUE;
if (start > end)
qSwap(start, end);

View File

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

View File

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

View File

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

View File

@ -834,9 +834,14 @@ static void executeBlockWithoutAnimation(Block block)
- (void)updateSelection
{
if (!hasSelection()) {
if (_cursorLayer.visible) {
_cursorLayer.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;
}
return;
}

View File

@ -48,6 +48,7 @@
#include <QtGui/qscreen.h>
#include <qpa/qwindowsysteminterface.h>
#include <QtCore/qcoreapplication.h>
#include <qpa/qplatforminputcontextfactory_p.h>
#include <emscripten/bind.h>
#include <emscripten/val.h>
@ -180,6 +181,18 @@ QPlatformOpenGLContext *QWasmIntegration::createPlatformOpenGLContext(QOpenGLCon
}
#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
{
if (m_fontDb == nullptr)

View File

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

View File

@ -37,6 +37,14 @@ QWasmOpenGLContext::QWasmOpenGLContext(const QSurfaceFormat &format)
: m_requestedFormat(format)
{
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()
@ -91,10 +99,14 @@ EMSCRIPTEN_WEBGL_CONTEXT_HANDLE QWasmOpenGLContext::createEmscriptenContext(cons
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
attributes.alpha = format.alphaBufferSize() > 0;
attributes.depth = format.depthBufferSize() > 0;
attributes.stencil = format.stencilBufferSize() > 0;
attributes.depth = useDepthStencil;
attributes.stencil = useDepthStencil;
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context(canvasId.toLocal8Bit().constData(), &attributes);

View File

@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>APPNAME</title>
<title>@APPNAME@</title>
<style>
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 */
@ -18,7 +18,7 @@
<figure style="overflow:visible;" id="qtspinner">
<center style="margin-top:1.5em; line-height:150%">
<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>
<noscript>JavaScript is disabled. Please enable JavaScript to use this application.</noscript>
</center>
@ -57,7 +57,7 @@
canvas.style.display = 'block';
},
});
qtLoader.loadEmscriptenModule("APPNAME");
qtLoader.loadEmscriptenModule("@APPNAME@");
}
</script>
<script type="text/javascript" src="qtloader.js"></script>

View File

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

View File

@ -157,6 +157,12 @@ QTouchDevice *QWindowsMouseHandler::ensureTouchDevice()
return m_touchDevice;
}
void QWindowsMouseHandler::clearEvents()
{
m_lastEventType = QEvent::None;
m_lastEventButton = Qt::NoButton;
}
Qt::MouseButtons QWindowsMouseHandler::queryMouseButtons()
{
Qt::MouseButtons result = nullptr;
@ -293,8 +299,6 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
Qt::MouseEventSource source = Qt::MouseEventNotSynthesized;
const MouseEvent mouseEvent = eventFromMsg(msg);
// Check for events synthesized from touch. Lower byte is touch index, 0 means pen.
static const bool passSynthesizedMouseEvents =
!(QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch);
@ -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) {
const Qt::MouseButtons buttons = QWindowsMouseHandler::queryMouseButtons();
QWindowSystemInterface::handleFrameStrutMouseEvent(window, clientPosition,
globalPosition, buttons,
mouseEvent.button, mouseEvent.type,
QWindowsKeyMapper::queryKeyboardModifiers(),
source);
keyModifiers, source);
return false; // Allow further event processing (dragging of windows).
}
@ -340,7 +371,6 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
}
QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle());
const Qt::MouseButtons buttons = keyStateToMouseButtons(int(msg.wParam));
// If the window was recently resized via mouse doubleclick on the frame or title bar,
// we don't get WM_LBUTTONDOWN or WM_LBUTTONDBLCLK for the second click,
@ -467,8 +497,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
if (!discardEvent && mouseEvent.type != QEvent::None) {
QWindowSystemInterface::handleMouseEvent(window, winEventPosition, globalPosition, buttons,
mouseEvent.button, mouseEvent.type,
QWindowsKeyMapper::queryKeyboardModifiers(),
source);
keyModifiers, source);
}
m_previousCaptureWindow = hasCapture ? window : nullptr;
// QTBUG-48117, force synchronous handling for the extra buttons so that WM_APPCOMMAND

View File

@ -45,6 +45,7 @@
#include <QtCore/qpointer.h>
#include <QtCore/qhash.h>
#include <QtGui/qevent.h>
QT_BEGIN_NAMESPACE
@ -72,13 +73,14 @@ public:
bool translateScrollEvent(QWindow *window, HWND hwnd,
MSG msg, LRESULT *result);
static inline Qt::MouseButtons keyStateToMouseButtons(int);
static inline Qt::MouseButtons keyStateToMouseButtons(WPARAM);
static inline Qt::KeyboardModifiers keyStateToModifiers(int);
static inline int mouseButtonsToKeyState(Qt::MouseButtons);
static Qt::MouseButtons queryMouseButtons();
QWindow *windowUnderMouse() const { return m_windowUnderMouse.data(); }
void clearWindowUnderMouse() { m_windowUnderMouse = 0; }
void clearEvents();
private:
inline bool translateMouseWheelEvent(QWindow *window, HWND hwnd,
@ -91,9 +93,11 @@ private:
QTouchDevice *m_touchDevice = nullptr;
bool m_leftButtonDown = false;
QWindow *m_previousCaptureWindow = nullptr;
QEvent::Type m_lastEventType = QEvent::None;
Qt::MouseButton m_lastEventButton = Qt::NoButton;
};
Qt::MouseButtons QWindowsMouseHandler::keyStateToMouseButtons(int wParam)
Qt::MouseButtons QWindowsMouseHandler::keyStateToMouseButtons(WPARAM wParam)
{
Qt::MouseButtons mb(Qt::NoButton);
if (wParam & MK_LBUTTON)

View File

@ -336,6 +336,12 @@ QTouchDevice *QWindowsPointerHandler::ensureTouchDevice()
return m_touchDevice;
}
void QWindowsPointerHandler::clearEvents()
{
m_lastEventType = QEvent::None;
m_lastEventButton = Qt::NoButton;
}
void QWindowsPointerHandler::handleCaptureRelease(QWindow *window,
QWindow *currentWindowUnderPointer,
HWND hwnd,
@ -732,10 +738,35 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
}
const MouseEvent mouseEvent = eventFromMsg(msg);
Qt::MouseButtons mouseButtons;
if (mouseEvent.type >= QEvent::NonClientAreaMouseMove && mouseEvent.type <= QEvent::NonClientAreaMouseButtonDblClick)
mouseButtons = queryMouseButtons();
else
mouseButtons = mouseButtonsFromKeyState(msg.wParam);
// When the left/right mouse buttons are pressed over the window title bar
// WM_NCLBUTTONDOWN/WM_NCRBUTTONDOWN messages are received. But no UP
// messages are received on release, only WM_NCMOUSEMOVE/WM_MOUSEMOVE.
// We detect it and generate the missing release events here. (QTBUG-75678)
// The last event vars are cleared on QWindowsContext::handleExitSizeMove()
// to avoid generating duplicated release events.
if (m_lastEventType == QEvent::NonClientAreaMouseButtonPress
&& (mouseEvent.type == QEvent::NonClientAreaMouseMove || mouseEvent.type == QEvent::MouseMove)
&& (m_lastEventButton & mouseButtons) == 0) {
if (mouseEvent.type == QEvent::NonClientAreaMouseMove) {
QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, mouseButtons, m_lastEventButton,
QEvent::NonClientAreaMouseButtonRelease, keyModifiers, source);
} else {
QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons, m_lastEventButton,
QEvent::MouseButtonRelease, keyModifiers, source);
}
}
m_lastEventType = mouseEvent.type;
m_lastEventButton = mouseEvent.button;
if (mouseEvent.type >= QEvent::NonClientAreaMouseMove && mouseEvent.type <= QEvent::NonClientAreaMouseButtonDblClick) {
const Qt::MouseButtons nonclientButtons = queryMouseButtons();
QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, nonclientButtons,
QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, mouseButtons,
mouseEvent.button, mouseEvent.type, keyModifiers, source);
return false; // Allow further event processing
}
@ -751,8 +782,6 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
return true;
}
const Qt::MouseButtons mouseButtons = mouseButtonsFromKeyState(msg.wParam);
handleCaptureRelease(window, currentWindowUnderPointer, hwnd, mouseEvent.type, mouseButtons);
handleEnterLeave(window, currentWindowUnderPointer, globalPos);

View File

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

View File

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

View File

@ -0,0 +1,168 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtGui/qtguiglobal.h>
#if QT_CONFIG(accessibility)
#include "qwindowsuiawindowprovider.h"
#include "qwindowsuiautils.h"
#include "qwindowscontext.h"
#include <QtGui/qaccessible.h>
#include <QtGui/private/qwindow_p.h>
#include <QtCore/qloggingcategory.h>
#include <QtCore/qstring.h>
QT_BEGIN_NAMESPACE
using namespace QWindowsUiAutomation;
QWindowsUiaWindowProvider::QWindowsUiaWindowProvider(QAccessible::Id id) :
QWindowsUiaBaseProvider(id)
{
}
QWindowsUiaWindowProvider::~QWindowsUiaWindowProvider()
{
}
HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::SetVisualState(WindowVisualState state) {
qCDebug(lcQpaUiAutomation) << __FUNCTION__;
QAccessibleInterface *accessible = accessibleInterface();
if (!accessible || !accessible->window())
return UIA_E_ELEMENTNOTAVAILABLE;
auto window = accessible->window();
switch (state) {
case WindowVisualState_Normal:
window->showNormal();
break;
case WindowVisualState_Maximized:
window->showMaximized();
break;
case WindowVisualState_Minimized:
window->showMinimized();
break;
}
return S_OK;
}
HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::Close() {
qCDebug(lcQpaUiAutomation) << __FUNCTION__;
QAccessibleInterface *accessible = accessibleInterface();
if (!accessible || !accessible->window())
return UIA_E_ELEMENTNOTAVAILABLE;
accessible->window()->close();
return S_OK;
}
HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::WaitForInputIdle(int milliseconds, __RPC__out BOOL *pRetVal) {
Q_UNUSED(milliseconds);
Q_UNUSED(pRetVal);
return UIA_E_NOTSUPPORTED;
}
HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::get_CanMaximize(__RPC__out BOOL *pRetVal) {
qCDebug(lcQpaUiAutomation) << __FUNCTION__;
QAccessibleInterface *accessible = accessibleInterface();
if (!accessible || !accessible->window())
return UIA_E_ELEMENTNOTAVAILABLE;
auto window = accessible->window();
auto flags = window->flags();
*pRetVal = (!(flags & Qt::MSWindowsFixedSizeDialogHint)
&& (flags & Qt::WindowMaximizeButtonHint)
&& ((flags & Qt::CustomizeWindowHint)
|| window->maximumSize() == QSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX)));
return S_OK;
}
HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::get_CanMinimize(__RPC__out BOOL *pRetVal) {
qCDebug(lcQpaUiAutomation) << __FUNCTION__;
QAccessibleInterface *accessible = accessibleInterface();
if (!accessible || !accessible->window())
return UIA_E_ELEMENTNOTAVAILABLE;
*pRetVal = accessible->window()->flags() & Qt::WindowMinimizeButtonHint;
return S_OK;
}
HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::get_IsModal(__RPC__out BOOL *pRetVal) {
qCDebug(lcQpaUiAutomation) << __FUNCTION__;
QAccessibleInterface *accessible = accessibleInterface();
if (!accessible || !accessible->window())
return UIA_E_ELEMENTNOTAVAILABLE;
*pRetVal = accessible->window()->isModal();
return S_OK;
}
HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::get_WindowVisualState(__RPC__out enum WindowVisualState *pRetVal) {
qCDebug(lcQpaUiAutomation) << __FUNCTION__;
QAccessibleInterface *accessible = accessibleInterface();
if (!accessible || !accessible->window())
return UIA_E_ELEMENTNOTAVAILABLE;
auto visibility = accessible->window()->visibility();
switch (visibility) {
case QWindow::FullScreen:
case QWindow::Maximized:
*pRetVal = WindowVisualState_Maximized;
break;
case QWindow::Minimized:
*pRetVal = WindowVisualState_Minimized;
break;
default:
*pRetVal = WindowVisualState_Normal;
break;
}
return S_OK;
}
HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::get_WindowInteractionState(__RPC__out enum WindowInteractionState *pRetVal) {
Q_UNUSED(pRetVal);
return UIA_E_NOTSUPPORTED;
}
HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::get_IsTopmost(__RPC__out BOOL *pRetVal) {
Q_UNUSED(pRetVal);
return UIA_E_NOTSUPPORTED;
}
QT_END_NAMESPACE
#endif // QT_CONFIG(accessibility)

View File

@ -0,0 +1,73 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWINDOWSUIAWINDOWPROVIDER_H
#define QWINDOWSUIAWINDOWPROVIDER_H
#include <QtGui/qtguiglobal.h>
#if QT_CONFIG(accessibility)
#include "qwindowsuiabaseprovider.h"
QT_BEGIN_NAMESPACE
class QWindowsUiaWindowProvider : public QWindowsUiaBaseProvider,
public QWindowsComBase<IWindowProvider>
{
Q_DISABLE_COPY(QWindowsUiaWindowProvider)
public:
explicit QWindowsUiaWindowProvider(QAccessible::Id id);
~QWindowsUiaWindowProvider() override;
HRESULT STDMETHODCALLTYPE SetVisualState(WindowVisualState state) override;
HRESULT STDMETHODCALLTYPE Close( void) override;
HRESULT STDMETHODCALLTYPE WaitForInputIdle(int milliseconds, __RPC__out BOOL *pRetVal) override;
HRESULT STDMETHODCALLTYPE get_CanMaximize(__RPC__out BOOL *pRetVal) override;
HRESULT STDMETHODCALLTYPE get_CanMinimize(__RPC__out BOOL *pRetVal) override;
HRESULT STDMETHODCALLTYPE get_IsModal(__RPC__out BOOL *pRetVal) override;
HRESULT STDMETHODCALLTYPE get_WindowVisualState(__RPC__out WindowVisualState *pRetVal) override;
HRESULT STDMETHODCALLTYPE get_WindowInteractionState(__RPC__out WindowInteractionState *pRetVal) override;
HRESULT STDMETHODCALLTYPE get_IsTopmost(__RPC__out BOOL *pRetVal) override;
};
QT_END_NAMESPACE
#endif // QT_CONFIG(accessibility)
#endif // QWINDOWSUIAWINDOWPROVIDER_H

View File

@ -18,6 +18,7 @@ SOURCES += \
$$PWD/qwindowsuiatableitemprovider.cpp \
$$PWD/qwindowsuiagridprovider.cpp \
$$PWD/qwindowsuiagriditemprovider.cpp \
$$PWD/qwindowsuiawindowprovider.cpp \
$$PWD/qwindowsuiautils.cpp
HEADERS += \
@ -37,6 +38,7 @@ HEADERS += \
$$PWD/qwindowsuiatableitemprovider.h \
$$PWD/qwindowsuiagridprovider.h \
$$PWD/qwindowsuiagriditemprovider.h \
$$PWD/qwindowsuiawindowprovider.h \
$$PWD/qwindowsuiautils.h
mingw: QMAKE_USE *= uuid

View File

@ -44,6 +44,8 @@
#include <QtCore/qfunctions_winrt.h>
#include <QtGui/QPalette>
#include <QtFontDatabaseSupport/private/qwinrtfontdatabase_p.h>
#include <wrl.h>
#include <windows.ui.h>
#include <windows.ui.viewmanagement.h>
@ -96,7 +98,13 @@ static IUISettings *uiSettings()
class QWinRTThemePrivate
{
public:
QWinRTThemePrivate()
: monospaceFont(QWinRTFontDatabase::familyForStyleHint(QFont::Monospace))
{
}
QPalette palette;
QFont monospaceFont;
};
static inline QColor fromColor(const Color &color)
@ -321,4 +329,14 @@ const QPalette *QWinRTTheme::palette(Palette type) const
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

View File

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

View File

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

View File

@ -150,6 +150,16 @@ static QWindow *qt_getWindow(const QWidget *widget)
QT_NAMESPACE_ALIAS_OBJC_CLASS(NotificationReceiver);
@implementation NotificationReceiver
{
QMacStylePrivate *privateStyle;
}
- (instancetype)initWithPrivateStyle:(QMacStylePrivate *)style
{
if (self = [super init])
privateStyle = style;
return self;
}
- (void)scrollBarStyleDidChange:(NSNotification *)notification
{
@ -162,6 +172,23 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(NotificationReceiver);
for (const auto &o : QMacStylePrivate::scrollBars)
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
@interface QT_MANGLE_NAMESPACE(QIndeterminateProgressIndicator) : NSProgressIndicator
@ -2068,11 +2095,17 @@ QMacStyle::QMacStyle()
Q_D(QMacStyle);
QMacAutoReleasePool pool;
d->receiver = [[NotificationReceiver alloc] init];
d->receiver = [[NotificationReceiver alloc] initWithPrivateStyle:d];
[[NSNotificationCenter defaultCenter] addObserver:d->receiver
selector:@selector(scrollBarStyleDidChange:)
name:NSPreferredScrollerStyleDidChangeNotification
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()
@ -2081,6 +2114,10 @@ QMacStyle::~QMacStyle()
QMacAutoReleasePool pool;
[[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];
}
@ -6129,8 +6166,9 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
switch (ct) {
#if QT_CONFIG(spinbox)
case CT_SpinBox:
if (qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
const int buttonWidth = 20; // FIXME Use subControlRect()
if (const QStyleOptionSpinBox *vopt = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
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);
}
break;

View File

@ -1864,6 +1864,9 @@ void QColorDialogPrivate::_q_addCustom()
void QColorDialogPrivate::retranslateStrings()
{
if (nativeDialogInUse)
return;
if (!smallDisplay) {
lblBasicColors->setText(QColorDialog::tr("&Basic colors"));
lblCustomColors->setText(QColorDialog::tr("&Custom colors"));

View File

@ -0,0 +1,5 @@
#! [qt5_wrap_ui]
set(SOURCES mainwindow.cpp main.cpp)
qt5_wrap_ui(SOURCES mainwindow.ui)
add_executable(myapp ${SOURCES})
#! [qt5_wrap_ui]

View File

@ -0,0 +1,60 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\page qtwidgets-cmake-qt5-wrap-ui.html
\ingroup cmake-macros-qtwidgets
\title qt5_wrap_ui
\brief Creates sources for \c{.ui} files.
\section1 Synopsis
\badcode
qt5_wrap_ui(<VAR> ui_file1 [ui_file2 ...]
[OPTIONS ...])
\endcode
\section1 Description
Creates rules for calling \l{uic}{User Interface Compiler (uic)} on the given
\c{.ui} files. For each input file, an header file is generated in the build
directory. The paths of the generated header files are added to\c{<VAR>}.
\note This is a low-level macro. See the \l{CMake AUTOUIC Documentation} for a
more convenient way to process \c{.ui} files with \c{uic}.
\section1 Options
You can set additional \c{OPTIONS} that should be added to the \c{uic} calls.
You can find possible options in the \l{uic}{uic documentation}.
\section1 Examples
\snippet cmake-macros/examples.cmake qt5_wrap_ui
*/

View File

@ -9795,9 +9795,9 @@ QRectF QGraphicsPixmapItem::boundingRect() const
return QRectF();
if (d->flags & ItemIsSelectable) {
qreal pw = 1.0;
return QRectF(d->offset, d->pixmap.size() / d->pixmap.devicePixelRatio()).adjusted(-pw/2, -pw/2, pw/2, pw/2);
return QRectF(d->offset, QSizeF(d->pixmap.size()) / d->pixmap.devicePixelRatio()).adjusted(-pw/2, -pw/2, pw/2, pw/2);
} else {
return QRectF(d->offset, d->pixmap.size() / d->pixmap.devicePixelRatio());
return QRectF(d->offset, QSizeF(d->pixmap.size()) / d->pixmap.devicePixelRatio());
}
}

View File

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

View File

@ -2578,14 +2578,15 @@ void QWidgetPrivate::createWinId()
/*!
\internal
Ensures that the widget is set on the screen point is on. This is handy getting a correct
size hint before a resize in e.g QMenu and QToolTip
size hint before a resize in e.g QMenu and QToolTip.
Returns if the screen was changed.
*/
void QWidgetPrivate::setScreenForPoint(const QPoint &pos)
bool QWidgetPrivate::setScreenForPoint(const QPoint &pos)
{
Q_Q(QWidget);
if (!q->isWindow())
return;
return false;
// Find the screen for pos and make the widget undertand it is on that screen.
const QScreen *currentScreen = windowHandle() ? windowHandle()->screen() : nullptr;
QScreen *actualScreen = QGuiApplication::screenAt(pos);
@ -2594,7 +2595,9 @@ void QWidgetPrivate::setScreenForPoint(const QPoint &pos)
createWinId();
if (windowHandle())
windowHandle()->setScreen(actualScreen);
return true;
}
return false;
}
/*!

View File

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

View File

@ -5029,7 +5029,8 @@ QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
case CT_SpinBox:
if (const QStyleOptionSpinBox *vopt = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
// 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;
sz += QSize(buttonWidth + 2*fw, 2*fw);
}

View File

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

View File

@ -976,18 +976,48 @@ void QCompleterPrivate::showPopup(const QRect& rect)
popup->show();
}
#if QT_CONFIG(filesystemmodel)
static bool isRoot(const QFileSystemModel *model, const QString &path)
{
const auto index = model->index(path);
return index.isValid() && model->fileInfo(index).isRoot();
}
static bool completeOnLoaded(const QFileSystemModel *model,
const QString &nativePrefix,
const QString &path,
Qt::CaseSensitivity caseSensitivity)
{
const auto pathSize = path.size();
const auto prefixSize = nativePrefix.size();
if (prefixSize < pathSize)
return false;
const QString prefix = QDir::fromNativeSeparators(nativePrefix);
if (prefixSize == pathSize)
return path.compare(prefix, caseSensitivity) == 0 && isRoot(model, path);
// The user is typing something within that directory and is not in a subdirectory yet.
const auto separator = QLatin1Char('/');
return prefix.startsWith(path, caseSensitivity) && prefix.at(pathSize) == separator
&& !prefix.rightRef(prefixSize - pathSize - 1).contains(separator);
}
void QCompleterPrivate::_q_fileSystemModelDirectoryLoaded(const QString &path)
{
Q_Q(QCompleter);
// Slot called when QFileSystemModel has finished loading.
// If we hide the popup because there was no match because the model was not loaded yet,
// we re-start the completion when we get the results
if (hiddenBecauseNoMatch
&& prefix.startsWith(path) && prefix != (path + QLatin1Char('/'))
&& widget) {
// we re-start the completion when we get the results (unless triggered by
// something else, see QTBUG-14292).
if (hiddenBecauseNoMatch && widget) {
if (auto model = qobject_cast<const QFileSystemModel *>(proxy->sourceModel())) {
if (completeOnLoaded(model, prefix, path, cs))
q->complete();
}
}
}
#else // QT_CONFIG(filesystemmodel)
void QCompleterPrivate::_q_fileSystemModelDirectoryLoaded(const QString &) {}
#endif
/*!
Constructs a completer object with the given \a parent.

View File

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

View File

@ -73,6 +73,7 @@
#endif
#include "qpushbutton.h"
#include "qtooltip.h"
#include <qwindow.h>
#include <private/qpushbutton_p.h>
#include <private/qaction_p.h>
#include <private/qguiapplication_p.h>
@ -1485,6 +1486,8 @@ void QMenuPrivate::_q_platformMenuAboutToShow()
{
Q_Q(QMenu);
emit q->aboutToShow();
#ifdef Q_OS_OSX
if (platformMenu) {
const auto actions = q->actions();
@ -1498,8 +1501,6 @@ void QMenuPrivate::_q_platformMenuAboutToShow()
}
}
#endif
emit q->aboutToShow();
}
bool QMenuPrivate::hasMouseMoved(const QPoint &globalPos)
@ -2328,8 +2329,10 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
d->motions = 0;
d->doChildEffects = true;
d->updateLayoutDirection();
// Ensure that we get correct sizeHints by placing this window on the right screen.
d->setScreenForPoint(p);
// Ensure that we get correct sizeHints by placing this window on the correct screen.
if (d->setScreenForPoint(p))
d->itemsDirty = true;
const bool contextMenu = d->isContextMenu();
if (d->lastContextMenu != contextMenu) {

View File

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

View File

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

View File

@ -30,8 +30,10 @@
\title Qt XML
\brief The Qt XML module provides C++ implementations of the SAX and DOM standards for XML.
The module is not actively maintained anymore. Please use
the QXmlStreamReader and QXmlStreamWriter classes in Qt Core instead.
Note that the module will not receive additional features anymore. For reading or writing XML
documents iteratively (SAX), we recommend using Qt Core's QXmlStreamReader and
QXmlStreamWriter classes. The classes are both easier to use and more compliant with the
XML standard.
To include the definitions of the module's classes, use the
following directive:

View File

@ -33,8 +33,10 @@
\brief The Qt XML module provides C++ implementations of the SAX and DOM standards for XML.
The module is not actively maintained anymore. Please use
the \l{QXmlStreamReader} and \l{QXmlStreamWriter} classes in \l{Qt Core} instead.
Note that the module will not receive additional features anymore. For reading or writing XML
documents iteratively (SAX), we recommend using Qt Core's QXmlStreamReader and
QXmlStreamWriter classes. The classes are both easier to use and more compliant with the
XML standard.
To include the definitions of the module's classes, use the
following directive:

View File

@ -174,6 +174,8 @@ void tst_qfloat16::qNan()
QVERIFY(qIsInf(-inf));
QVERIFY(qIsInf(2.f*inf));
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));
#ifdef Q_CC_INTEL
QEXPECT_FAIL("", "ICC optimizes zero * anything to zero", Continue);

View File

@ -655,6 +655,8 @@ void tst_QFileInfo::canonicalFilePath()
QVERIFY(tempFile.open(QFile::WriteOnly));
QFileInfo fi(tempFile.fileName());
QCOMPARE(fi.canonicalFilePath(), QDir::currentPath() + "/" + fileName);
fi = QFileInfo(tempFile.fileName() + QString::fromLatin1("/"));
QCOMPARE(fi.canonicalFilePath(), QString::fromLatin1(""));
tempFile.remove();
// 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 pos = 0; pos < latin1Whitespace.size() - len; ++pos) {
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);
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -26,8 +26,6 @@
**
****************************************************************************/
#include <QtGui>
#include <QApplication>
#include "base.h"
@ -35,7 +33,6 @@ int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QApplication::setAttribute(Qt::AA_NativeWindows); //QTBUG-15774
base *b = new base();
Q_UNUSED(b);
base b;
return app.exec();
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -54,12 +54,25 @@
using namespace QTestPrivate;
// Compare a window position that may go through scaling in the platform plugin with fuzz.
static inline bool qFuzzyCompareWindowPosition(const QPoint &p1, const QPoint p2, int fuzz)
{
return (p1 - p2).manhattanLength() <= fuzz;
}
static QString msgPointMismatch(const QPoint &p1, const QPoint p2)
{
QString result;
QDebug(&result) << p1 << "!=" << p2 << ", manhattanLength=" << (p1 - p2).manhattanLength();
return result;
}
class tst_QWidget_window : public QObject
{
Q_OBJECT
public:
tst_QWidget_window(){};
tst_QWidget_window();
public slots:
void initTestCase();
@ -110,8 +123,20 @@ private slots:
void nativeShow();
void QTBUG_56277_resize_on_showEvent();
private:
QSize m_testWidgetSize;
const int m_fuzz;
};
tst_QWidget_window::tst_QWidget_window() :
m_fuzz(int(QHighDpiScaling::factor(QGuiApplication::primaryScreen())))
{
const int screenWidth = QGuiApplication::primaryScreen()->geometry().width();
const int width = qMax(200, 100 * ((screenWidth + 500) / 1000));
m_testWidgetSize = QSize(width, width);
}
void tst_QWidget_window::initTestCase()
{
}
@ -162,65 +187,65 @@ void tst_QWidget_window::tst_min_max_size()
void tst_QWidget_window::tst_move_show()
{
QWidget w;
w.move(100, 100);
const QPoint pos(100, 100);
w.move(pos);
w.show();
#ifdef Q_OS_WINRT
QEXPECT_FAIL("", "Winrt does not support move", Abort);
#endif
QCOMPARE(w.pos(), QPoint(100, 100));
// QCoreApplication::processEvents(QEventLoop::AllEvents, 3000);
QVERIFY2(qFuzzyCompareWindowPosition(w.pos(), pos, m_fuzz),
qPrintable(msgPointMismatch(w.pos(), pos)));
}
void tst_QWidget_window::tst_show_move()
{
QWidget w;
w.show();
w.move(100, 100);
QCOMPARE(w.pos(), QPoint(100, 100));
// QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
const QPoint pos(100, 100);
w.move(pos);
QVERIFY2(qFuzzyCompareWindowPosition(w.pos(), pos, m_fuzz),
qPrintable(msgPointMismatch(w.pos(), pos)));
}
void tst_QWidget_window::tst_show_move_hide_show()
{
QWidget w;
w.show();
w.move(100, 100);
const QPoint pos(100, 100);
w.move(pos);
w.hide();
w.show();
QCOMPARE(w.pos(), QPoint(100, 100));
// QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
QVERIFY2(qFuzzyCompareWindowPosition(w.pos(), pos, m_fuzz),
qPrintable(msgPointMismatch(w.pos(), pos)));
}
void tst_QWidget_window::tst_resize_show()
{
QWidget w;
w.resize(200, 200);
w.resize(m_testWidgetSize);
w.show();
#ifdef Q_OS_WINRT
QEXPECT_FAIL("", "Winrt does not support resize", Abort);
#endif
QCOMPARE(w.size(), QSize(200, 200));
// QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
QCOMPARE(w.size(), m_testWidgetSize);
}
void tst_QWidget_window::tst_show_resize()
{
QWidget w;
w.show();
w.resize(200, 200);
QCOMPARE(w.size(), QSize(200, 200));
// QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
w.resize(m_testWidgetSize);
QCOMPARE(w.size(), m_testWidgetSize);
}
void tst_QWidget_window::tst_show_resize_hide_show()
{
QWidget w;
w.show();
w.resize(200, 200);
w.resize(m_testWidgetSize);
w.hide();
w.show();
QCOMPARE(w.size(), QSize(200, 200));
// QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
QCOMPARE(w.size(), m_testWidgetSize);
}
class PaintTestWidget : public QWidget
@ -857,7 +882,7 @@ void tst_QWidget_window::tst_updateWinId_QTBUG40681()
lbl->setAttribute(Qt::WA_NativeWindow);
lbl->setObjectName("label1");
vl->addWidget(lbl);
w.setMinimumWidth(200);
w.setMinimumWidth(m_testWidgetSize.width());
w.show();
@ -880,6 +905,7 @@ void tst_QWidget_window::tst_updateWinId_QTBUG40681()
void tst_QWidget_window::tst_recreateWindow_QTBUG40817()
{
QTabWidget tab;
tab.setMinimumWidth(m_testWidgetSize.width());
QWidget *w = new QWidget;
tab.addTab(w, "Tab1");
@ -946,7 +972,7 @@ void tst_QWidget_window::tst_resize_count()
resize.resizeCount = 0;
ResizeWidget child(&resize);
child.resize(200,200);
child.resize(m_testWidgetSize);
child.winId();
child.show();
QVERIFY(QTest::qWaitForWindowExposed(&child));
@ -963,7 +989,7 @@ void tst_QWidget_window::tst_resize_count()
{
ResizeWidget parent;
ResizeWidget child(&parent);
child.resize(200,200);
child.resize(m_testWidgetSize);
child.winId();
parent.show();
QVERIFY(QTest::qWaitForWindowExposed(&parent));
@ -1076,6 +1102,7 @@ void tst_QWidget_window::QTBUG_50561_QCocoaBackingStore_paintDevice_crash()
ApplicationStateSaver as;
QMainWindow w;
w.setMinimumWidth(m_testWidgetSize.width());
w.addToolBar(new QToolBar(&w));
w.show();
QVERIFY(QTest::qWaitForWindowExposed(&w));

View File

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

View File

@ -461,26 +461,30 @@ void tst_QSpinBox::setPrefixSuffix()
QFETCH(QString, expectedCleanText);
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();
spin.setPrefix(prefix);
const QSize size2 = spin.sizeHint();
spin.setSuffix(suffix);
const QSize size3 = spin.sizeHint();
spin.setValue(value);
if (show)
spin.show();
QCOMPARE(spin.prefix(), prefix);
QCOMPARE(spin.suffix(), suffix);
QCOMPARE(spin.text(), expectedText);
QCOMPARE(spin.cleanText(), expectedCleanText);
if (!prefix.isEmpty() && !suffix.isEmpty()) {
QVERIFY(size1.width() < size2.width());
if (!suffix.isEmpty()) {
QVERIFY(size2.width() < size3.width());
spin.setSuffix(QString());
QCOMPARE(spin.sizeHint(), size2);
}
if (!prefix.isEmpty()) {
QVERIFY(size1.width() < size2.width());
spin.setPrefix(QString());
QCOMPARE(spin.sizeHint(), size1);
}