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

Conflicts:
	.qmake.conf
	src/corelib/doc/src/objectmodel/signalsandslots.qdoc
	src/plugins/platforms/cocoa/qcocoamenuloader.mm
	src/plugins/platforms/xcb/qxcbconnection.cpp
	src/plugins/platforms/xcb/qxcbconnection.h
	src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
	src/plugins/platforms/xcb/qxcbwindow.cpp
	tests/auto/gui/image/qimage/tst_qimage.cpp

Done-with: Gatis Paeglis <gatis.paeglis@qt.io>
Change-Id: I9bd24ee9b00d4f26c8f344ce3970aa6e93935ff5
This commit is contained in:
Qt Forward Merge Bot 2018-08-03 01:00:16 +02:00 committed by Edward Welbourne
commit 053e7cce79
57 changed files with 846 additions and 504 deletions

View File

@ -520,7 +520,7 @@
\title Qt Creator: Adding Debuggers \title Qt Creator: Adding Debuggers
*/ */
/*! /*!
\externalpage http://doc.qt.io/qtcreator/qtcreator-accelbubble-example.html \externalpage http://doc.qt.io/qtcreator/qt-creator-accelbubble-example.html
\title Qt Creator: Creating a Mobile Application \title Qt Creator: Creating a Mobile Application
*/ */
/*! /*!

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -106,16 +106,16 @@ public:
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
//! [3] //! [4] //! [3] //! [4]
#define BrushInterface_iid "org.qt-project.Qt.Examples.PlugAndPaint.BrushInterface" #define BrushInterface_iid "org.qt-project.Qt.Examples.PlugAndPaint.BrushInterface/1.0"
Q_DECLARE_INTERFACE(BrushInterface, BrushInterface_iid) Q_DECLARE_INTERFACE(BrushInterface, BrushInterface_iid)
//! [3] //! [3]
#define ShapeInterface_iid "org.qt-project.Qt.Examples.PlugAndPaint.ShapeInterface" #define ShapeInterface_iid "org.qt-project.Qt.Examples.PlugAndPaint.ShapeInterface/1.0"
Q_DECLARE_INTERFACE(ShapeInterface, ShapeInterface_iid) Q_DECLARE_INTERFACE(ShapeInterface, ShapeInterface_iid)
//! [5] //! [5]
#define FilterInterface_iid "org.qt-project.Qt.Examples.PlugAndPaint.FilterInterface" #define FilterInterface_iid "org.qt-project.Qt.Examples.PlugAndPaint.FilterInterface/1.0"
Q_DECLARE_INTERFACE(FilterInterface, FilterInterface_iid) Q_DECLARE_INTERFACE(FilterInterface, FilterInterface_iid)
//! [4] //! [5] //! [4] //! [5]

View File

@ -18,7 +18,7 @@ include(g++-base.conf)
MAKEFILE_GENERATOR = MINGW MAKEFILE_GENERATOR = MINGW
QMAKE_PLATFORM = win32 mingw QMAKE_PLATFORM = win32 mingw
CONFIG += debug_and_release debug_and_release_target precompile_header CONFIG += debug_and_release debug_and_release_target precompile_header
DEFINES += UNICODE _UNICODE WIN32 DEFINES += UNICODE _UNICODE WIN32 MINGW_HAS_SECURE_API=1
QMAKE_COMPILER_DEFINES += __GNUC__ _WIN32 QMAKE_COMPILER_DEFINES += __GNUC__ _WIN32
# can't add 'DEFINES += WIN64' and 'QMAKE_COMPILER_DEFINES += _WIN64' defines for # can't add 'DEFINES += WIN64' and 'QMAKE_COMPILER_DEFINES += _WIN64' defines for
# x86_64 platform similar to 'msvc-desktop.conf' toolchain, because, unlike for MSVC, # x86_64 platform similar to 'msvc-desktop.conf' toolchain, because, unlike for MSVC,

View File

@ -1,5 +1,5 @@
EXEEXT = .exe EXEEXT = .exe
EXTRA_CXXFLAGS = -DUNICODE EXTRA_CXXFLAGS = -DUNICODE -DMINGW_HAS_SECURE_API=1
EXTRA_LFLAGS = -static -s -lole32 -luuid -ladvapi32 -lkernel32 -lnetapi32 EXTRA_LFLAGS = -static -s -lole32 -luuid -ladvapi32 -lkernel32 -lnetapi32
QTOBJS = \ QTOBJS = \
qfilesystemengine_win.o \ qfilesystemengine_win.o \

View File

@ -2873,7 +2873,16 @@ MakefileGenerator::escapeDependencyPath(const QString &path) const
QString ret = path; QString ret = path;
if (!ret.isEmpty()) { if (!ret.isEmpty()) {
// Unix make semantics, to be inherited by unix and mingw generators. // Unix make semantics, to be inherited by unix and mingw generators.
#ifdef Q_OS_UNIX
// When running on Unix, we need to escape colons (which may appear
// anywhere in a path, and would be mis-parsed as dependency separators).
static const QRegExp criticalChars(QStringLiteral("([\t :#])")); static const QRegExp criticalChars(QStringLiteral("([\t :#])"));
#else
// MinGW make has a hack for colons which denote drive letters, and no
// other colons may appear in paths. And escaping colons actually breaks
// the make from the Android SDK.
static const QRegExp criticalChars(QStringLiteral("([\t #])"));
#endif
ret.replace(criticalChars, QStringLiteral("\\\\1")); ret.replace(criticalChars, QStringLiteral("\\\\1"));
debug_msg(2, "escapeDependencyPath: %s -> %s", path.toLatin1().constData(), ret.toLatin1().constData()); debug_msg(2, "escapeDependencyPath: %s -> %s", path.toLatin1().constData(), ret.toLatin1().constData());
} }

View File

@ -1,169 +0,0 @@
#qmake code
SOURCES += project.cpp property.cpp main.cpp \
library/ioutils.cpp library/proitems.cpp library/qmakevfs.cpp library/qmakeglobals.cpp \
library/qmakeparser.cpp library/qmakeevaluator.cpp library/qmakebuiltins.cpp \
generators/makefile.cpp \
generators/unix/unixmake2.cpp generators/unix/unixmake.cpp meta.cpp \
option.cpp generators/win32/winmakefile.cpp generators/win32/mingw_make.cpp \
generators/makefiledeps.cpp generators/metamakefile.cpp generators/mac/pbuilder_pbx.cpp \
generators/xmloutput.cpp \
generators/win32/msvc_nmake.cpp generators/projectgenerator.cpp \
generators/win32/msvc_vcproj.cpp \
generators/win32/msvc_vcxproj.cpp \
generators/win32/msvc_objectmodel.cpp generators/win32/msbuild_objectmodel.cpp
HEADERS += project.h property.h \
library/qmake_global.h library/ioutils.h library/proitems.h library/qmakevfs.h library/qmakeglobals.h \
library/qmakeparser.h library/qmakeevaluator.h library/qmakeevaluator_p.h \
generators/makefile.h \
generators/unix/unixmake.h meta.h option.h cachekeys.h \
generators/win32/winmakefile.h generators/win32/mingw_make.h generators/projectgenerator.h \
generators/makefiledeps.h generators/metamakefile.h generators/mac/pbuilder_pbx.h \
generators/xmloutput.h generators/win32/msvc_nmake.h \
generators/win32/msvc_vcproj.h \
generators/win32/msvc_vcxproj.h \
generators/win32/msvc_objectmodel.h generators/win32/msbuild_objectmodel.h
bootstrap { #Qt code
SOURCES+= \
qbitarray.cpp \
qbuffer.cpp \
qarraydata.cpp \
qbytearray.cpp \
qbytearraymatcher.cpp \
qcryptographichash.cpp \
qdatetime.cpp \
qdir.cpp \
qdiriterator.cpp \
qfiledevice.cpp \
qfile.cpp \
qabstractfileengine.cpp \
qfileinfo.cpp \
qfilesystementry.cpp \
qfilesystemengine.cpp \
qfsfileengine.cpp \
qfsfileengine_iterator.cpp \
qglobal.cpp \
qnumeric.cpp \
qhash.cpp \
qiodevice.cpp \
qlist.cpp \
qlinkedlist.cpp \
qlocale.cpp \
qlocale_tools.cpp \
qmalloc.cpp \
qmap.cpp \
qmetatype.cpp \
qregexp.cpp \
qtextcodec.cpp \
qutfcodec.cpp \
qstring.cpp \
qstring_compat.cpp \
qstringlist.cpp \
qtemporaryfile.cpp \
qtextstream.cpp \
quuid.cpp \
qsettings.cpp \
qlibraryinfo.cpp \
qsystemerror.cpp \
qvariant.cpp \
qversionnumber.cpp \
qvsnprintf.cpp \
qxmlstream.cpp \
qxmlutils.cpp \
qlogging.cpp \
qjson.cpp \
qjsondocument.cpp \
qjsonparser.cpp \
qjsonarray.cpp \
qjsonobject.cpp \
qjsonvalue.cpp
HEADERS+= \
qbitarray.h \
qbuffer.h \
qarraydata.h \
qbytearray.h \
qarraydataops.h \
qarraydatapointer.h \
qbytearraymatcher.h \
qchar.h \
qcryptographichash.h \
qdatetime.h \
qdatetime_p.h \
qdir.h \
qdir_p.h \
qdiriterator.h \
qfile.h \
qabstractfileengine_p.h \
qfileinfo.h \
qglobal.h \
qnumeric.h \
qhash.h \
qiodevice.h \
qlist.h \
qlinkedlist.h \
qlocale.h \
qlocale_tools_p.h \
qmalloc.h \
qmap.h \
qmetatype.h \
qregexp.h \
qtextcodec.h \
qutfcodec.h \
qstring.h \
qstringlist.h \
qstringmatcher.h \
qsystemerror_p.h \
qtemporaryfile.h \
qtextstream.h \
quuid.h \
qvector.h \
qversionnumber.h \
qxmlstream.h \
qxmlutils.h \
qjson.h \
qjsondocument.h \
qjsonparser.h \
qjsonwriter.h \
qjsonarray.h \
qjsonobject.h \
qjsonvalue.h
unix {
SOURCES += qfilesystemengine_unix.cpp qfilesystemiterator_unix.cpp qfsfileengine_unix.cpp
mac {
SOURCES += qcore_mac.cpp qsettings_mac.cpp qcore_mac_objc.mm qlocale_mac.mm
LIBS += -framework ApplicationServices -framework CoreServices -framework Foundation
} else {
SOURCES += qlocale_unix.cpp
}
} else:win32 {
SOURCES += qfilesystemengine_win.cpp qfsfileengine_win.cpp qfilesystemiterator_win.cpp qsettings_win.cpp \
qsystemlibrary.cpp qlocale_win.cpp registry.cpp
win32-msvc*:LIBS += ole32.lib advapi32.lib netapi32.lib
mingw:LIBS += -lole32 -luuid -ladvapi32 -lkernel32 -lnetapi32
}
qnx {
CFLAGS += -fhonor-std
LFLAGS += -lcpp
}
DEFINES += QT_BOOTSTRAPPED
INCLUDEPATH += \
$$QT.core.includes $$QT.core_private.includes \
$$shadowed(../src/corelib/global)
} else {
CONFIG += qt
QT = core
}
*-g++:profiling {
QMAKE_CFLAGS = -pg
QMAKE_CXXFLAGS = -pg
QMAKE_LFLAGS = -pg
}
PRECOMPILED_HEADER = qmake_pch.h

View File

@ -3,12 +3,101 @@
# and the configures. # and the configures.
option(host_build) option(host_build)
CONFIG += console bootstrap CONFIG += console
CONFIG -= qt CONFIG -= qt app_bundle
DEFINES += \ DEFINES += \
PROEVALUATOR_FULL \
QT_BOOTSTRAPPED \
QT_BUILD_QMAKE \ QT_BUILD_QMAKE \
QT_NO_FOREACH \ QT_NO_FOREACH \
PROEVALUATOR_FULL $$shell_quote(QT_VERSION_STR=\"$$QT_VERSION\") \
QT_VERSION_MAJOR=$$QT_MAJOR_VERSION \
QT_VERSION_MINOR=$$QT_MINOR_VERSION \
QT_VERSION_PATCH=$$QT_PATCH_VERSION
win32: DEFINES += \
UNICODE \
_ENABLE_EXTENDED_ALIGNED_STORAGE \
_CRT_SECURE_NO_WARNINGS _SCL_SECURE_NO_WARNINGS
# qmake code
PRECOMPILED_HEADER = qmake_pch.h
INCLUDEPATH += \
. \
library \
generators \
generators/unix \
generators/win32 \
generators/mac
SOURCES += \
main.cpp \
meta.cpp \
option.cpp \
project.cpp \
property.cpp \
library/ioutils.cpp \
library/proitems.cpp \
library/qmakebuiltins.cpp \
library/qmakeevaluator.cpp \
library/qmakeglobals.cpp \
library/qmakeparser.cpp \
library/qmakevfs.cpp \
generators/makefile.cpp \
generators/makefiledeps.cpp \
generators/metamakefile.cpp \
generators/projectgenerator.cpp \
generators/xmloutput.cpp \
generators/mac/pbuilder_pbx.cpp \
generators/unix/unixmake.cpp \
generators/unix/unixmake2.cpp \
generators/win32/mingw_make.cpp \
generators/win32/msbuild_objectmodel.cpp \
generators/win32/msvc_nmake.cpp \
generators/win32/msvc_objectmodel.cpp \
generators/win32/msvc_vcproj.cpp \
generators/win32/msvc_vcxproj.cpp \
generators/win32/winmakefile.cpp
HEADERS += \
cachekeys.h \
meta.h \
option.h \
project.h \
property.h \
library/ioutils.h \
library/proitems.h \
library/qmake_global.h \
library/qmakeevaluator.h \
library/qmakeevaluator_p.h \
library/qmakeglobals.h \
library/qmakeparser.h \
library/qmakevfs.h \
generators/makefile.h \
generators/makefiledeps.h \
generators/metamakefile.h \
generators/projectgenerator.h \
generators/xmloutput.h \
generators/mac/pbuilder_pbx.h \
generators/unix/unixmake.h \
generators/win32/mingw_make.h \
generators/win32/msbuild_objectmodel.h \
generators/win32/msvc_nmake.h \
generators/win32/msvc_objectmodel.h \
generators/win32/msvc_vcproj.h \
generators/win32/msvc_vcxproj.h \
generators/win32/winmakefile.h
# qt code
bp = $$shadowed(..)
INCLUDEPATH += \
$$bp/include $$bp/include/QtCore \
$$bp/include/QtCore/$$QT_VERSION $$bp/include/QtCore/$$QT_VERSION/QtCore
$$bp/src/corelib/global
VPATH += \ VPATH += \
../src/corelib/global \ ../src/corelib/global \
@ -17,17 +106,143 @@ VPATH += \
../src/corelib/codecs \ ../src/corelib/codecs \
../src/corelib/plugin \ ../src/corelib/plugin \
../src/corelib/io \ ../src/corelib/io \
../src/corelib/serialization \ ../src/corelib/serialization
../tools/shared/windows
INCLUDEPATH += . \ SOURCES += \
library \ qabstractfileengine.cpp \
generators \ qarraydata.cpp \
generators/unix \ qbitarray.cpp \
generators/win32 \ qbuffer.cpp \
generators/mac \ qbytearray.cpp \
../tools/shared qbytearraymatcher.cpp \
qcryptographichash.cpp \
qdatetime.cpp \
qdir.cpp \
qdiriterator.cpp \
qfile.cpp \
qfiledevice.cpp \
qfileinfo.cpp \
qfilesystemengine.cpp \
qfilesystementry.cpp \
qfsfileengine.cpp \
qfsfileengine_iterator.cpp \
qglobal.cpp \
qhash.cpp \
qiodevice.cpp \
qjson.cpp \
qjsonarray.cpp \
qjsondocument.cpp \
qjsonobject.cpp \
qjsonparser.cpp \
qjsonvalue.cpp \
qlibraryinfo.cpp \
qlinkedlist.cpp \
qlist.cpp \
qlocale.cpp \
qlocale_tools.cpp \
qlogging.cpp \
qmalloc.cpp \
qmap.cpp \
qmetatype.cpp \
qnumeric.cpp \
qregexp.cpp \
qsettings.cpp \
qstring.cpp \
qstring_compat.cpp \
qstringlist.cpp \
qsystemerror.cpp \
qtemporaryfile.cpp \
qtextcodec.cpp \
qtextstream.cpp \
qutfcodec.cpp \
quuid.cpp \
qvariant.cpp \
qversionnumber.cpp \
qvsnprintf.cpp \
qxmlstream.cpp \
qxmlutils.cpp
include(qmake.pri) HEADERS += \
qabstractfileengine_p.h \
qarraydata.h \
qarraydataops.h \
qarraydatapointer.h \
qbitarray.h \
qbuffer.h \
qbytearray.h \
qbytearraymatcher.h \
qchar.h \
qcryptographichash.h \
qdatetime.h \
qdatetime_p.h \
qdir.h \
qdir_p.h \
qdiriterator.h \
qfile.h \
qfileinfo.h \
qglobal.h \
qhash.h \
qiodevice.h \
qjson.h \
qjsonarray.h \
qjsondocument.h \
qjsonobject.h \
qjsonparser.h \
qjsonvalue.h \
qjsonwriter.h \
qlinkedlist.h \
qlist.h \
qlocale.h \
qlocale_tools_p.h \
qmalloc.h \
qmap.h \
qmetatype.h \
qnumeric.h \
qregexp.h \
qstring.h \
qstringlist.h \
qstringmatcher.h \
qsystemerror_p.h \
qtemporaryfile.h \
qtextcodec.h \
qtextstream.h \
qutfcodec.h \
quuid.h \
qvector.h \
qversionnumber.h \
qxmlstream.h \
qxmlutils.h
load(qt_app) unix {
SOURCES += \
qcore_unix.cpp \
qfilesystemengine_unix.cpp \
qfilesystemiterator_unix.cpp \
qfsfileengine_unix.cpp \
qlocale_unix.cpp
macos {
SOURCES += \
qcore_foundation.mm \
qcore_mac.cpp \
qoperatingsystemversion_darwin.mm \
qsettings_mac.cpp
LIBS += \
-framework ApplicationServices \
-framework CoreServices \
-framework Foundation
QMAKE_CXXFLAGS += -fconstant-cfstrings
}
} else {
SOURCES += \
qfilesystemengine_win.cpp \
qfilesystemiterator_win.cpp \
qfsfileengine_win.cpp \
qlocale_win.cpp \
qoperatingsystemversion_win.cpp \
qsettings_win.cpp \
qsystemlibrary.cpp \
registry.cpp
LIBS += -lole32 -ladvapi32 -lkernel32 -lnetapi32
mingw: LIBS += -luuid
clang: QMAKE_CXXFLAGS += -fms-compatibility-version=19.00.23506 -Wno-microsoft-enum-value
}

View File

@ -246,18 +246,20 @@
If you pass the Qt::UniqueConnection \a type, the connection will only If you pass the Qt::UniqueConnection \a type, the connection will only
be made if it is not a duplicate. If there is already a duplicate be made if it is not a duplicate. If there is already a duplicate
(exact same signal to the exact same slot on the same objects), (exact same signal to the exact same slot on the same objects),
the connection will fail and connect will return false the connection will fail and connect will return \c false.
This example illustrates that objects can work together without needing to This example illustrates that objects can work together without needing to
know any information about each other. To enable this, the objects only know any information about each other. To enable this, the objects only
need to be connected together, and this can be achieved with some simple need to be connected together, and this can be achieved with some simple
QObject::connect() function calls, or with \c{uic}'s QObject::connect() function calls, or with \l{User Interface Compiler
\l{Automatic Connections}{automatic connections} feature. (uic)}{uic}'s \l{Automatic Connections}{automatic connections} feature.
\section1 A Real Example \section1 A Real Example
Here is a simple commented example of a widget. The following is an example of the header of a simple widget class without
member functions. The purpose is to show how you can utilize signals and
slots in your own applications.
\snippet signalsandslots/lcdnumber.h 0 \snippet signalsandslots/lcdnumber.h 0
\snippet signalsandslots/lcdnumber.h 1 \snippet signalsandslots/lcdnumber.h 1
@ -281,19 +283,13 @@
\snippet signalsandslots/lcdnumber.h 6 \snippet signalsandslots/lcdnumber.h 6
\snippet signalsandslots/lcdnumber.h 7 \snippet signalsandslots/lcdnumber.h 7
\codeline
It's not obviously relevant to the moc, but if you inherit
QWidget you almost certainly want to have the \c parent argument
in your constructor and pass it to the base class's constructor.
Some destructors and member functions are omitted here; the \c
moc ignores member functions.
\snippet signalsandslots/lcdnumber.h 8 \snippet signalsandslots/lcdnumber.h 8
\snippet signalsandslots/lcdnumber.h 9 \snippet signalsandslots/lcdnumber.h 9
\c LcdNumber emits a signal when it is asked to show an impossible After the class constructor and \c public members, we declare the class
value. \c signals. The \c LcdNumber class emits a signal, \c overflow(), when it
is asked to show an impossible value.
If you don't care about overflow, or you know that overflow If you don't care about overflow, or you know that overflow
cannot occur, you can ignore the \c overflow() signal, i.e. don't cannot occur, you can ignore the \c overflow() signal, i.e. don't
@ -325,8 +321,8 @@
callbacks, you'd have to find five different names and keep track callbacks, you'd have to find five different names and keep track
of the types yourself. of the types yourself.
Some irrelevant member functions have been omitted from this \sa QLCDNumber, QObject::connect(), {Digital Clock Example}, and
example. {Tetrix Example}.
\section1 Signals And Slots With Default Arguments \section1 Signals And Slots With Default Arguments
@ -361,18 +357,24 @@
You can also connect to functors or C++11 lambdas: You can also connect to functors or C++11 lambdas:
\code \code
connect(sender, &QObject::destroyed, context, [=](){ this->m_objects.remove(sender); }); connect(sender, &QObject::destroyed, this, [=](){ this->m_objects.remove(sender); });
\endcode \endcode
The lambda will be disconnected when the context is destroyed. In both these cases, we provide \a this as context in the call to connect().
The context object provides information about in which thread the receiver
should be executed. This is important, as providing the context ensures
that the receiver is executed in the context thread.
The lambda will be disconnected when the sender or context is destroyed.
You should take care that any objects used inside the functor are still
alive when the signal is emitted.
The other way to connect a signal to a slot is to use QObject::connect() The other way to connect a signal to a slot is to use QObject::connect()
and the \c{SIGNAL} and \c{SLOT} macros. and the \c{SIGNAL} and \c{SLOT} macros.
The rule about whether to The rule about whether to include arguments or not in the \c{SIGNAL()} and
include arguments or not in the \c{SIGNAL()} and \c{SLOT()} \c{SLOT()} macros, if the arguments have default values, is that the
macros, if the arguments have default values, is that the signature passed to the \c{SIGNAL()} macro must \e not have fewer arguments
signature passed to the \c{SIGNAL()} macro must \e not have fewer than the signature passed to the \c{SLOT()} macro.
arguments than the signature passed to the \c{SLOT()} macro.
All of these would work: All of these would work:
\code \code

View File

@ -589,7 +589,7 @@ Q_STATIC_ASSERT((std::is_same<qsizetype, qptrdiff>::value));
{long long int } (\c __int64 on Windows). {long long int } (\c __int64 on Windows).
Several convenience type definitions are declared: \l qreal for \c Several convenience type definitions are declared: \l qreal for \c
double, \l uchar for \c unsigned char, \l uint for \c unsigned double or \c float, \l uchar for \c unsigned char, \l uint for \c unsigned
int, \l ulong for \c unsigned long and \l ushort for \c unsigned int, \l ulong for \c unsigned long and \l ushort for \c unsigned
short. short.

View File

@ -116,8 +116,8 @@
\value AA_DontShowShortcutsInContextMenus Actions with the Shortcut property \value AA_DontShowShortcutsInContextMenus Actions with the Shortcut property
won't be shown in any shortcut menus unless specifically set by the won't be shown in any shortcut menus unless specifically set by the
QAction::shortcutVisibleInContextMenu property. This value has QAction::shortcutVisibleInContextMenu property. This value was added
been added in Qt 5.10. in Qt 5.10.
\value AA_NativeWindows Ensures that widgets have native windows. \value AA_NativeWindows Ensures that widgets have native windows.
@ -132,9 +132,8 @@
menu and not taking possession of the native menu bar. Setting this menu and not taking possession of the native menu bar. Setting this
attribute to true will also set the AA_DontUseNativeMenuBar attribute attribute to true will also set the AA_DontUseNativeMenuBar attribute
to true. It also disables native event filters. to true. It also disables native event filters.
This attribute has been added in Qt 5.7. It must be set before This attribute must be set before QGuiApplication constructed.
\l {QGuiApplication}{Q\(Gui\)Application} is constructed. This value was added in Qt 5.7.
\value AA_DontUseNativeMenuBar All menubars created while this attribute is \value AA_DontUseNativeMenuBar All menubars created while this attribute is
set to true won't be used as a native menubar (e.g, the menubar at set to true won't be used as a native menubar (e.g, the menubar at
@ -174,14 +173,14 @@
\value AA_UseDesktopOpenGL Forces the usage of desktop OpenGL (for example, \value AA_UseDesktopOpenGL Forces the usage of desktop OpenGL (for example,
\e opengl32.dll or \e libGL.so) on platforms that use dynamic loading \e opengl32.dll or \e libGL.so) on platforms that use dynamic loading
of the OpenGL implementation. This value has been added in Qt 5.3. of the OpenGL implementation. This attribute must be set before
This attribute must be set before \l {QGuiApplication} QGuiApplication is constructed.
{Q\(Gui\)Application} is constructed. This value was added in Qt 5.3.
\value AA_UseOpenGLES Forces the usage of OpenGL ES 2.0 or higher on \value AA_UseOpenGLES Forces the usage of OpenGL ES 2.0 or higher on
platforms that use dynamic loading of the OpenGL implementation. platforms that use dynamic loading of the OpenGL implementation.
This value has been added in Qt 5.3. This attribute must be set This attribute must be set before QGuiApplication is constructed.
before \l {QGuiApplication}{Q\(Gui\)Application} is constructed. This value was added in Qt 5.3.
\value AA_UseSoftwareOpenGL Forces the usage of a software based OpenGL \value AA_UseSoftwareOpenGL Forces the usage of a software based OpenGL
implementation on platforms that use dynamic loading of the OpenGL implementation on platforms that use dynamic loading of the OpenGL
@ -191,29 +190,28 @@
implementation is available. The default name of this library is implementation is available. The default name of this library is
\c opengl32sw.dll and can be overridden by setting the environment \c opengl32sw.dll and can be overridden by setting the environment
variable \e QT_OPENGL_DLL. See the platform-specific pages, for variable \e QT_OPENGL_DLL. See the platform-specific pages, for
instance \l{Qt for Windows}, for more information. This value has instance \l{Qt for Windows}, for more information. This attribute
been added in Qt 5.4. This attribute must be set before must be set before QGuiApplication is constructed.
\l {QGuiApplication}{Q\(Gui\)Application} is constructed. This value was added in Qt 5.4.
\value AA_ShareOpenGLContexts Enables resource sharing between the OpenGL \value AA_ShareOpenGLContexts Enables resource sharing between the OpenGL
contexts used by classes like QOpenGLWidget and QQuickWidget. This contexts used by classes like QOpenGLWidget and QQuickWidget. This
allows sharing OpenGL resources, like textures, between QOpenGLWidget allows sharing OpenGL resources, like textures, between QOpenGLWidget
instances that belong to different top-level windows. This value has instances that belong to different top-level windows. This attribute
been added in Qt 5.4. This attribute must be set before must be set before QGuiApplication is constructed.
\l {QGuiApplication}{Q\(Gui\)Application} is constructed. This value was added in Qt 5.4.
\value AA_SetPalette Indicates whether a palette was explicitly set on the \value AA_SetPalette Indicates whether a palette was explicitly set on the
\l {QGuiApplication}{Q\(Gui\)Application}. This value has been added QGuiApplication. This value was added in Qt 5.5.
in Qt 5.5.
\value AA_EnableHighDpiScaling Enables high-DPI scaling in Qt on supported \value AA_EnableHighDpiScaling Enables high-DPI scaling in Qt on supported
platforms (see also \l{High DPI Displays}). Supported platforms are platforms (see also \l{High DPI Displays}). Supported platforms are
X11, Windows and Android. Enabling makes Qt scale the main (device X11, Windows and Android. Enabling makes Qt scale the main (device
independent) coordinate system according to display scale factors independent) coordinate system according to display scale factors
provided by the operating system. This corresponds to setting the provided by the operating system. This corresponds to setting the
QT_AUTO_SCREEN\unicode{0x200b}_SCALE_FACTOR environment variable to 1. This value QT_AUTO_SCREEN\unicode{0x200b}_SCALE_FACTOR environment variable to
has been added in Qt 5.6. This attribute must be set before 1. This attribute must be set before QGuiApplication is constructed.
Q(Gui)Application is constructed. This value was added in Qt 5.6.
\value AA_DisableHighDpiScaling Disables high-DPI scaling in Qt, exposing window \value AA_DisableHighDpiScaling Disables high-DPI scaling in Qt, exposing window
system coordinates. Note that the window system may do its own scaling, system coordinates. Note that the window system may do its own scaling,
@ -221,24 +219,26 @@
be equal to 1. In addition, scale factors set by QT_SCALE_FACTOR will not be equal to 1. In addition, scale factors set by QT_SCALE_FACTOR will not
be affected. This corresponds to setting the be affected. This corresponds to setting the
QT_AUTO_SCREEN\unicode{0x200b}_SCALE_FACTOR environment variable to 0. QT_AUTO_SCREEN\unicode{0x200b}_SCALE_FACTOR environment variable to 0.
This value has been added in Qt 5.6. This This attribute must be set before QGuiApplication is constructed.
attribute must be set before Q(Gui)Application is constructed. This value was added in Qt 5.6.
\value AA_UseStyleSheetPropagationInWidgetStyles By default, Qt Style Sheets \value AA_UseStyleSheetPropagationInWidgetStyles By default, Qt Style Sheets
disable regular QWidget palette and font propagation. When this flag disable regular QWidget palette and font propagation. When this flag
is enabled, font and palette changes propagate as though the user had is enabled, font and palette changes propagate as though the user had
manually called the corresponding QWidget methods. See manually called the corresponding QWidget methods. See
\l{The Style Sheet Syntax#Inheritance}{The Style Sheet Syntax - Inheritance} \l{The Style Sheet Syntax#Inheritance}{The Style Sheet Syntax - Inheritance}
for more details. This value has been added in Qt 5.7. for more details.
This value was added in Qt 5.7.
\value AA_DontUseNativeDialogs All dialogs created while this attribute is \value AA_DontUseNativeDialogs All dialogs created while this attribute is
set to true won't use the native dialogs provided by the platform. set to true won't use the native dialogs provided by the platform.
This value has been added in Qt 5.7. This value was added in Qt 5.7.
\value AA_SynthesizeMouseForUnhandledTabletEvents All tablet events \value AA_SynthesizeMouseForUnhandledTabletEvents All tablet events
that are not accepted by the application will be translated that are not accepted by the application will be translated
to mouse events instead. This attribute is enabled to mouse events instead. This attribute is enabled
by default. This value has been added in Qt 5.7. by default.
This value was added in Qt 5.7.
\value AA_CompressHighFrequencyEvents Enables compression of certain frequent events. \value AA_CompressHighFrequencyEvents Enables compression of certain frequent events.
On the X11 windowing system, the default value is true, which means that On the X11 windowing system, the default value is true, which means that
@ -251,19 +251,21 @@
If your application needs to handle all events with no compression, If your application needs to handle all events with no compression,
you can unset this attribute. Notice that input events from tablet devices you can unset this attribute. Notice that input events from tablet devices
will not be compressed. See AA_CompressTabletEvents if you want these to be will not be compressed. See AA_CompressTabletEvents if you want these to be
compressed as well. This value has been added in Qt 5.7. compressed as well.
This value was added in Qt 5.7.
\value AA_CompressTabletEvents Enables compression of input events from tablet devices. \value AA_CompressTabletEvents Enables compression of input events from tablet devices.
Notice that AA_CompressHighFrequencyEvents must be true for events compression Notice that AA_CompressHighFrequencyEvents must be true for events compression
to be enabled, and that this flag extends the former to tablet events. Its default to be enabled, and that this flag extends the former to tablet events. Its default
value is false. This value has been added in Qt 5.10. value is false.
This value was added in Qt 5.10.
\value AA_DontCheckOpenGLContextThreadAffinity When making a context \value AA_DontCheckOpenGLContextThreadAffinity When making a context
current using QOpenGLContext, do not check that the current using QOpenGLContext, do not check that the
\l{QObject#Thread Affinity}{QObject thread affinity} \l{QObject#Thread Affinity}{QObject thread affinity}
of the QOpenGLContext object is the same thread calling of the QOpenGLContext object is the same thread calling
\l{QOpenGLContext::makeCurrent}{makeCurrent()}. This value has been \l{QOpenGLContext::makeCurrent}{makeCurrent()}.
added in Qt 5.8. This value was added in Qt 5.8.
\value AA_DisableShaderDiskCache Disables caching of shader program binaries \value AA_DisableShaderDiskCache Disables caching of shader program binaries
on disk. By default Qt Quick, QPainter's OpenGL backend, and any on disk. By default Qt Quick, QPainter's OpenGL backend, and any
@ -277,7 +279,7 @@
\value AA_DisableWindowContextHelpButton Disables the WindowContextHelpButtonHint \value AA_DisableWindowContextHelpButton Disables the WindowContextHelpButtonHint
by default on Qt::Sheet and Qt::Dialog widgets. This hides the \gui ? button by default on Qt::Sheet and Qt::Dialog widgets. This hides the \gui ? button
on Windows, which only makes sense if you use \l QWhatsThis functionality. on Windows, which only makes sense if you use \l QWhatsThis functionality.
This value has been added in Qt 5.10. For Qt 6, WindowContextHelpButtonHint This value was added in Qt 5.10. In Qt 6, WindowContextHelpButtonHint
will not be set by default. will not be set by default.
The following values are deprecated or obsolete: The following values are deprecated or obsolete:
@ -2276,13 +2278,17 @@
correctly. correctly.
\value WindowStaysOnBottomHint Informs the window system that the \value WindowStaysOnBottomHint Informs the window system that the
window should stay on bottom of all other windows. Note window should stay on bottom of all other windows.
that on X11 this hint will work only in window managers
\note On X11, this hint will work only in window managers
that support _NET_WM_STATE_BELOW atom. If a window always that support _NET_WM_STATE_BELOW atom. If a window always
on the bottom has a parent, the parent will also be left on on the bottom has a parent, the parent will also be left on
the bottom. This window hint is currently not implemented the bottom. This window hint is currently not implemented
for \macos. for \macos.
\note On Windows, this will work only for frameless or
full-screen windows.
\value WindowTransparentForInput Informs the window system that this window \value WindowTransparentForInput Informs the window system that this window
is used only for output (displaying something) and does not take input. is used only for output (displaying something) and does not take input.
Therefore input events should pass through as if it wasn't there. Therefore input events should pass through as if it wasn't there.
@ -2652,7 +2658,7 @@
but \b{must} not return an empty string unless the cursor is at the end of the document. but \b{must} not return an empty string unless the cursor is at the end of the document.
\value ImEnterKeyType The Enter key type. \value ImEnterKeyType The Enter key type.
\value ImAnchorRectangle The bounding rectangle of the selection anchor. \value ImAnchorRectangle The bounding rectangle of the selection anchor.
This value has been added in Qt 5.7. This value was added in Qt 5.7.
\value ImInputItemClipRectangle The actual exposed input item rectangle. Parts of the input item might be \value ImInputItemClipRectangle The actual exposed input item rectangle. Parts of the input item might be
clipped. This value will take clipping into consideration and return the actual painted clipped. This value will take clipping into consideration and return the actual painted
item rectangle. The rectangle is in widget coordinates. item rectangle. The rectangle is in widget coordinates.
@ -2780,7 +2786,7 @@
\value ItemNeverHasChildren The item never has child items. \value ItemNeverHasChildren The item never has child items.
This is used for optimization purposes only. This is used for optimization purposes only.
\value ItemIsUserTristate The user can cycle through three separate states. \value ItemIsUserTristate The user can cycle through three separate states.
This value has been added in Qt 5.5. This value was added in Qt 5.5.
Note that checkable items need to be given both a suitable set of flags Note that checkable items need to be given both a suitable set of flags
and an initial state, indicating whether the item is checked or not. and an initial state, indicating whether the item is checked or not.

View File

@ -2147,6 +2147,10 @@ void QProcess::start(OpenMode mode)
\endlist \endlist
All other properties of the QProcess object are ignored. All other properties of the QProcess object are ignored.
\note The called process inherits the console window of the calling
process. To suppress console output, redirect standard/error output to
QProcess::nullDevice().
\sa start() \sa start()
\sa startDetached(const QString &program, const QStringList &arguments, \sa startDetached(const QString &program, const QStringList &arguments,
const QString &workingDirectory, qint64 *pid) const QString &workingDirectory, qint64 *pid)

View File

@ -949,16 +949,14 @@ bool QProcessPrivate::startDetached(qint64 *pid)
qt_safe_close(pidPipe[1]); qt_safe_close(pidPipe[1]);
// copy the stdin socket if asked to (without closing on exec) // copy the stdin socket if asked to (without closing on exec)
if (inputChannelMode != QProcess::ForwardedInputChannel) if (stdinChannel.type == Channel::Redirect)
qt_safe_dup2(stdinChannel.pipe[0], STDIN_FILENO, 0); qt_safe_dup2(stdinChannel.pipe[0], STDIN_FILENO, 0);
// copy the stdout and stderr if asked to // copy the stdout and stderr if asked to
if (processChannelMode != QProcess::ForwardedChannels) { if (stdoutChannel.type == Channel::Redirect)
if (processChannelMode != QProcess::ForwardedOutputChannel) qt_safe_dup2(stdoutChannel.pipe[1], STDOUT_FILENO, 0);
qt_safe_dup2(stdoutChannel.pipe[1], STDOUT_FILENO, 0); if (stderrChannel.type == Channel::Redirect)
if (processChannelMode != QProcess::ForwardedErrorChannel) qt_safe_dup2(stderrChannel.pipe[1], STDERR_FILENO, 0);
qt_safe_dup2(stderrChannel.pipe[1], STDERR_FILENO, 0);
}
if (!encodedWorkingDirectory.isEmpty()) { if (!encodedWorkingDirectory.isEmpty()) {
if (QT_CHDIR(encodedWorkingDirectory.constData()) == -1) if (QT_CHDIR(encodedWorkingDirectory.constData()) == -1)

View File

@ -893,6 +893,11 @@ static bool startDetachedUacPrompt(const QString &programIn, const QStringList &
return true; return true;
} }
static Q_PIPE pipeOrStdHandle(Q_PIPE pipe, DWORD handleNumber)
{
return pipe != INVALID_Q_PIPE ? pipe : GetStdHandle(handleNumber);
}
bool QProcessPrivate::startDetached(qint64 *pid) bool QProcessPrivate::startDetached(qint64 *pid)
{ {
static const DWORD errorElevationRequired = 740; static const DWORD errorElevationRequired = 740;
@ -925,15 +930,14 @@ bool QProcessPrivate::startDetached(qint64 *pid)
0, 0, 0, 0, 0, 0,
STARTF_USESTDHANDLES, STARTF_USESTDHANDLES,
0, 0, 0, 0, 0, 0,
stdinChannel.pipe[0], stdoutChannel.pipe[1], stderrChannel.pipe[1] pipeOrStdHandle(stdinChannel.pipe[0], STD_INPUT_HANDLE),
pipeOrStdHandle(stdoutChannel.pipe[1], STD_OUTPUT_HANDLE),
pipeOrStdHandle(stderrChannel.pipe[1], STD_ERROR_HANDLE)
}; };
const bool inheritHandles = stdinChannel.type == Channel::Redirect
|| stdoutChannel.type == Channel::Redirect
|| stderrChannel.type == Channel::Redirect;
QProcess::CreateProcessArguments cpargs = { QProcess::CreateProcessArguments cpargs = {
nullptr, reinterpret_cast<wchar_t *>(const_cast<ushort *>(args.utf16())), nullptr, reinterpret_cast<wchar_t *>(const_cast<ushort *>(args.utf16())),
nullptr, nullptr, inheritHandles, dwCreationFlags, envPtr, nullptr, nullptr, true, dwCreationFlags, envPtr,
workingDirectory.isEmpty() workingDirectory.isEmpty()
? nullptr : reinterpret_cast<const wchar_t *>(workingDirectory.utf16()), ? nullptr : reinterpret_cast<const wchar_t *>(workingDirectory.utf16()),
&startupInfo, &pinfo &startupInfo, &pinfo

View File

@ -223,7 +223,7 @@ QDeadlineTimer::QDeadlineTimer(qint64 msecs, Qt::TimerType type) Q_DECL_NOTHROW
Constructs a QDeadlineTimer object with a deadline at \a deadline time Constructs a QDeadlineTimer object with a deadline at \a deadline time
point, converting from the clock source \c{Clock} to Qt's internal clock point, converting from the clock source \c{Clock} to Qt's internal clock
source (see QElapsedTimer::clcokType()). source (see QElapsedTimer::clockType()).
If \a deadline is in the past, this QDeadlineTimer object is set to If \a deadline is in the past, this QDeadlineTimer object is set to
expired, whereas if \a deadline is equal to \c{Duration::max()}, then this expired, whereas if \a deadline is equal to \c{Duration::max()}, then this
@ -266,7 +266,7 @@ QDeadlineTimer::QDeadlineTimer(qint64 msecs, Qt::TimerType type) Q_DECL_NOTHROW
Sets this QDeadlineTimer to the deadline marked by \a deadline time Sets this QDeadlineTimer to the deadline marked by \a deadline time
point, converting from the clock source \c{Clock} to Qt's internal clock point, converting from the clock source \c{Clock} to Qt's internal clock
source (see QElapsedTimer::clcokType()). source (see QElapsedTimer::clockType()).
If \a deadline is in the past, this QDeadlineTimer object is set to If \a deadline is in the past, this QDeadlineTimer object is set to
expired, whereas if \a deadline is equal to \c{Duration::max()}, then this expired, whereas if \a deadline is equal to \c{Duration::max()}, then this

View File

@ -3903,7 +3903,8 @@ bool QObject::setProperty(const char *name, const QVariant &value)
d->extraData->propertyNames.append(name); d->extraData->propertyNames.append(name);
d->extraData->propertyValues.append(value); d->extraData->propertyValues.append(value);
} else { } else {
if (value == d->extraData->propertyValues.at(idx)) if (value.userType() == d->extraData->propertyValues.at(idx).userType()
&& value == d->extraData->propertyValues.at(idx))
return false; return false;
d->extraData->propertyValues[idx] = value; d->extraData->propertyValues[idx] = value;
} }

View File

@ -46,7 +46,7 @@ namespace QJsonPrivate
{ {
static Q_CONSTEXPR Base emptyArray = { { qle_uint(sizeof(Base)) }, { 0 }, { qle_uint(0) } }; static Q_CONSTEXPR Base emptyArray = { { qle_uint(sizeof(Base)) }, { 0 }, { qle_uint(0) } };
static Q_CONSTEXPR Base emptyObject = { { qle_uint(sizeof(Base)) }, { 0 }, { qle_uint(0) } }; static Q_CONSTEXPR Base emptyObject = { { qle_uint(sizeof(Base)) }, { qToLittleEndian(1u) }, { qle_uint(0) } };
void Data::compact() void Data::compact()
{ {

View File

@ -1791,6 +1791,8 @@ QString QLocale::toString(qulonglong i) const
Returns a localized string representation of the given \a date in the Returns a localized string representation of the given \a date in the
specified \a format. specified \a format.
If \a format is an empty string, an empty string is returned. If \a format is an empty string, an empty string is returned.
\sa QDate::toString()
*/ */
QString QLocale::toString(const QDate &date, const QString &format) const QString QLocale::toString(const QDate &date, const QString &format) const
@ -1805,6 +1807,8 @@ QString QLocale::toString(const QDate &date, const QString &format) const
Returns a localized string representation of the given \a date in the Returns a localized string representation of the given \a date in the
specified \a format. specified \a format.
If \a format is an empty string, an empty string is returned. If \a format is an empty string, an empty string is returned.
\sa QDate::toString()
*/ */
QString QLocale::toString(const QDate &date, QStringView format) const QString QLocale::toString(const QDate &date, QStringView format) const
{ {
@ -1857,6 +1861,8 @@ static bool timeFormatContainsAP(QStringView format)
Returns a localized string representation of the given \a time according Returns a localized string representation of the given \a time according
to the specified \a format. to the specified \a format.
If \a format is an empty string, an empty string is returned. If \a format is an empty string, an empty string is returned.
\sa QTime::toString()
*/ */
QString QLocale::toString(const QTime &time, const QString &format) const QString QLocale::toString(const QTime &time, const QString &format) const
{ {
@ -1870,6 +1876,8 @@ QString QLocale::toString(const QTime &time, const QString &format) const
Returns a localized string representation of the given \a time according Returns a localized string representation of the given \a time according
to the specified \a format. to the specified \a format.
If \a format is an empty string, an empty string is returned. If \a format is an empty string, an empty string is returned.
\sa QTime::toString()
*/ */
QString QLocale::toString(const QTime &time, QStringView format) const QString QLocale::toString(const QTime &time, QStringView format) const
{ {
@ -1883,6 +1891,8 @@ QString QLocale::toString(const QTime &time, QStringView format) const
Returns a localized string representation of the given \a dateTime according Returns a localized string representation of the given \a dateTime according
to the specified \a format. to the specified \a format.
If \a format is an empty string, an empty string is returned. If \a format is an empty string, an empty string is returned.
\sa QDateTime::toString(), QDate::toString(), QTime::toString()
*/ */
QString QLocale::toString(const QDateTime &dateTime, const QString &format) const QString QLocale::toString(const QDateTime &dateTime, const QString &format) const
@ -1897,6 +1907,8 @@ QString QLocale::toString(const QDateTime &dateTime, const QString &format) cons
Returns a localized string representation of the given \a dateTime according Returns a localized string representation of the given \a dateTime according
to the specified \a format. to the specified \a format.
If \a format is an empty string, an empty string is returned. If \a format is an empty string, an empty string is returned.
\sa QDateTime::toString(), QDate::toString(), QTime::toString()
*/ */
QString QLocale::toString(const QDateTime &dateTime, QStringView format) const QString QLocale::toString(const QDateTime &dateTime, QStringView format) const
{ {

View File

@ -939,6 +939,8 @@
locale doesn't support narrow names, so you should avoid using it locale doesn't support narrow names, so you should avoid using it
for date formatting. Also, for the system locale this format is for date formatting. Also, for the system locale this format is
the same as ShortFormat. the same as ShortFormat.
\sa QDateTime::toString(), QDate::toString(), QTime::toString()
*/ */
/*! /*!
@ -1103,6 +1105,8 @@
\value ListToSeparatedString a string that represents a join of a given QStringList with a locale-defined separator. \value ListToSeparatedString a string that represents a join of a given QStringList with a locale-defined separator.
\value NativeLanguageName a string that represents the name of the native language. \value NativeLanguageName a string that represents the name of the native language.
\value NativeCountryName a string that represents the name of the native country. \value NativeCountryName a string that represents the name of the native country.
\sa FormatType
*/ */
/*! /*!

View File

@ -7388,7 +7388,7 @@ ushort QString::toUShort(bool *ok, int base) const
\snippet qstring/main.cpp 66 \snippet qstring/main.cpp 66
\warning The QString content may only contain valid numerical characters \warning The QString content may only contain valid numerical characters
which includes the plus/minus sign, the characters g and e used in scientific which includes the plus/minus sign, the character e used in scientific
notation, and the decimal point. Including the unit or additional characters notation, and the decimal point. Including the unit or additional characters
leads to a conversion error. leads to a conversion error.
@ -7424,7 +7424,7 @@ double QString::toDouble(bool *ok) const
to \c false, and success by setting *\a{ok} to \c true. to \c false, and success by setting *\a{ok} to \c true.
\warning The QString content may only contain valid numerical characters \warning The QString content may only contain valid numerical characters
which includes the plus/minus sign, the characters g and e used in scientific which includes the plus/minus sign, the character e used in scientific
notation, and the decimal point. Including the unit or additional characters notation, and the decimal point. Including the unit or additional characters
leads to a conversion error. leads to a conversion error.

View File

@ -611,8 +611,6 @@ static int lastIndexOfMutating(const QStringList *that, QRegExp &rx, int from)
the list, searching forward from index position \a from. Returns the list, searching forward from index position \a from. Returns
-1 if no item matched. -1 if no item matched.
By default, this function is case sensitive.
\sa lastIndexOf(), contains(), QRegExp::exactMatch() \sa lastIndexOf(), contains(), QRegExp::exactMatch()
*/ */
int QtPrivate::QStringList_indexOf(const QStringList *that, const QRegExp &rx, int from) int QtPrivate::QStringList_indexOf(const QStringList *that, const QRegExp &rx, int from)
@ -630,8 +628,6 @@ int QtPrivate::QStringList_indexOf(const QStringList *that, const QRegExp &rx, i
the list, searching forward from index position \a from. Returns the list, searching forward from index position \a from. Returns
-1 if no item matched. -1 if no item matched.
By default, this function is case sensitive.
If an item matched, the \a rx regular expression will contain the If an item matched, the \a rx regular expression will contain the
matched objects (see QRegExp::matchedLength, QRegExp::cap). matched objects (see QRegExp::matchedLength, QRegExp::cap).
@ -650,8 +646,6 @@ int QtPrivate::QStringList_indexOf(const QStringList *that, QRegExp &rx, int fro
from is -1 (the default), the search starts at the last item. from is -1 (the default), the search starts at the last item.
Returns -1 if no item matched. Returns -1 if no item matched.
By default, this function is case sensitive.
\sa indexOf(), contains(), QRegExp::exactMatch() \sa indexOf(), contains(), QRegExp::exactMatch()
*/ */
int QtPrivate::QStringList_lastIndexOf(const QStringList *that, const QRegExp &rx, int from) int QtPrivate::QStringList_lastIndexOf(const QStringList *that, const QRegExp &rx, int from)
@ -670,8 +664,6 @@ int QtPrivate::QStringList_lastIndexOf(const QStringList *that, const QRegExp &r
from is -1 (the default), the search starts at the last item. from is -1 (the default), the search starts at the last item.
Returns -1 if no item matched. Returns -1 if no item matched.
By default, this function is case sensitive.
If an item matched, the \a rx regular expression will contain the If an item matched, the \a rx regular expression will contain the
matched objects (see QRegExp::matchedLength, QRegExp::cap). matched objects (see QRegExp::matchedLength, QRegExp::cap).

View File

@ -1144,7 +1144,7 @@ static QVector<QRgb> fix_color_table(const QVector<QRgb> &ctbl, QImage::Format f
if (format == QImage::Format_RGB32) { if (format == QImage::Format_RGB32) {
// check if the color table has alpha // check if the color table has alpha
for (int i = 0; i < colorTable.size(); ++i) for (int i = 0; i < colorTable.size(); ++i)
if (qAlpha(colorTable.at(i) != 0xff)) if (qAlpha(colorTable.at(i)) != 0xff)
colorTable[i] = colorTable.at(i) | 0xff000000; colorTable[i] = colorTable.at(i) | 0xff000000;
} else if (format == QImage::Format_ARGB32_Premultiplied) { } else if (format == QImage::Format_ARGB32_Premultiplied) {
// check if the color table has alpha // check if the color table has alpha
@ -1746,8 +1746,9 @@ static void convert_Indexed8_to_X32(QImageData *dest, const QImageData *src, Qt:
if (colorTable.size() < 256) { if (colorTable.size() < 256) {
int tableSize = colorTable.size(); int tableSize = colorTable.size();
colorTable.resize(256); colorTable.resize(256);
QRgb fallbackColor = (dest->format == QImage::Format_RGB32) ? 0xff000000 : 0;
for (int i=tableSize; i<256; ++i) for (int i=tableSize; i<256; ++i)
colorTable[i] = 0; colorTable[i] = fallbackColor;
} }
int w = src->width; int w = src->width;

View File

@ -115,7 +115,7 @@ static bool read_pbm_header(QIODevice *device, char& type, int& w, int& h, int&
else else
mcc = read_pbm_int(device); // get max color component mcc = read_pbm_int(device); // get max color component
if (w <= 0 || w > 32767 || h <= 0 || h > 32767 || mcc <= 0) if (w <= 0 || w > 32767 || h <= 0 || h > 32767 || mcc <= 0 || mcc > 0xffff)
return false; // weird P.M image return false; // weird P.M image
return true; return true;

View File

@ -39,6 +39,8 @@
#include "qshapedpixmapdndwindow_p.h" #include "qshapedpixmapdndwindow_p.h"
#include "qplatformwindow.h"
#include <QtGui/QPainter> #include <QtGui/QPainter>
#include <QtGui/QCursor> #include <QtGui/QCursor>
#include <QtGui/QGuiApplication> #include <QtGui/QGuiApplication>
@ -70,7 +72,12 @@ void QShapedPixmapWindow::setPixmap(const QPixmap &pixmap)
if (!mask.isNull()) { if (!mask.isNull()) {
if (!handle()) if (!handle())
create(); create();
setMask(mask); if (auto platformWindow = handle()) {
const auto pixmapDpr = m_pixmap.devicePixelRatio();
const auto winDpr = devicePixelRatio();
const auto maskSize = (QSizeF(m_pixmap.size()) * winDpr / pixmapDpr).toSize();
platformWindow->setMask(QBitmap(mask.scaled(maskSize)));
}
} }
} }
} }

View File

@ -841,6 +841,53 @@ static inline void qConvertARGB32PMToARGB64PM_sse2(QRgba64 *buffer, const uint *
*buffer++ = QRgba64::fromArgb32(s); *buffer++ = QRgba64::fromArgb32(s);
} }
} }
#elif defined(__ARM_NEON__)
template<bool RGBA, bool maskAlpha>
static inline void qConvertARGB32PMToRGBA64PM_neon(QRgba64 *buffer, const uint *src, int count)
{
if (count <= 0)
return;
const uint32x4_t amask = vdupq_n_u32(0xff000000);
#if defined(Q_PROCESSOR_ARM_64)
const uint8x16_t rgbaMask = { 2, 1, 0, 3, 6, 5, 4, 7, 10, 9, 8, 11, 14, 13, 12, 15};
#else
const uint8x8_t rgbaMask = { 2, 1, 0, 3, 6, 5, 4, 7 };
#endif
int i = 0;
for (; i < count-3; i += 4) {
uint32x4_t vs32 = vld1q_u32(src);
src += 4;
if (maskAlpha)
vs32 = vorrq_u32(vs32, amask);
uint8x16_t vs8 = vreinterpretq_u8_u32(vs32);
if (!RGBA) {
#if defined(Q_PROCESSOR_ARM_64)
vs8 = vqtbl1q_u8(vs8, rgbaMask);
#else
// no vqtbl1q_u8
const uint8x8_t vlo = vtbl1_u8(vget_low_u8(vs8), rgbaMask);
const uint8x8_t vhi = vtbl1_u8(vget_high_u8(vs8), rgbaMask);
vs8 = vcombine_u8(vlo, vhi);
#endif
}
uint8x16x2_t v = vzipq_u8(vs8, vs8);
vst1q_u16((uint16_t *)buffer, vreinterpretq_u16_u8(v.val[0]));
buffer += 2;
vst1q_u16((uint16_t *)buffer, vreinterpretq_u16_u8(v.val[1]));
buffer += 2;
}
SIMD_EPILOGUE(i, count, 3) {
uint s = *src++;
if (maskAlpha)
s = s | 0xff000000;
if (RGBA)
s = RGBA2ARGB(s);
*buffer++ = QRgba64::fromArgb32(s);
}
}
#endif #endif
static const QRgba64 *QT_FASTCALL convertRGB32ToRGB64(QRgba64 *buffer, const uint *src, int count, static const QRgba64 *QT_FASTCALL convertRGB32ToRGB64(QRgba64 *buffer, const uint *src, int count,
@ -848,6 +895,8 @@ static const QRgba64 *QT_FASTCALL convertRGB32ToRGB64(QRgba64 *buffer, const uin
{ {
#ifdef __SSE2__ #ifdef __SSE2__
qConvertARGB32PMToARGB64PM_sse2<false, true>(buffer, src, count); qConvertARGB32PMToARGB64PM_sse2<false, true>(buffer, src, count);
#elif defined(__ARM_NEON__)
qConvertARGB32PMToRGBA64PM_neon<false, true>(buffer, src, count);
#else #else
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
buffer[i] = QRgba64::fromArgb32(0xff000000 | src[i]); buffer[i] = QRgba64::fromArgb32(0xff000000 | src[i]);
@ -862,6 +911,10 @@ static const QRgba64 *QT_FASTCALL convertARGB32ToARGB64PM(QRgba64 *buffer, const
qConvertARGB32PMToARGB64PM_sse2<false, false>(buffer, src, count); qConvertARGB32PMToARGB64PM_sse2<false, false>(buffer, src, count);
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
buffer[i] = buffer[i].premultiplied(); buffer[i] = buffer[i].premultiplied();
#elif defined(__ARM_NEON__)
qConvertARGB32PMToRGBA64PM_neon<false, false>(buffer, src, count);
for (int i = 0; i < count; ++i)
buffer[i] = buffer[i].premultiplied();
#else #else
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
buffer[i] = QRgba64::fromArgb32(src[i]).premultiplied(); buffer[i] = QRgba64::fromArgb32(src[i]).premultiplied();
@ -874,6 +927,8 @@ static const QRgba64 *QT_FASTCALL convertARGB32PMToARGB64PM(QRgba64 *buffer, con
{ {
#ifdef __SSE2__ #ifdef __SSE2__
qConvertARGB32PMToARGB64PM_sse2<false, false>(buffer, src, count); qConvertARGB32PMToARGB64PM_sse2<false, false>(buffer, src, count);
#elif defined(__ARM_NEON__)
qConvertARGB32PMToRGBA64PM_neon<false, false>(buffer, src, count);
#else #else
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
buffer[i] = QRgba64::fromArgb32(src[i]); buffer[i] = QRgba64::fromArgb32(src[i]);
@ -888,6 +943,10 @@ static const QRgba64 *QT_FASTCALL convertRGBA8888ToARGB64PM(QRgba64 *buffer, con
qConvertARGB32PMToARGB64PM_sse2<true, false>(buffer, src, count); qConvertARGB32PMToARGB64PM_sse2<true, false>(buffer, src, count);
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
buffer[i] = buffer[i].premultiplied(); buffer[i] = buffer[i].premultiplied();
#elif defined(__ARM_NEON__)
qConvertARGB32PMToRGBA64PM_neon<true, false>(buffer, src, count);
for (int i = 0; i < count; ++i)
buffer[i] = buffer[i].premultiplied();
#else #else
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
buffer[i] = QRgba64::fromArgb32(RGBA2ARGB(src[i])).premultiplied(); buffer[i] = QRgba64::fromArgb32(RGBA2ARGB(src[i])).premultiplied();
@ -900,6 +959,8 @@ static const QRgba64 *QT_FASTCALL convertRGBA8888PMToARGB64PM(QRgba64 *buffer, c
{ {
#ifdef __SSE2__ #ifdef __SSE2__
qConvertARGB32PMToARGB64PM_sse2<true, false>(buffer, src, count); qConvertARGB32PMToARGB64PM_sse2<true, false>(buffer, src, count);
#elif defined(__ARM_NEON__)
qConvertARGB32PMToRGBA64PM_neon<true, false>(buffer, src, count);
#else #else
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
buffer[i] = QRgba64::fromArgb32(RGBA2ARGB(src[i])); buffer[i] = QRgba64::fromArgb32(RGBA2ARGB(src[i]));

View File

@ -1056,6 +1056,77 @@ void QRasterPaintEnginePrivate::drawImage(const QPointF &pt,
alpha); alpha);
} }
void QRasterPaintEnginePrivate::blitImage(const QPointF &pt,
const QImage &img,
const QRect &clip,
const QRect &sr)
{
if (!clip.isValid())
return;
Q_ASSERT(img.depth() >= 8);
qsizetype srcBPL = img.bytesPerLine();
const uchar *srcBits = img.bits();
int srcSize = img.depth() >> 3; // This is the part that is incompatible with lower than 8-bit..
int iw = img.width();
int ih = img.height();
if (!sr.isEmpty()) {
iw = sr.width();
ih = sr.height();
// Adjust the image according to the source offset...
srcBits += ((sr.y() * srcBPL) + sr.x() * srcSize);
}
// adapt the x parameters
int x = qRound(pt.x());
int cx1 = clip.x();
int cx2 = clip.x() + clip.width();
if (x < cx1) {
int d = cx1 - x;
srcBits += srcSize * d;
iw -= d;
x = cx1;
}
if (x + iw > cx2) {
int d = x + iw - cx2;
iw -= d;
}
if (iw <= 0)
return;
// adapt the y paremeters...
int cy1 = clip.y();
int cy2 = clip.y() + clip.height();
int y = qRound(pt.y());
if (y < cy1) {
int d = cy1 - y;
srcBits += srcBPL * d;
ih -= d;
y = cy1;
}
if (y + ih > cy2) {
int d = y + ih - cy2;
ih -= d;
}
if (ih <= 0)
return;
// blit..
int dstSize = rasterBuffer->bytesPerPixel();
qsizetype dstBPL = rasterBuffer->bytesPerLine();
const uint *src = (const uint *) srcBits;
uint *dst = reinterpret_cast<uint *>(rasterBuffer->buffer() + x * dstSize + y * dstBPL);
const int len = iw * (qt_depthForFormat(rasterBuffer->format) >> 3);
for (int y = 0; y < ih; ++y) {
memcpy(dst, src, len);
dst = (quint32 *)(((uchar *) dst) + dstBPL);
src = (const quint32 *)(((const uchar *) src) + srcBPL);
}
}
void QRasterPaintEnginePrivate::systemStateChanged() void QRasterPaintEnginePrivate::systemStateChanged()
{ {
@ -2160,7 +2231,15 @@ void QRasterPaintEngine::drawImage(const QPointF &p, const QImage &img)
const QClipData *clip = d->clip(); const QClipData *clip = d->clip();
QPointF pt(p.x() + s->matrix.dx(), p.y() + s->matrix.dy()); QPointF pt(p.x() + s->matrix.dx(), p.y() + s->matrix.dy());
if (d->canUseFastImageBlending(d->rasterBuffer->compositionMode, img)) { if (d->canUseImageBlitting(d->rasterBuffer->compositionMode, img)) {
if (!clip) {
d->blitImage(pt, img, d->deviceRect);
return;
} else if (clip->hasRectClip) {
d->blitImage(pt, img, clip->clipRect);
return;
}
} else if (d->canUseFastImageBlending(d->rasterBuffer->compositionMode, img)) {
SrcOverBlendFunc func = qBlendFunctions[d->rasterBuffer->format][img.format()]; SrcOverBlendFunc func = qBlendFunctions[d->rasterBuffer->format][img.format()];
if (func) { if (func) {
if (!clip) { if (!clip) {
@ -2445,7 +2524,16 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
fillPath(path, &d->image_filler_xform); fillPath(path, &d->image_filler_xform);
s->matrix = m; s->matrix = m;
} else { } else {
if (d->canUseFastImageBlending(d->rasterBuffer->compositionMode, img)) { if (d->canUseImageBlitting(d->rasterBuffer->compositionMode, img)) {
QPointF pt(r.x() + s->matrix.dx(), r.y() + s->matrix.dy());
if (!clip) {
d->blitImage(pt, img, d->deviceRect, sr.toRect());
return;
} else if (clip->hasRectClip) {
d->blitImage(pt, img, clip->clipRect, sr.toRect());
return;
}
} else if (d->canUseFastImageBlending(d->rasterBuffer->compositionMode, img)) {
SrcOverBlendFunc func = qBlendFunctions[d->rasterBuffer->format][img.format()]; SrcOverBlendFunc func = qBlendFunctions[d->rasterBuffer->format][img.format()];
if (func) { if (func) {
QPointF pt(r.x() + s->matrix.dx(), r.y() + s->matrix.dy()); QPointF pt(r.x() + s->matrix.dx(), r.y() + s->matrix.dy());
@ -3668,6 +3756,33 @@ bool QRasterPaintEnginePrivate::canUseFastImageBlending(QPainter::CompositionMod
&& !image.hasAlphaChannel())); && !image.hasAlphaChannel()));
} }
bool QRasterPaintEnginePrivate::canUseImageBlitting(QPainter::CompositionMode mode, const QImage &image) const
{
Q_Q(const QRasterPaintEngine);
const QRasterPaintEngineState *s = q->state();
if (!s->flags.fast_images || s->intOpacity != 256 || qt_depthForFormat(rasterBuffer->format) < 8)
return false;
QImage::Format dFormat = rasterBuffer->format;
QImage::Format sFormat = image.format();
// Formats must match or source format must be a subset of destination format
if (dFormat != sFormat && image.pixelFormat().alphaUsage() == QPixelFormat::IgnoresAlpha) {
if ((sFormat == QImage::Format_RGB32 && dFormat == QImage::Format_ARGB32)
|| (sFormat == QImage::Format_RGBX8888 && dFormat == QImage::Format_RGBA8888))
sFormat = dFormat;
else
sFormat = qt_maybeAlphaVersionWithSameDepth(sFormat); // this returns premul formats
}
if (dFormat != sFormat)
return false;
return s->matrix.type() <= QTransform::TxTranslate
&& (mode == QPainter::CompositionMode_Source
|| (mode == QPainter::CompositionMode_SourceOver
&& !image.hasAlphaChannel()));
}
QImage QRasterBuffer::colorizeBitmap(const QImage &image, const QColor &color) QImage QRasterBuffer::colorizeBitmap(const QImage &image, const QColor &color)
{ {
Q_ASSERT(image.depth() == 1); Q_ASSERT(image.depth() == 1);

View File

@ -291,6 +291,8 @@ public:
void drawImage(const QPointF &pt, const QImage &img, SrcOverBlendFunc func, void drawImage(const QPointF &pt, const QImage &img, SrcOverBlendFunc func,
const QRect &clip, int alpha, const QRect &sr = QRect()); const QRect &clip, int alpha, const QRect &sr = QRect());
void blitImage(const QPointF &pt, const QImage &img,
const QRect &clip, const QRect &sr = QRect());
QTransform brushMatrix() const { QTransform brushMatrix() const {
Q_Q(const QRasterPaintEngine); Q_Q(const QRasterPaintEngine);
@ -313,6 +315,7 @@ public:
void recalculateFastImages(); void recalculateFastImages();
bool canUseFastImageBlending(QPainter::CompositionMode mode, const QImage &image) const; bool canUseFastImageBlending(QPainter::CompositionMode mode, const QImage &image) const;
bool canUseImageBlitting(QPainter::CompositionMode mode, const QImage &image) const;
QPaintDevice *device; QPaintDevice *device;
QScopedPointer<QOutlineMapper> outlineMapper; QScopedPointer<QOutlineMapper> outlineMapper;

View File

@ -1254,7 +1254,7 @@ QFont::StyleStrategy QFont::styleStrategy() const
/*! /*!
Returns the StyleHint. Returns the StyleHint.
The style hint affects the \l{QFont}{font matching} algorithm. The style hint affects the \l{#fontmatching}{font matching algorithm}.
See \l QFont::StyleHint for the list of available hints. See \l QFont::StyleHint for the list of available hints.
\sa setStyleHint(), QFont::StyleStrategy, QFontInfo::styleHint() \sa setStyleHint(), QFont::StyleStrategy, QFontInfo::styleHint()

View File

@ -251,6 +251,20 @@ bool QHttpNetworkConnectionChannel::sendRequest()
return protocolHandler->sendRequest(); return protocolHandler->sendRequest();
} }
/*
* Invoke "protocolHandler->sendRequest" using a queued connection.
* It's used to return to the event loop before invoking sendRequest when
* there's a very real chance that the request could have been aborted
* (i.e. after having emitted 'encrypted').
*/
void QHttpNetworkConnectionChannel::sendRequestDelayed()
{
QMetaObject::invokeMethod(this, [this] {
Q_ASSERT(!protocolHandler.isNull());
if (reply)
protocolHandler->sendRequest();
}, Qt::ConnectionType::QueuedConnection);
}
void QHttpNetworkConnectionChannel::_q_receiveReply() void QHttpNetworkConnectionChannel::_q_receiveReply()
{ {
@ -1234,7 +1248,7 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
emit reply->encrypted(); emit reply->encrypted();
} }
if (reply) if (reply)
sendRequest(); sendRequestDelayed();
} }
} }

View File

@ -174,6 +174,7 @@ public:
void abort(); void abort();
bool sendRequest(); bool sendRequest();
void sendRequestDelayed();
bool ensureConnection(); bool ensureConnection();

View File

@ -61,6 +61,7 @@
#include <algorithm> #include <algorithm>
#include <cstddef> #include <cstddef>
#include <limits>
#include <vector> #include <vector>
#include <QtCore/private/qcore_mac_p.h> #include <QtCore/private/qcore_mac_p.h>
@ -145,6 +146,16 @@ EphemeralSecKeychain::EphemeralSecKeychain()
} }
} }
if (keychain) {
SecKeychainSettings settings = {};
settings.version = SEC_KEYCHAIN_SETTINGS_VERS1;
// Strange, huh? But that's what their docs say to do! With lockOnSleep
// == false, set interval to INT_MAX to never lock ...
settings.lockInterval = INT_MAX;
if (SecKeychainSetSettings(keychain, &settings) != errSecSuccess)
qCWarning(lcSsl) << "SecKeychainSettings: failed to disable lock on sleep";
}
#ifdef QSSLSOCKET_DEBUG #ifdef QSSLSOCKET_DEBUG
if (keychain) { if (keychain) {
qCDebug(lcSsl) << "Custom keychain with name" << keychainName << "was created" qCDebug(lcSsl) << "Custom keychain with name" << keychainName << "was created"

View File

@ -354,7 +354,8 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length,
(*image) = QImage(swidth, sheight, format); (*image) = QImage(swidth, sheight, format);
bpl = image->bytesPerLine(); bpl = image->bytesPerLine();
bits = image->bits(); bits = image->bits();
memset(bits, 0, image->sizeInBytes()); if (bits)
memset(bits, 0, image->sizeInBytes());
} }
// Check if the previous attempt to create the image failed. If it // Check if the previous attempt to create the image failed. If it
@ -415,6 +416,10 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length,
backingstore = QImage(qMax(backingstore.width(), w), backingstore = QImage(qMax(backingstore.width(), w),
qMax(backingstore.height(), h), qMax(backingstore.height(), h),
QImage::Format_RGB32); QImage::Format_RGB32);
if (backingstore.isNull()) {
state = Error;
return -1;
}
memset(backingstore.bits(), 0, backingstore.sizeInBytes()); memset(backingstore.bits(), 0, backingstore.sizeInBytes());
} }
const int dest_bpl = backingstore.bytesPerLine(); const int dest_bpl = backingstore.bytesPerLine();

View File

@ -213,26 +213,23 @@
Q_ASSERT(mainMenu); Q_ASSERT(mainMenu);
#endif #endif
// Grab the app menu out of the current menu. // Grab the app menu out of the current menu.
const int numItems = mainMenu.numberOfItems; auto unparentAppMenu = ^bool (NSMenu *supermenu) {
NSMenuItem *oldAppMenuItem = nil; auto index = [supermenu indexOfItemWithSubmenu:appMenu];
for (int i = 0; i < numItems; ++i) { if (index != -1) {
NSMenuItem *item = [mainMenu itemAtIndex:i]; [supermenu removeItemAtIndex:index];
if (item.submenu == appMenu) { return true;
oldAppMenuItem = item;
[oldAppMenuItem retain];
[mainMenu removeItemAtIndex:i];
break;
} }
} return false;
};
if (oldAppMenuItem) { if (!mainMenu || !unparentAppMenu(mainMenu))
oldAppMenuItem.submenu = nil; if (appMenu.supermenu)
[oldAppMenuItem release]; unparentAppMenu(appMenu.supermenu);
NSMenuItem *appMenuItem = [[NSMenuItem alloc] initWithTitle:@"Apple"
action:nil keyEquivalent:@""]; NSMenuItem *appMenuItem = [[NSMenuItem alloc] initWithTitle:@"Apple"
appMenuItem.submenu = appMenu; action:nil keyEquivalent:@""];
[menu insertItem:appMenuItem atIndex:0]; appMenuItem.submenu = appMenu;
} [menu insertItem:appMenuItem atIndex:0];
} }
- (NSMenu *)menu - (NSMenu *)menu

View File

@ -550,6 +550,7 @@ CursorHandlePtr QWindowsCursor::standardWindowCursor(Qt::CursorShape shape)
} }
HCURSOR QWindowsCursor::m_overriddenCursor = nullptr; HCURSOR QWindowsCursor::m_overriddenCursor = nullptr;
HCURSOR QWindowsCursor::m_overrideCursor = nullptr;
/*! /*!
\brief Return cached pixmap cursor or create new one. \brief Return cached pixmap cursor or create new one.
@ -622,11 +623,20 @@ void QWindowsCursor::changeCursor(QCursor *cursorIn, QWindow *window)
} }
} }
// QTBUG-69637: Override cursors can get reset externally when moving across
// window borders. Enforce the cursor again (to be called from enter event).
void QWindowsCursor::enforceOverrideCursor()
{
if (hasOverrideCursor() && m_overrideCursor != GetCursor())
SetCursor(m_overrideCursor);
}
void QWindowsCursor::setOverrideCursor(const QCursor &cursor) void QWindowsCursor::setOverrideCursor(const QCursor &cursor)
{ {
const CursorHandlePtr wcursor = cursorHandle(cursor); const CursorHandlePtr wcursor = cursorHandle(cursor);
if (wcursor->handle()) { if (const auto overrideCursor = wcursor->handle()) {
const HCURSOR previousCursor = SetCursor(wcursor->handle()); m_overrideCursor = overrideCursor;
const HCURSOR previousCursor = SetCursor(overrideCursor);
if (m_overriddenCursor == nullptr) if (m_overriddenCursor == nullptr)
m_overriddenCursor = previousCursor; m_overriddenCursor = previousCursor;
} else { } else {
@ -639,7 +649,7 @@ void QWindowsCursor::clearOverrideCursor()
{ {
if (m_overriddenCursor) { if (m_overriddenCursor) {
SetCursor(m_overriddenCursor); SetCursor(m_overriddenCursor);
m_overriddenCursor = nullptr; m_overriddenCursor = m_overrideCursor = nullptr;
} }
} }

View File

@ -107,7 +107,8 @@ public:
void changeCursor(QCursor * widgetCursor, QWindow * widget) override; void changeCursor(QCursor * widgetCursor, QWindow * widget) override;
void setOverrideCursor(const QCursor &cursor) override; void setOverrideCursor(const QCursor &cursor) override;
void clearOverrideCursor() override; void clearOverrideCursor() override;
bool hasOverrideCursor() const { return m_overriddenCursor != nullptr; } static void enforceOverrideCursor();
static bool hasOverrideCursor() { return m_overriddenCursor != nullptr; }
QPoint pos() const override; QPoint pos() const override;
void setPos(const QPoint &pos) override; void setPos(const QPoint &pos) override;
@ -143,6 +144,7 @@ private:
mutable QPixmap m_ignoreDragCursor; mutable QPixmap m_ignoreDragCursor;
static HCURSOR m_overriddenCursor; static HCURSOR m_overriddenCursor;
static HCURSOR m_overrideCursor;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -2108,6 +2108,8 @@ bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow *
HWND desktopHWND = GetDesktopWindow(); HWND desktopHWND = GetDesktopWindow();
platformWindow->m_data.embedded = !parentWindow && parentHWND && (parentHWND != desktopHWND); platformWindow->m_data.embedded = !parentWindow && parentHWND && (parentHWND != desktopHWND);
} }
if (qWindow->flags().testFlag(Qt::WindowStaysOnBottomHint))
windowPos->hwndInsertAfter = HWND_BOTTOM;
} }
if (!qWindow->isTopLevel()) // Implement hasHeightForWidth(). if (!qWindow->isTopLevel()) // Implement hasHeightForWidth().
return false; return false;
@ -2454,8 +2456,11 @@ static inline bool applyNewCursor(const QWindow *w)
void QWindowsWindow::applyCursor() void QWindowsWindow::applyCursor()
{ {
if (static_cast<const QWindowsCursor *>(screen()->cursor())->hasOverrideCursor()) if (QWindowsCursor::hasOverrideCursor()) {
if (isTopLevel())
QWindowsCursor::enforceOverrideCursor();
return; return;
}
#ifndef QT_NO_CURSOR #ifndef QT_NO_CURSOR
if (m_cursor->isNull()) { // Recurse up to parent with non-null cursor. Set default for toplevel. if (m_cursor->isNull()) { // Recurse up to parent with non-null cursor. Set default for toplevel.
if (const QWindow *p = window()->parent()) { if (const QWindow *p = window()->parent()) {

View File

@ -68,21 +68,18 @@ QWindowsUiaAccessibility::~QWindowsUiaAccessibility()
// Handles UI Automation window messages. // Handles UI Automation window messages.
bool QWindowsUiaAccessibility::handleWmGetObject(HWND hwnd, WPARAM wParam, LPARAM lParam, LRESULT *lResult) bool QWindowsUiaAccessibility::handleWmGetObject(HWND hwnd, WPARAM wParam, LPARAM lParam, LRESULT *lResult)
{ {
if (lParam == LPARAM(UiaRootObjectId)) { // Start handling accessibility internally
QGuiApplicationPrivate::platformIntegration()->accessibility()->setActive(true);
// Start handling accessibility internally // Ignoring all requests while starting up / shutting down
QGuiApplicationPrivate::platformIntegration()->accessibility()->setActive(true); if (QCoreApplication::startingUp() || QCoreApplication::closingDown())
return false;
// Ignoring all requests while starting up / shutting down if (QWindow *window = QWindowsContext::instance()->findWindow(hwnd)) {
if (QCoreApplication::startingUp() || QCoreApplication::closingDown()) if (QAccessibleInterface *accessible = window->accessibleRoot()) {
return false; QWindowsUiaMainProvider *provider = QWindowsUiaMainProvider::providerForAccessible(accessible);
*lResult = QWindowsUiaWrapper::instance()->returnRawElementProvider(hwnd, wParam, lParam, provider);
if (QWindow *window = QWindowsContext::instance()->findWindow(hwnd)) { return true;
if (QAccessibleInterface *accessible = window->accessibleRoot()) {
QWindowsUiaMainProvider *provider = QWindowsUiaMainProvider::providerForAccessible(accessible);
*lResult = QWindowsUiaWrapper::instance()->returnRawElementProvider(hwnd, wParam, lParam, provider);
return true;
}
} }
} }
return false; return false;

View File

@ -149,7 +149,7 @@ long roleToControlTypeId(QAccessible::Role role)
{QAccessible::Caret, UIA_CustomControlTypeId}, {QAccessible::Caret, UIA_CustomControlTypeId},
{QAccessible::AlertMessage, UIA_CustomControlTypeId}, {QAccessible::AlertMessage, UIA_CustomControlTypeId},
{QAccessible::Window, UIA_WindowControlTypeId}, {QAccessible::Window, UIA_WindowControlTypeId},
{QAccessible::Client, UIA_CustomControlTypeId}, {QAccessible::Client, UIA_GroupControlTypeId},
{QAccessible::PopupMenu, UIA_MenuControlTypeId}, {QAccessible::PopupMenu, UIA_MenuControlTypeId},
{QAccessible::MenuItem, UIA_MenuItemControlTypeId}, {QAccessible::MenuItem, UIA_MenuItemControlTypeId},
{QAccessible::ToolTip, UIA_ToolTipControlTypeId}, {QAccessible::ToolTip, UIA_ToolTipControlTypeId},

View File

@ -1693,10 +1693,8 @@ bool QXcbConnection::compressEvent(xcb_generic_event_t *event, int currentIndex,
continue; continue;
if (isXIType(next, m_xiOpCode, XCB_INPUT_TOUCH_UPDATE)) { if (isXIType(next, m_xiOpCode, XCB_INPUT_TOUCH_UPDATE)) {
auto *touchUpdateNextEvent = reinterpret_cast<xcb_input_touch_update_event_t *>(next); auto *touchUpdateNextEvent = reinterpret_cast<xcb_input_touch_update_event_t *>(next);
if (id == touchUpdateNextEvent->detail % INT_MAX && if (id == touchUpdateNextEvent->detail % INT_MAX)
touchUpdateNextEvent->deviceid == touchUpdateEvent->deviceid) {
return true; return true;
}
} }
} }
return false; return false;

View File

@ -569,7 +569,6 @@ private:
bool m_xi2Enabled = false; bool m_xi2Enabled = false;
#if QT_CONFIG(xcb_xinput) #if QT_CONFIG(xcb_xinput)
QVector<int> m_floatingSlaveDevices;
int m_xi2Minor = -1; int m_xi2Minor = -1;
void initializeXInput2(); void initializeXInput2();
void xi2SetupDevice(void *info, bool removeExisting = true); void xi2SetupDevice(void *info, bool removeExisting = true);

View File

@ -113,7 +113,7 @@ void QXcbConnection::xi2SelectDeviceEvents(xcb_window_t window)
} }
qt_xcb_input_event_mask_t mask; qt_xcb_input_event_mask_t mask;
mask.header.deviceid = XCB_INPUT_DEVICE_ALL; mask.header.deviceid = XCB_INPUT_DEVICE_ALL_MASTER;
mask.header.mask_len = 1; mask.header.mask_len = 1;
mask.mask = bitMask; mask.mask = bitMask;
xcb_void_cookie_t cookie = xcb_void_cookie_t cookie =
@ -309,7 +309,6 @@ void QXcbConnection::xi2SetupDevices()
m_scrollingDevices.clear(); m_scrollingDevices.clear();
m_touchDevices.clear(); m_touchDevices.clear();
m_xiMasterPointerIds.clear(); m_xiMasterPointerIds.clear();
m_floatingSlaveDevices.clear();
auto reply = Q_XCB_REPLY(xcb_input_xi_query_device, m_connection, XCB_INPUT_DEVICE_ALL); auto reply = Q_XCB_REPLY(xcb_input_xi_query_device, m_connection, XCB_INPUT_DEVICE_ALL);
if (!reply) { if (!reply) {
@ -320,10 +319,6 @@ void QXcbConnection::xi2SetupDevices()
auto it = xcb_input_xi_query_device_infos_iterator(reply.get()); auto it = xcb_input_xi_query_device_infos_iterator(reply.get());
for (; it.rem; xcb_input_xi_device_info_next(&it)) { for (; it.rem; xcb_input_xi_device_info_next(&it)) {
xcb_input_xi_device_info_t *deviceInfo = it.data; xcb_input_xi_device_info_t *deviceInfo = it.data;
if (deviceInfo->type == XCB_INPUT_DEVICE_TYPE_FLOATING_SLAVE) {
m_floatingSlaveDevices.append(deviceInfo->deviceid);
continue;
}
if (deviceInfo->type == XCB_INPUT_DEVICE_TYPE_MASTER_POINTER) { if (deviceInfo->type == XCB_INPUT_DEVICE_TYPE_MASTER_POINTER) {
m_xiMasterPointerIds.append(deviceInfo->deviceid); m_xiMasterPointerIds.append(deviceInfo->deviceid);
continue; continue;
@ -547,72 +542,6 @@ static inline qreal fixed1616ToReal(xcb_input_fp1616_t val)
} }
#endif // QT_CONFIG(tabletevent) #endif // QT_CONFIG(tabletevent)
namespace {
/*! \internal
Qt listens for XIAllDevices to avoid losing mouse events. This function
ensures that we don't process the same event twice: from a slave device and
then again from a master device.
In a normal use case (e.g. mouse press and release inside a window), we will
drop events from master devices as duplicates. Other advantage of processing
events from slave devices is that they don't share button state. All buttons
on a master device share the state.
Examples of special cases:
- During system move/resize, window manager (_NET_WM_MOVERESIZE) grabs the
master pointer, in this case we process the matching release from the slave
device. A master device event is not sent by the server, hence no duplicate
event to drop. If we listened for XIAllMasterDevices instead, we would never
see a release event in this case.
- If we dismiss a context menu by clicking somewhere outside a Qt application,
we will process the mouse press from the master pointer as that is the
device we are grabbing. We are not grabbing slave devices (grabbing on the
slave device is buggy according to 19d289ab1b5bde3e136765e5432b5c7d004df3a4).
And since the event occurs outside our window, the slave device event is
not sent to us by the server, hence no duplicate event to drop.
*/
bool isDuplicateEvent(xcb_ge_event_t *event)
{
struct qXIEvent {
bool isValid = false;
uint16_t sourceid;
uint8_t event_type;
uint32_t detail;
int32_t root_x;
int32_t root_y;
};
static qXIEvent lastSeenEvent;
bool isDuplicate = false;
auto xiDeviceEvent = reinterpret_cast<qt_xcb_input_device_event_t *>(event);
if (lastSeenEvent.isValid) {
isDuplicate = lastSeenEvent.sourceid == xiDeviceEvent->sourceid &&
lastSeenEvent.event_type == xiDeviceEvent->event_type &&
lastSeenEvent.detail == xiDeviceEvent->detail &&
lastSeenEvent.root_x == xiDeviceEvent->root_x &&
lastSeenEvent.root_y == xiDeviceEvent->root_y;
} else {
lastSeenEvent.isValid = true;
}
lastSeenEvent.sourceid = xiDeviceEvent->sourceid;
lastSeenEvent.event_type = xiDeviceEvent->event_type;
lastSeenEvent.detail = xiDeviceEvent->detail;
lastSeenEvent.root_x = xiDeviceEvent->root_x;
lastSeenEvent.root_y = xiDeviceEvent->root_y;
if (isDuplicate)
// This sanity check ensures that special cases like QTBUG-59277 keep working.
lastSeenEvent.isValid = false; // An event can be a duplicate only once.
return isDuplicate;
}
} // namespace
void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
{ {
auto *xiEvent = reinterpret_cast<qt_xcb_input_device_event_t *>(event); auto *xiEvent = reinterpret_cast<qt_xcb_input_device_event_t *>(event);
@ -621,31 +550,15 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
xcb_input_enter_event_t *xiEnterEvent = nullptr; xcb_input_enter_event_t *xiEnterEvent = nullptr;
QXcbWindowEventListener *eventListener = 0; QXcbWindowEventListener *eventListener = 0;
bool isTouchEvent = true;
switch (xiEvent->event_type) { switch (xiEvent->event_type) {
case XCB_INPUT_BUTTON_PRESS: case XCB_INPUT_BUTTON_PRESS:
case XCB_INPUT_BUTTON_RELEASE: case XCB_INPUT_BUTTON_RELEASE:
case XCB_INPUT_MOTION: case XCB_INPUT_MOTION:
isTouchEvent = false;
if (!xi2MouseEventsDisabled() && isDuplicateEvent(event))
return;
case XCB_INPUT_TOUCH_BEGIN: case XCB_INPUT_TOUCH_BEGIN:
case XCB_INPUT_TOUCH_UPDATE: case XCB_INPUT_TOUCH_UPDATE:
case XCB_INPUT_TOUCH_END: case XCB_INPUT_TOUCH_END:
{ {
xiDeviceEvent = xiEvent; xiDeviceEvent = xiEvent;
if (m_floatingSlaveDevices.contains(xiDeviceEvent->sourceid))
return; // Not interested in floating slave device events, only in attached slaves.
bool isSlaveEvent = xiDeviceEvent->deviceid == xiDeviceEvent->sourceid;
if (!xi2MouseEventsDisabled() && isTouchEvent && isSlaveEvent) {
// For touch events we want events only from master devices, at least
// currently there is no apparent reason why we would need to consider
// events from slave devices.
return;
}
eventListener = windowEventListenerFromId(xiDeviceEvent->event); eventListener = windowEventListenerFromId(xiDeviceEvent->event);
sourceDeviceId = xiDeviceEvent->sourceid; // use the actual device id instead of the master sourceDeviceId = xiDeviceEvent->sourceid; // use the actual device id instead of the master
break; break;

View File

@ -2569,12 +2569,13 @@ bool QXcbWindow::startSystemMove(const QPoint &pos)
bool QXcbWindow::startSystemMoveResize(const QPoint &pos, int corner) bool QXcbWindow::startSystemMoveResize(const QPoint &pos, int corner)
{ {
#if QT_CONFIG(xcb_xinput) return false; // ### FIXME QTBUG-69716
const xcb_atom_t moveResize = connection()->atom(QXcbAtom::_NET_WM_MOVERESIZE); const xcb_atom_t moveResize = connection()->atom(QXcbAtom::_NET_WM_MOVERESIZE);
if (!connection()->wmSupport()->isSupportedByWM(moveResize)) if (!connection()->wmSupport()->isSupportedByWM(moveResize))
return false; return false;
const QPoint globalPos = QHighDpi::toNativePixels(window()->mapToGlobal(pos), window()->screen()); const QPoint globalPos = QHighDpi::toNativePixels(window()->mapToGlobal(pos), window()->screen());
#if QT_CONFIG(xcb_xinput)
// ### FIXME QTBUG-53389 // ### FIXME QTBUG-53389
bool startedByTouch = connection()->startSystemMoveResizeForTouchBegin(m_window, globalPos, corner); bool startedByTouch = connection()->startSystemMoveResizeForTouchBegin(m_window, globalPos, corner);
if (startedByTouch) { if (startedByTouch) {
@ -2584,11 +2585,9 @@ bool QXcbWindow::startSystemMoveResize(const QPoint &pos, int corner)
return false; return false;
} }
// KWin, Openbox, AwesomeWM have been tested to work with _NET_WM_MOVERESIZE. // KWin, Openbox, AwesomeWM have been tested to work with _NET_WM_MOVERESIZE.
} else { // Started by mouse press. } else
if (!connection()->hasXInput2() || connection()->xi2MouseEventsDisabled()) { #endif
// Without XI2 we can't get button press/move/release events. { // Started by mouse press.
return false;
}
if (connection()->isUnity()) if (connection()->isUnity())
return false; // _NET_WM_MOVERESIZE on this WM is bouncy (WM bug?). return false; // _NET_WM_MOVERESIZE on this WM is bouncy (WM bug?).
@ -2596,11 +2595,6 @@ bool QXcbWindow::startSystemMoveResize(const QPoint &pos, int corner)
} }
return true; return true;
#else
Q_UNUSED(pos);
Q_UNUSED(corner);
return false;
#endif // xcb_xinput
} }
void QXcbWindow::doStartSystemMoveResize(const QPoint &globalPos, int corner) void QXcbWindow::doStartSystemMoveResize(const QPoint &globalPos, int corner)

View File

@ -1,37 +0,0 @@
Before building the Qt library, the Qt SQL module can be enabled for
specific databases using 'configure'. 'configure' is located at the
top of your QTDIR.
Specific databases drivers can be enabled using one of the following
options:
./configure [-qt-sql-<driver>] [-plugin-sql-<driver>]
or disabled using the following option:
./configure [-no-sql-<driver>]
Where <driver> is the name of the driver, for example 'psql'. This
will configure the Qt library to compile the specified driver into
the Qt lib itself.
For example, to build the PostgreSQL driver directly into the Qt
library, configure Qt like this:
./configure -qt-sql-psql
In addition, you may need to specify an extra include path, as some
database drivers require headers for the database they are using,
for example:
./configure -qt-sql-psql -I/usr/local/include
If instead you need to build the PostgreSQL driver as a dynamically
loaded plugin, configure Qt like this:
./configure -plugin-sql-psql
To compile drivers as dynamically loaded plugins, see the
QTDIR/plugins/src/sqldrivers directory. Use 'configure -help'
for a complete list of configure options. See the Qt documentation
for a complete list of supported database drivers.

View File

@ -31,12 +31,10 @@
\brief The QTestEventList class provides a list of GUI events. \brief The QTestEventList class provides a list of GUI events.
QTestEventList inherits from QList<QTestEvent *>, and provides
convenience functions for populating the list.
A QTestEventList can be populated with GUI events that can be A QTestEventList can be populated with GUI events that can be
stored as test data for later usage, or be replayed on any stored as test data for later usage, or be replayed on any
QWidget. QWidget. QTestEventList provides convenience functions for populating
the list.
Example: Example:
\snippet code/doc_src_qtestevent.cpp 0 \snippet code/doc_src_qtestevent.cpp 0
@ -174,4 +172,3 @@
\sa QTest::mousePress() \sa QTest::mousePress()
*/ */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -7147,6 +7147,12 @@ void QWidget::move(const QPoint &p)
// move() was invoked with Qt::WA_WState_Created not set (frame geometry // move() was invoked with Qt::WA_WState_Created not set (frame geometry
// unknown), that is, crect has a position including the frame. // unknown), that is, crect has a position including the frame.
// If we can determine the frame strut, fix that and clear the flag. // If we can determine the frame strut, fix that and clear the flag.
// FIXME: This does not play well with window states other than
// Qt::WindowNoState, as we depend on calling setGeometry() on the
// platform window after fixing up the position so that the new
// geometry is reflected in the platform window, but when the frame
// comes in after the window has been shown (e.g. maximized), we're
// not in a position to do that kind of fixup.
void QWidgetPrivate::fixPosIncludesFrame() void QWidgetPrivate::fixPosIncludesFrame()
{ {
Q_Q(QWidget); Q_Q(QWidget);

View File

@ -879,9 +879,16 @@ QSize QCommonStylePrivate::viewItemSize(const QStyleOptionViewItem *option, int
QRect bounds = option->rect; QRect bounds = option->rect;
switch (option->decorationPosition) { switch (option->decorationPosition) {
case QStyleOptionViewItem::Left: case QStyleOptionViewItem::Left:
case QStyleOptionViewItem::Right: case QStyleOptionViewItem::Right: {
bounds.setWidth(wrapText && bounds.isValid() ? bounds.width() - 2 * textMargin : QFIXED_MAX); if (wrapText && bounds.isValid()) {
int width = bounds.width() - 2 * textMargin;
if (option->features & QStyleOptionViewItem::HasDecoration)
width -= option->decorationSize.width() + 2 * textMargin;
bounds.setWidth(width);
} else
bounds.setWidth(QFIXED_MAX);
break; break;
}
case QStyleOptionViewItem::Top: case QStyleOptionViewItem::Top:
case QStyleOptionViewItem::Bottom: case QStyleOptionViewItem::Bottom:
if (wrapText) if (wrapText)
@ -893,12 +900,8 @@ QSize QCommonStylePrivate::viewItemSize(const QStyleOptionViewItem *option, int
break; break;
} }
if (wrapText) { if (wrapText && option->features & QStyleOptionViewItem::HasCheckIndicator)
if (option->features & QStyleOptionViewItem::HasCheckIndicator) bounds.setWidth(bounds.width() - proxyStyle->pixelMetric(QStyle::PM_IndicatorWidth) - 2 * textMargin);
bounds.setWidth(bounds.width() - proxyStyle->pixelMetric(QStyle::PM_IndicatorWidth) - 2 * textMargin);
if (option->features & QStyleOptionViewItem::HasDecoration)
bounds.setWidth(bounds.width() - option->decorationSize.width() - 2 * textMargin);
}
const int lineWidth = bounds.width(); const int lineWidth = bounds.width();
const QSizeF size = viewItemTextLayout(textLayout, lineWidth); const QSizeF size = viewItemTextLayout(textLayout, lineWidth);

View File

@ -189,7 +189,7 @@ QLabelPrivate::~QLabelPrivate()
#ifndef QT_NO_PICTURE #ifndef QT_NO_PICTURE
/*! /*!
Returns the label's picture or 0 if the label doesn't have a Returns the label's picture or nullptr if the label doesn't have a
picture. picture.
*/ */
@ -348,7 +348,7 @@ void QLabel::clear()
\property QLabel::pixmap \property QLabel::pixmap
\brief the label's pixmap \brief the label's pixmap
If no pixmap has been set this will return 0. If no pixmap has been set this will return nullptr.
Setting the pixmap clears any previous content. The buddy Setting the pixmap clears any previous content. The buddy
shortcut, if any, is disabled. shortcut, if any, is disabled.
@ -1157,7 +1157,7 @@ void QLabelPrivate::updateLabel()
Alt+P. Alt+P.
To unset a previously set buddy, call this function with \a buddy To unset a previously set buddy, call this function with \a buddy
set to 0. set to nullptr.
\sa buddy(), setText(), QShortcut, setAlignment() \sa buddy(), setText(), QShortcut, setAlignment()
*/ */
@ -1187,7 +1187,7 @@ void QLabel::setBuddy(QWidget *buddy)
/*! /*!
Returns this label's buddy, or 0 if no buddy is currently set. Returns this label's buddy, or nullptr if no buddy is currently set.
\sa setBuddy() \sa setBuddy()
*/ */
@ -1339,7 +1339,7 @@ void QLabelPrivate::clearContents()
#if QT_CONFIG(movie) #if QT_CONFIG(movie)
/*! /*!
Returns a pointer to the label's movie, or 0 if no movie has been Returns a pointer to the label's movie, or nullptr if no movie has been
set. set.
\sa setMovie() \sa setMovie()

View File

@ -11,6 +11,7 @@ SUBPROGRAMS = \
testProcessEOF \ testProcessEOF \
testExitCodes \ testExitCodes \
testForwarding \ testForwarding \
testForwardingHelper \
testGuiProcess \ testGuiProcess \
testDetached \ testDetached \
fileWriterProcess \ fileWriterProcess \

View File

@ -27,15 +27,32 @@
****************************************************************************/ ****************************************************************************/
#include <QtCore/QCoreApplication> #include <QtCore/QCoreApplication>
#include <QtCore/QDeadlineTimer>
#include <QtCore/QProcess> #include <QtCore/QProcess>
#include <QtCore/QTemporaryFile>
#include <QtCore/QThread>
#include <stdlib.h> #include <stdlib.h>
static bool waitForDoneFileWritten(const QString &filePath, int msecs = 30000)
{
QDeadlineTimer t(msecs);
do {
QThread::msleep(250);
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly))
continue;
if (file.readAll() == "That's all folks!")
return true;
} while (!t.hasExpired());
return false;
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
QCoreApplication app(argc, argv); QCoreApplication app(argc, argv);
if (argc < 3) if (argc < 4)
return 13; return 13;
QProcess process; QProcess process;
@ -50,23 +67,37 @@ int main(int argc, char **argv)
if (process.inputChannelMode() != inmode) if (process.inputChannelMode() != inmode)
return 11; return 11;
process.start("testProcessEcho2/testProcessEcho2"); if (atoi(argv[3])) {
QTemporaryFile doneFile("testForwarding_XXXXXX.txt");
if (!doneFile.open())
return 12;
doneFile.close();
if (!process.waitForStarted(5000)) process.setProgram("testForwardingHelper/testForwardingHelper");
return 2; process.setArguments(QStringList(doneFile.fileName()));
if (!process.startDetached())
return 13;
if (!waitForDoneFileWritten(doneFile.fileName()))
return 14;
} else {
process.start("testProcessEcho2/testProcessEcho2");
if (inmode == QProcess::ManagedInputChannel && process.write("forwarded") != 9) if (!process.waitForStarted(5000))
return 3; return 2;
process.closeWriteChannel(); if (inmode == QProcess::ManagedInputChannel && process.write("forwarded") != 9)
if (!process.waitForFinished(5000)) return 3;
return 4;
if ((mode == QProcess::ForwardedOutputChannel || mode == QProcess::ForwardedChannels) process.closeWriteChannel();
if (!process.waitForFinished(5000))
return 4;
if ((mode == QProcess::ForwardedOutputChannel || mode == QProcess::ForwardedChannels)
&& !process.readAllStandardOutput().isEmpty()) && !process.readAllStandardOutput().isEmpty())
return 5; return 5;
if ((mode == QProcess::ForwardedErrorChannel || mode == QProcess::ForwardedChannels) if ((mode == QProcess::ForwardedErrorChannel || mode == QProcess::ForwardedChannels)
&& !process.readAllStandardError().isEmpty()) && !process.readAllStandardError().isEmpty())
return 6; return 6;
}
return 0; return 0;
} }

View File

@ -0,0 +1,45 @@
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** 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 General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** 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-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <fstream>
#include <stdio.h>
int main(int argc, char *argv[])
{
if (argc < 2) {
puts("Usage: testForwardingHelper <doneFilePath>");
return 1;
}
fputs("out data", stdout);
fputs("err data", stderr);
fflush(stdout);
fflush(stderr);
std::ofstream out(argv[1]);
out << "That's all folks!";
return 0;
}

View File

@ -0,0 +1,4 @@
SOURCES = main.cpp
CONFIG -= qt app_bundle
CONFIG += console
DESTDIR = ./

View File

@ -1047,32 +1047,50 @@ void tst_QProcess::mergedChannels()
void tst_QProcess::forwardedChannels_data() void tst_QProcess::forwardedChannels_data()
{ {
QTest::addColumn<bool>("detach");
QTest::addColumn<int>("mode"); QTest::addColumn<int>("mode");
QTest::addColumn<int>("inmode"); QTest::addColumn<int>("inmode");
QTest::addColumn<QByteArray>("outdata"); QTest::addColumn<QByteArray>("outdata");
QTest::addColumn<QByteArray>("errdata"); QTest::addColumn<QByteArray>("errdata");
QTest::newRow("separate") << int(QProcess::SeparateChannels) << int(QProcess::ManagedInputChannel) QTest::newRow("separate")
<< QByteArray() << QByteArray(); << false
QTest::newRow("forwarded") << int(QProcess::ForwardedChannels) << int(QProcess::ManagedInputChannel) << int(QProcess::SeparateChannels) << int(QProcess::ManagedInputChannel)
<< QByteArray("forwarded") << QByteArray("forwarded"); << QByteArray() << QByteArray();
QTest::newRow("stdout") << int(QProcess::ForwardedOutputChannel) << int(QProcess::ManagedInputChannel) QTest::newRow("forwarded")
<< QByteArray("forwarded") << QByteArray(); << false
QTest::newRow("stderr") << int(QProcess::ForwardedErrorChannel) << int(QProcess::ManagedInputChannel) << int(QProcess::ForwardedChannels) << int(QProcess::ManagedInputChannel)
<< QByteArray() << QByteArray("forwarded"); << QByteArray("forwarded") << QByteArray("forwarded");
QTest::newRow("fwdinput") << int(QProcess::ForwardedErrorChannel) << int(QProcess::ForwardedInputChannel) QTest::newRow("stdout")
<< QByteArray() << QByteArray("input"); << false
<< int(QProcess::ForwardedOutputChannel) << int(QProcess::ManagedInputChannel)
<< QByteArray("forwarded") << QByteArray();
QTest::newRow("stderr")
<< false
<< int(QProcess::ForwardedErrorChannel) << int(QProcess::ManagedInputChannel)
<< QByteArray() << QByteArray("forwarded");
QTest::newRow("fwdinput")
<< false
<< int(QProcess::ForwardedErrorChannel) << int(QProcess::ForwardedInputChannel)
<< QByteArray() << QByteArray("input");
QTest::newRow("detached-default-forwarding")
<< true
<< int(QProcess::SeparateChannels) << int(QProcess::ManagedInputChannel)
<< QByteArray("out data") << QByteArray("err data");
} }
void tst_QProcess::forwardedChannels() void tst_QProcess::forwardedChannels()
{ {
QFETCH(bool, detach);
QFETCH(int, mode); QFETCH(int, mode);
QFETCH(int, inmode); QFETCH(int, inmode);
QFETCH(QByteArray, outdata); QFETCH(QByteArray, outdata);
QFETCH(QByteArray, errdata); QFETCH(QByteArray, errdata);
QProcess process; QProcess process;
process.start("testForwarding/testForwarding", QStringList() << QString::number(mode) << QString::number(inmode)); process.start("testForwarding/testForwarding",
QStringList() << QString::number(mode) << QString::number(inmode)
<< QString::number(bool(detach)));
QVERIFY(process.waitForStarted(5000)); QVERIFY(process.waitForStarted(5000));
QCOMPARE(process.write("input"), 5); QCOMPARE(process.write("input"), 5);
process.closeWriteChannel(); process.closeWriteChannel();
@ -1089,7 +1107,9 @@ void tst_QProcess::forwardedChannels()
case 4: err = "did not finish"; break; case 4: err = "did not finish"; break;
case 5: err = "unexpected stdout"; break; case 5: err = "unexpected stdout"; break;
case 6: err = "unexpected stderr"; break; case 6: err = "unexpected stderr"; break;
case 13: err = "parameter error"; break; case 12: err = "cannot create temp file"; break;
case 13: err = "startDetached failed"; break;
case 14: err = "waitForDoneFileWritten timed out"; break;
default: err = "unknown exit code"; break; default: err = "unknown exit code"; break;
} }
QVERIFY2(!process.exitCode(), err); QVERIFY2(!process.exitCode(), err);

View File

@ -2968,6 +2968,7 @@ void tst_QObject::dynamicProperties()
QVERIFY(obj.dynamicPropertyNames().isEmpty()); QVERIFY(obj.dynamicPropertyNames().isEmpty());
// set a non-dynamic property
QVERIFY(obj.setProperty("number", 42)); QVERIFY(obj.setProperty("number", 42));
QVERIFY(obj.changedDynamicProperties.isEmpty()); QVERIFY(obj.changedDynamicProperties.isEmpty());
QCOMPARE(obj.property("number").toInt(), 42); QCOMPARE(obj.property("number").toInt(), 42);
@ -2975,19 +2976,30 @@ void tst_QObject::dynamicProperties()
QVERIFY(!obj.setProperty("number", "invalid string")); QVERIFY(!obj.setProperty("number", "invalid string"));
QVERIFY(obj.changedDynamicProperties.isEmpty()); QVERIFY(obj.changedDynamicProperties.isEmpty());
// set a dynamic property
QVERIFY(!obj.setProperty("myuserproperty", "Hello")); QVERIFY(!obj.setProperty("myuserproperty", "Hello"));
QCOMPARE(obj.changedDynamicProperties.count(), 1); QCOMPARE(obj.changedDynamicProperties.count(), 1);
QCOMPARE(obj.changedDynamicProperties.first(), QByteArray("myuserproperty")); QCOMPARE(obj.changedDynamicProperties.first(), QByteArray("myuserproperty"));
//check if there is no redundant DynamicPropertyChange events //check if there is no redundant DynamicPropertyChange events
QVERIFY(!obj.setProperty("myuserproperty", "Hello")); QVERIFY(!obj.setProperty("myuserproperty", "Hello"));
QCOMPARE(obj.changedDynamicProperties.count(), 1); QCOMPARE(obj.changedDynamicProperties.count(), 1);
obj.changedDynamicProperties.clear();
QCOMPARE(obj.property("myuserproperty").type(), QVariant::String);
QCOMPARE(obj.property("myuserproperty").toString(), QString("Hello")); QCOMPARE(obj.property("myuserproperty").toString(), QString("Hello"));
QCOMPARE(obj.dynamicPropertyNames().count(), 1); QCOMPARE(obj.dynamicPropertyNames().count(), 1);
QCOMPARE(obj.dynamicPropertyNames().first(), QByteArray("myuserproperty")); QCOMPARE(obj.dynamicPropertyNames().first(), QByteArray("myuserproperty"));
// change type of the dynamic property
obj.changedDynamicProperties.clear();
QVERIFY(!obj.setProperty("myuserproperty", QByteArray("Hello")));
QCOMPARE(obj.changedDynamicProperties.count(), 1);
QCOMPARE(obj.changedDynamicProperties.first(), QByteArray("myuserproperty"));
QCOMPARE(obj.property("myuserproperty").type(), QVariant::ByteArray);
QCOMPARE(obj.property("myuserproperty").toString(), QByteArray("Hello"));
// unset the property
obj.changedDynamicProperties.clear();
QVERIFY(!obj.setProperty("myuserproperty", QVariant())); QVERIFY(!obj.setProperty("myuserproperty", QVariant()));
QCOMPARE(obj.changedDynamicProperties.count(), 1); QCOMPARE(obj.changedDynamicProperties.count(), 1);

View File

@ -648,6 +648,7 @@ void tst_QtJson::testArrayNestedEmpty()
object.insert("inner", inner); object.insert("inner", inner);
QJsonValue val = object.value("inner"); QJsonValue val = object.value("inner");
QJsonArray value = object.value("inner").toArray(); QJsonArray value = object.value("inner").toArray();
QVERIFY(QJsonDocument(value).isArray());
QCOMPARE(value.size(), 0); QCOMPARE(value.size(), 0);
QCOMPARE(value, inner); QCOMPARE(value, inner);
QCOMPARE(value.size(), 0); QCOMPARE(value.size(), 0);
@ -666,6 +667,7 @@ void tst_QtJson::testObjectNestedEmpty()
object.insert("inner", inner); object.insert("inner", inner);
object.insert("inner2", inner2); object.insert("inner2", inner2);
QJsonObject value = object.value("inner").toObject(); QJsonObject value = object.value("inner").toObject();
QVERIFY(QJsonDocument(value).isObject());
QCOMPARE(value.size(), 0); QCOMPARE(value.size(), 0);
QCOMPARE(value, inner); QCOMPARE(value, inner);
QCOMPARE(value.size(), 0); QCOMPARE(value.size(), 0);

View File

@ -227,6 +227,8 @@ private slots:
void hugeQImage(); void hugeQImage();
void convertColorTable();
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
void toWinHBITMAP_data(); void toWinHBITMAP_data();
void toWinHBITMAP(); void toWinHBITMAP();
@ -3496,6 +3498,19 @@ void tst_QImage::hugeQImage()
#endif #endif
} }
void tst_QImage::convertColorTable()
{
QImage image(10, 10, QImage::Format_Indexed8);
image.setColor(0, 0x80ffffff);
image.fill(0);
QImage argb32 = image.convertToFormat(QImage::Format_ARGB32);
QCOMPARE(argb32.pixel(0,0), 0x80ffffff);
QImage argb32pm = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
QCOMPARE(argb32pm.pixel(0,0), 0x80808080);
QImage rgb32 = image.convertToFormat(QImage::Format_RGB32);
QCOMPARE(rgb32.pixel(0,0), 0xffffffff);
}
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
Q_GUI_EXPORT HBITMAP qt_imageToWinHBITMAP(const QImage &p, int hbitmapFormat = 0); Q_GUI_EXPORT HBITMAP qt_imageToWinHBITMAP(const QImage &p, int hbitmapFormat = 0);

View File

@ -393,6 +393,7 @@ private Q_SLOTS:
void ignoreSslErrorsListWithSlot_data(); void ignoreSslErrorsListWithSlot_data();
void ignoreSslErrorsListWithSlot(); void ignoreSslErrorsListWithSlot();
void encrypted(); void encrypted();
void abortOnEncrypted();
void sslConfiguration_data(); void sslConfiguration_data();
void sslConfiguration(); void sslConfiguration();
#ifdef QT_BUILD_INTERNAL #ifdef QT_BUILD_INTERNAL
@ -6365,6 +6366,37 @@ void tst_QNetworkReply::encrypted()
reply->deleteLater(); reply->deleteLater();
} }
void tst_QNetworkReply::abortOnEncrypted()
{
SslServer server;
server.listen();
if (!server.isListening())
QSKIP("Server fails to listen. Skipping since QTcpServer is covered in another test.");
server.connect(&server, &SslServer::newEncryptedConnection, [&server]() {
connect(server.socket, &QTcpSocket::readyRead, server.socket, []() {
// This slot must not be invoked!
QVERIFY(false);
});
});
QNetworkAccessManager nm;
QNetworkReply *reply = nm.get(QNetworkRequest(QUrl(QString("https://localhost:%1").arg(server.serverPort()))));
reply->ignoreSslErrors();
connect(reply, &QNetworkReply::encrypted, [reply, &nm]() {
reply->abort();
nm.clearConnectionCache();
});
QSignalSpy spyEncrypted(reply, &QNetworkReply::encrypted);
QTRY_COMPARE(spyEncrypted.count(), 1);
// Wait for the socket to be closed again in order to be sure QTcpSocket::readyRead would have been emitted.
QTRY_VERIFY(server.socket != nullptr);
QTRY_COMPARE(server.socket->state(), QAbstractSocket::UnconnectedState);
}
void tst_QNetworkReply::sslConfiguration() void tst_QNetworkReply::sslConfiguration()
{ {
QNetworkRequest request(QUrl("https://" + QtNetworkSettings::httpServerName() + "/index.html")); QNetworkRequest request(QUrl("https://" + QtNetworkSettings::httpServerName() + "/index.html"));