summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfigure11
-rw-r--r--examples/network/torrent/mainwindow.cpp2
-rw-r--r--mkspecs/features/qt.prf15
-rw-r--r--mkspecs/features/qt_build_config.prf7
-rw-r--r--mkspecs/features/qt_build_extra.prf40
-rw-r--r--mkspecs/features/qt_functions.prf13
-rw-r--r--qmake/generators/win32/msvc_nmake.cpp7
-rw-r--r--src/3rdparty/libpng/ANNOUNCE121
-rw-r--r--src/3rdparty/libpng/CHANGES34
-rw-r--r--src/3rdparty/libpng/LICENSE4
-rw-r--r--src/3rdparty/libpng/README2
-rw-r--r--src/3rdparty/libpng/libpng-manual.txt9
-rw-r--r--src/3rdparty/libpng/png.c8
-rw-r--r--src/3rdparty/libpng/png.h23
-rw-r--r--src/3rdparty/libpng/pngconf.h2
-rw-r--r--src/3rdparty/libpng/pngerror.c2
-rw-r--r--src/3rdparty/libpng/pnginfo.h2
-rw-r--r--src/3rdparty/libpng/pnglibconf.h2
-rw-r--r--src/3rdparty/libpng/pngpread.c4
-rw-r--r--src/3rdparty/libpng/pngpriv.h8
-rw-r--r--src/3rdparty/libpng/pngread.c1
-rw-r--r--src/3rdparty/libpng/pngrutil.c43
-rw-r--r--src/3rdparty/libpng/pngset.c6
-rw-r--r--src/3rdparty/libpng/pngstruct.h3
-rw-r--r--src/3rdparty/libpng/pngwutil.c6
-rw-r--r--src/corelib/global/qlogging.cpp5
-rw-r--r--src/corelib/global/qtypeinfo.h4
-rw-r--r--src/corelib/io/qprocess_win.cpp6
-rw-r--r--src/corelib/io/qstandardpaths_win.cpp22
-rw-r--r--src/corelib/io/qwindowspipereader.cpp154
-rw-r--r--src/corelib/io/qwindowspipereader_p.h32
-rw-r--r--src/corelib/io/qwindowspipewriter.cpp239
-rw-r--r--src/corelib/io/qwindowspipewriter_p.h70
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt.cpp10
-rw-r--r--src/corelib/kernel/qobject.h16
-rw-r--r--src/corelib/thread/qthread.cpp5
-rw-r--r--src/corelib/tools/qrect.h2
-rw-r--r--src/corelib/tools/qtimezone.cpp4
-rw-r--r--src/corelib/tools/qtimezoneprivate_win.cpp100
-rw-r--r--src/corelib/tools/tools.pri6
-rw-r--r--src/dbus/qdbusintegrator.cpp42
-rw-r--r--src/dbus/qdbusintegrator_p.h1
-rw-r--r--src/gui/kernel/qshapedpixmapdndwindow.cpp72
-rw-r--r--src/gui/kernel/qshapedpixmapdndwindow_p.h10
-rw-r--r--src/gui/painting/qcosmeticstroker.cpp26
-rw-r--r--src/gui/text/qfont.cpp4
-rw-r--r--src/gui/text/qrawfont.cpp3
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp2
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp54
-rw-r--r--src/network/access/qnetworkcookiejar.cpp2
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp2
-rw-r--r--src/network/access/qnetworkrequest.cpp12
-rw-r--r--src/network/socket/qlocalserver_win.cpp70
-rw-r--r--src/network/socket/qlocalsocket_win.cpp1
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp12
-rw-r--r--src/platformsupport/clipboard/qmacmime.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm10
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.h13
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm78
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.h6
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.mm115
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.h3
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm17
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm11
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp7
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp30
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp6
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp1
-rw-r--r--src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp37
-rw-r--r--src/sql/kernel/qsqlresult.h5
-rw-r--r--src/testlib/Qt5TestConfigExtras.cmake.in5
-rw-r--r--src/widgets/dialogs/qerrormessage.cpp2
-rw-r--r--src/widgets/dialogs/qfileinfogatherer.cpp2
-rw-r--r--src/widgets/dialogs/qsidebar.cpp2
-rw-r--r--src/widgets/effects/qgraphicseffect.cpp3
-rw-r--r--src/widgets/effects/qpixmapfilter.cpp2
-rw-r--r--src/widgets/graphicsview/qgraphicsanchorlayout.cpp3
-rw-r--r--src/widgets/graphicsview/qgraphicsitemanimation.cpp2
-rw-r--r--src/widgets/graphicsview/qgraphicsscenelinearindex.cpp1
-rw-r--r--src/widgets/graphicsview/qgraphicswidget.cpp2
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp15
-rw-r--r--src/widgets/itemviews/qcolumnviewgrip.cpp2
-rw-r--r--src/widgets/itemviews/qitemeditorfactory.cpp2
-rw-r--r--src/widgets/itemviews/qlistview.cpp2
-rw-r--r--src/widgets/itemviews/qlistwidget.cpp1
-rw-r--r--src/widgets/itemviews/qtablewidget.cpp1
-rw-r--r--src/widgets/itemviews/qtreewidget.cpp1
-rw-r--r--src/widgets/kernel/qboxlayout.cpp2
-rw-r--r--src/widgets/kernel/qdesktopwidget.cpp1
-rw-r--r--src/widgets/kernel/qformlayout.cpp2
-rw-r--r--src/widgets/kernel/qgridlayout.cpp2
-rw-r--r--src/widgets/kernel/qlayout.cpp2
-rw-r--r--src/widgets/kernel/qopenglwidget.cpp2
-rw-r--r--src/widgets/kernel/qshortcut.cpp2
-rw-r--r--src/widgets/kernel/qsizepolicy.cpp2
-rw-r--r--src/widgets/kernel/qstackedlayout.cpp2
-rw-r--r--src/widgets/kernel/qwidget.cpp3
-rw-r--r--src/widgets/kernel/qwidget.h52
-rw-r--r--src/widgets/kernel/qwidget_p.h3
-rw-r--r--src/widgets/kernel/qwidgetbackingstore.cpp2
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp2
-rw-r--r--src/widgets/kernel/qwindowcontainer.cpp2
-rw-r--r--src/widgets/statemachine/qbasickeyeventtransition.cpp2
-rw-r--r--src/widgets/statemachine/qbasicmouseeventtransition.cpp2
-rw-r--r--src/widgets/statemachine/qkeyeventtransition.cpp2
-rw-r--r--src/widgets/statemachine/qmouseeventtransition.cpp2
-rw-r--r--src/widgets/styles/qfusionstyle.cpp2
-rw-r--r--src/widgets/styles/qmacstyle_mac.mm90
-rw-r--r--src/widgets/styles/qmacstyle_mac_p_p.h2
-rw-r--r--src/widgets/styles/qproxystyle.cpp2
-rw-r--r--src/widgets/styles/qstyle.cpp2
-rw-r--r--src/widgets/styles/qstyle.h10
-rw-r--r--src/widgets/styles/qstyleanimation.cpp2
-rw-r--r--src/widgets/styles/qstyleplugin.cpp2
-rw-r--r--src/widgets/styles/qwindowsstyle.cpp2
-rw-r--r--src/widgets/styles/qwindowsstyle_p.h1
-rw-r--r--src/widgets/styles/qwindowsxpstyle_p.h1
-rw-r--r--src/widgets/util/qcompleter.cpp2
-rw-r--r--src/widgets/util/qflickgesture.cpp2
-rw-r--r--src/widgets/util/qscroller.cpp3
-rw-r--r--src/widgets/util/qsystemtrayicon.cpp1
-rw-r--r--src/widgets/util/qundogroup.cpp2
-rw-r--r--src/widgets/util/qundostack.cpp3
-rw-r--r--src/widgets/util/qundoview.cpp1
-rw-r--r--src/widgets/widgets/qabstractbutton.cpp137
-rw-r--r--src/widgets/widgets/qabstractbutton_p.h2
-rw-r--r--src/widgets/widgets/qabstractslider.cpp2
-rw-r--r--src/widgets/widgets/qbuttongroup.cpp129
-rw-r--r--src/widgets/widgets/qbuttongroup_p.h80
-rw-r--r--src/widgets/widgets/qcheckbox.cpp2
-rw-r--r--src/widgets/widgets/qcombobox.cpp1
-rw-r--r--src/widgets/widgets/qcommandlinkbutton.cpp1
-rw-r--r--src/widgets/widgets/qdatetimeedit.cpp1
-rw-r--r--src/widgets/widgets/qdial.cpp2
-rw-r--r--src/widgets/widgets/qdockwidget.cpp1
-rw-r--r--src/widgets/widgets/qfocusframe.cpp2
-rw-r--r--src/widgets/widgets/qframe.cpp2
-rw-r--r--src/widgets/widgets/qkeysequenceedit.cpp2
-rw-r--r--src/widgets/widgets/qlcdnumber.cpp2
-rw-r--r--src/widgets/widgets/qlineedit_p.cpp2
-rw-r--r--src/widgets/widgets/qmainwindow.cpp2
-rw-r--r--src/widgets/widgets/qmainwindowlayout.cpp2
-rw-r--r--src/widgets/widgets/qprogressbar.cpp2
-rw-r--r--src/widgets/widgets/qradiobutton.cpp2
-rw-r--r--src/widgets/widgets/qrubberband.cpp2
-rw-r--r--src/widgets/widgets/qscrollarea.cpp2
-rw-r--r--src/widgets/widgets/qscrollbar.cpp2
-rw-r--r--src/widgets/widgets/qslider.cpp2
-rw-r--r--src/widgets/widgets/qspinbox.cpp2
-rw-r--r--src/widgets/widgets/qsplashscreen.cpp2
-rw-r--r--src/widgets/widgets/qsplitter.cpp2
-rw-r--r--src/widgets/widgets/qstackedwidget.cpp2
-rw-r--r--src/widgets/widgets/qstatusbar.cpp2
-rw-r--r--src/widgets/widgets/qtabbar.cpp2
-rw-r--r--src/widgets/widgets/qtoolbarextension.cpp2
-rw-r--r--src/widgets/widgets/qtoolbarextension_p.h1
-rw-r--r--src/widgets/widgets/qtoolbarlayout.cpp2
-rw-r--r--src/widgets/widgets/qtoolbarseparator.cpp2
-rw-r--r--src/widgets/widgets/qwidgetanimator.cpp2
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol.cpp2
-rw-r--r--src/widgets/widgets/qwidgetresizehandler.cpp2
-rw-r--r--src/widgets/widgets/widgets.pri2
-rw-r--r--tests/auto/cmake/CMakeLists.txt18
-rw-r--r--tests/auto/cmake/test_QFINDTESTDATA/CMakeLists.txt11
-rw-r--r--tests/auto/cmake/test_QFINDTESTDATA/tests/CMakeLists.txt4
-rw-r--r--tests/auto/cmake/test_QFINDTESTDATA/tests/main.cpp55
-rw-r--r--tests/auto/cmake/test_QFINDTESTDATA/tests/testdata.txt1
-rw-r--r--tests/auto/corelib/io/qtextstream/test/test.pro4
-rw-r--r--tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp22
-rw-r--r--tests/auto/corelib/plugin/plugin.pro6
-rw-r--r--tests/auto/corelib/tools/qrect/tst_qrect.cpp5
-rw-r--r--tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp2
-rw-r--r--tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp3
-rw-r--r--tests/auto/gui/text/qstatictext/qstatictext.pro4
-rw-r--r--tests/auto/gui/text/qstatictext/tst_qstatictext.cpp6
-rw-r--r--tests/auto/gui/text/text.pro1
-rw-r--r--tests/auto/network/socket/qlocalsocket/BLACKLIST2
-rw-r--r--tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp9
-rw-r--r--tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp82
-rw-r--r--tests/auto/widgets/widgets/qdockwidget/BLACKLIST2
-rw-r--r--tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp26
-rw-r--r--tests/manual/foreignwindows/foreignwindows.pro6
-rw-r--r--tests/manual/foreignwindows/main.cpp329
-rw-r--r--tests/manual/highdpi/dragwidget.cpp6
-rw-r--r--tests/manual/highdpi/main.cpp23
-rw-r--r--tests/manual/manual.pro4
189 files changed, 2045 insertions, 977 deletions
diff --git a/configure b/configure
index 8b508ddf44..e90c31e30f 100755
--- a/configure
+++ b/configure
@@ -6553,9 +6553,9 @@ fi
[ "$CFG_SYSTEM_PROXIES" = "yes" ] && QT_CONFIG="$QT_CONFIG system-proxies"
[ "$CFG_DIRECTWRITE" = "yes" ] && QT_CONFIG="$QT_CONFIG directwrite"
-[ '!' -z "$DEFINES" ] && QMakeVar add DEFINES "$DEFINES"
-[ '!' -z "$INCLUDES" ] && QMakeVar add INCLUDEPATH "$INCLUDES"
-[ '!' -z "$L_FLAGS" ] && QMakeVar add LIBS "$L_FLAGS"
+[ '!' -z "$DEFINES" ] && QMakeVar add EXTRA_DEFINES "$DEFINES"
+[ '!' -z "$INCLUDES" ] && QMakeVar add EXTRA_INCLUDEPATH "$INCLUDES"
+[ '!' -z "$L_FLAGS" ] && QMakeVar add EXTRA_LIBS "$L_FLAGS"
if [ -z "`getXQMakeConf 'QMAKE_(LFLAGS_)?RPATH'`" ]; then
if [ -n "$RPATH_FLAGS" ]; then
@@ -6571,7 +6571,7 @@ if [ -z "`getXQMakeConf 'QMAKE_(LFLAGS_)?RPATH'`" ]; then
else
if [ -n "$RPATH_FLAGS" ]; then
# add the user defined rpaths
- QMakeVar add QMAKE_RPATHDIR "$RPATH_FLAGS"
+ QMakeVar add EXTRA_RPATHS "$RPATH_FLAGS"
fi
fi
if [ "$CFG_RPATH" = "yes" ]; then
@@ -7159,9 +7159,6 @@ if [ -n "$CFG_SYSROOT" ] && [ "$CFG_GCC_SYSROOT" = "yes" ]; then
echo "}"
echo
fi
-if [ -n "$RPATH_FLAGS" ]; then
- echo "QMAKE_RPATHDIR += $RPATH_FLAGS"
-fi
echo "QT_COMPILER_STDCXX = $CFG_STDCXX_DEFAULT"
if [ -n "$QT_GCC_MAJOR_VERSION" ]; then
echo "QT_GCC_MAJOR_VERSION = $QT_GCC_MAJOR_VERSION"
diff --git a/examples/network/torrent/mainwindow.cpp b/examples/network/torrent/mainwindow.cpp
index 2b87f71294..bfe221c129 100644
--- a/examples/network/torrent/mainwindow.cpp
+++ b/examples/network/torrent/mainwindow.cpp
@@ -702,7 +702,7 @@ void TorrentView::dragMoveEvent(QDragMoveEvent *event)
{
// Accept file actions with a '.torrent' extension.
QUrl url(event->mimeData()->text());
- if (url.isValid() && url.scheme().toLower() == "file"
+ if (url.isValid() && url.scheme() == "file"
&& url.path().toLower().endsWith(".torrent"))
event->acceptProposedAction();
}
diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf
index 4b40451c96..e54841a678 100644
--- a/mkspecs/features/qt.prf
+++ b/mkspecs/features/qt.prf
@@ -160,21 +160,8 @@ qt_module_deps = $$resolve_depends(qt_module_deps, "QT.")
contains(qt_module_deps, core) {
relative_qt_rpath:!isEmpty(QMAKE_REL_RPATH_BASE):contains(INSTALLS, target):\
isEmpty(target.files):isEmpty(target.commands):isEmpty(target.extra) {
- mac {
- if(equals(TEMPLATE, app):app_bundle)|\
- if(equals(TEMPLATE, lib):plugin:plugin_bundle) {
- ios: binpath = $$target.path/$${TARGET}.app
- else: binpath = $$target.path/$${TARGET}.app/Contents/MacOS
- } else: equals(TEMPLATE, lib):!plugin:lib_bundle {
- binpath = $$target.path/$${TARGET}.framework/Versions/Current
- } else {
- binpath = $$target.path
- }
- } else {
- binpath = $$target.path
- }
# NOT the /dev property, as INSTALLS use host paths
- QMAKE_RPATHDIR += $$relative_path($$[QT_INSTALL_LIBS], $$binpath)
+ QMAKE_RPATHDIR += $$relative_path($$[QT_INSTALL_LIBS], $$qtRelativeRPathBase())
} else {
QMAKE_RPATHDIR += $$[QT_INSTALL_LIBS/dev]
}
diff --git a/mkspecs/features/qt_build_config.prf b/mkspecs/features/qt_build_config.prf
index 518fd93f04..2d437e7f91 100644
--- a/mkspecs/features/qt_build_config.prf
+++ b/mkspecs/features/qt_build_config.prf
@@ -52,6 +52,9 @@ QMAKE_DIR_REPLACE_SANE = PRECOMPILED_DIR OBJECTS_DIR MOC_DIR RCC_DIR UI_DIR
unset(modpath)
}
+# Apply extra compiler flags passed via configure last.
+CONFIG = qt_build_extra $$CONFIG
+
# Don't actually try to install anything in non-prefix builds.
# This is much easier and safer than making every single INSTALLS
# assignment conditional.
@@ -72,6 +75,10 @@ CONFIG += \
# However, testcases should be still built with exceptions.
exceptions_off testcase_exceptions
+# Under Windows, this is neither necessary (transitive deps are automatically
+# resolved), nor functional (.res files end up in .prl files and break things).
+unix: CONFIG += explicitlib
+
defineTest(qtBuildPart) {
bp = $$eval($$upper($$section(_QMAKE_CONF_, /, -2, -2))_BUILD_PARTS)
diff --git a/mkspecs/features/qt_build_extra.prf b/mkspecs/features/qt_build_extra.prf
new file mode 100644
index 0000000000..378f5bbd7c
--- /dev/null
+++ b/mkspecs/features/qt_build_extra.prf
@@ -0,0 +1,40 @@
+#
+# W A R N I N G
+# -------------
+#
+# This file is not part of the Qt API. It exists purely as an
+# implementation detail. It may change from version to version
+# without notice, or even be removed.
+#
+# We mean it.
+#
+
+equals(TEMPLATE, subdirs): return()
+
+# It's likely that these extra flags will be wrong for host builds,
+# and the bootstrapped tools usually don't need them anyway.
+host_build:force_bootstrap: return()
+
+# The headersclean check needs defines and includes even for
+# header-only modules.
+DEFINES += $$EXTRA_DEFINES
+INCLUDEPATH += $$EXTRA_INCLUDEPATH
+
+# The other flags are relevant only for actual libraries.
+equals(TEMPLATE, aux): return()
+
+LIBS += $$EXTRA_LIBS
+
+# Static libs need no rpaths
+static: return()
+
+for (rp, EXTRA_RPATHS) {
+ absrp = $$absolute_path($$rp, $$[QT_INSTALL_LIBS])
+ !isEqual(absrp, $$rp) {
+ isEmpty(QMAKE_REL_RPATH_BASE)|!contains(INSTALLS, target): \
+ rp = $$absrp
+ else: \
+ rp = $$relative_path($$absrp, $$qtRelativeRPathBase())
+ }
+ QMAKE_RPATHDIR += $$rp
+}
diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf
index 2756f90b01..9c3414c6fc 100644
--- a/mkspecs/features/qt_functions.prf
+++ b/mkspecs/features/qt_functions.prf
@@ -33,6 +33,19 @@ defineReplace(qt5LibraryTarget) {
return($$LIBRARY_NAME)
}
+defineReplace(qtRelativeRPathBase) {
+ darwin {
+ if(equals(TEMPLATE, app):app_bundle)|\
+ if(equals(TEMPLATE, lib):plugin:plugin_bundle) {
+ ios: return($$target.path/$${TARGET}.app)
+ return($$target.path/$${TARGET}.app/Contents/MacOS)
+ }
+ equals(TEMPLATE, lib):!plugin:lib_bundle: \
+ return($$target.path/$${TARGET}.framework/Versions/Current)
+ }
+ return($$target.path)
+}
+
defineTest(qtAddLibrary) {
warning("qtAddLibrary() is deprecated. Use QT+= instead.")
diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp
index 25a2765a01..d8ac80f99d 100644
--- a/qmake/generators/win32/msvc_nmake.cpp
+++ b/qmake/generators/win32/msvc_nmake.cpp
@@ -258,12 +258,9 @@ void NmakeMakefileGenerator::writeSubMakeCall(QTextStream &t, const QString &cal
QString NmakeMakefileGenerator::defaultInstall(const QString &t)
{
- if((t != "target" && t != "dlltarget") ||
- (t == "dlltarget" && (project->first("TEMPLATE") != "lib" || !project->isActiveConfig("shared"))) ||
- project->first("TEMPLATE") == "subdirs")
- return QString();
-
QString ret = Win32MakefileGenerator::defaultInstall(t);
+ if (ret.isEmpty())
+ return ret;
const QString root = installRoot();
ProStringList &uninst = project->values(ProKey(t + ".uninstall"));
diff --git a/src/3rdparty/libpng/ANNOUNCE b/src/3rdparty/libpng/ANNOUNCE
index 9f1b665834..4dae783b55 100644
--- a/src/3rdparty/libpng/ANNOUNCE
+++ b/src/3rdparty/libpng/ANNOUNCE
@@ -1,4 +1,4 @@
-Libpng 1.6.19 - November 12, 2015
+Libpng 1.6.20 - December 3, 2015
This is a public release of libpng, intended for use in production codes.
@@ -7,104 +7,41 @@ Files available for download:
Source files with LF line endings (for Unix/Linux) and with a
"configure" script
- libpng-1.6.19.tar.xz (LZMA-compressed, recommended)
- libpng-1.6.19.tar.gz
+ libpng-1.6.20.tar.xz (LZMA-compressed, recommended)
+ libpng-1.6.20.tar.gz
Source files with CRLF line endings (for Windows), without the
"configure" script
- lpng1619.7z (LZMA-compressed, recommended)
- lpng1619.zip
+ /scratch/glennrp/Libpng16/lpng1620.7z (LZMA-compressed, recommended)
+ /scratch/glennrp/Libpng16/lpng1620.zip
Other information:
- libpng-1.6.19-README.txt
- libpng-1.6.19-LICENSE.txt
- libpng-1.6.19-*.asc (armored detached GPG signatures)
-
-Changes since the last public release (1.6.18):
-
- Updated obsolete information about the simplified API macros in the
- manual pages (Bug report by Arc Riley).
- Avoid potentially dereferencing NULL info_ptr in png_info_init_3().
- Rearranged png.h to put the major sections in the same order as
- in libpng17.
- Eliminated unused PNG_COST_SHIFT, PNG_WEIGHT_SHIFT, PNG_COST_FACTOR, and
- PNG_WEIGHT_FACTOR macros.
- Suppressed some warnings from the Borland C++ 5.5.1/5.82 compiler
- (Bug report by Viktor Szakats). Several warnings remain and are
- unavoidable, where we test for overflow.
- Fixed potential leak of png_pixels in contrib/pngminus/pnm2png.c
- Fixed uninitialized variable in contrib/gregbook/rpng2-x.c
- Moved config.h.in~ from the "libpng_autotools_files" list to the
- "libpng_autotools_extra" list in autogen.sh because it was causing a
- false positive for missing files (bug report by Robert C. Seacord).
- Removed unreachable "break" statements in png.c, pngread.c, and pngrtran.c
- to suppress clang warnings (Bug report by Viktor Szakats).
- Fixed some bad links in the man page.
- Changed "n bit" to "n-bit" in comments.
- Added signed/unsigned 16-bit safety net. This removes the dubious
- 0x8000 flag definitions on 16-bit systems. They aren't supported
- yet the defs *probably* work, however it seems much safer to do this
- and be advised if anyone, contrary to advice, is building libpng 1.6
- on a 16-bit system. It also adds back various switch default clauses
- for GCC; GCC errors out if they are not present (with an appropriately
- high level of warnings).
- Safely convert num_bytes to a png_byte in png_set_sig_bytes() (Robert
- Seacord).
- Fixed the recently reported 1's complement security issue by replacing
- the value that is illegal in the PNG spec, in both signed and unsigned
- values, with 0. Illegal unsigned values (anything greater than or equal
- to 0x80000000) can still pass through, but since these are not illegal
- in ANSI-C (unlike 0x80000000 in the signed case) the checking that
- occurs later can catch them (John Bowler).
- Fixed png_save_int_32 when int is not 2's complement (John Bowler).
- Updated libpng16 with all the recent test changes from libpng17,
- including changes to pngvalid.c to ensure that the original,
- distributed, version of contrib/visupng/cexcept.h can be used
- (John Bowler).
- pngvalid contains the correction to the use of SAVE/STORE_
- UNKNOWN_CHUNKS; a bug revealed by changes in libpng 1.7. More
- tests contain the --strict option to detect warnings and the
- pngvalid-standard test has been corrected so that it does not
- turn on progressive-read. There is a separate test which does
- that. (John Bowler)
- Also made some signed/unsigned fixes.
- Make pngstest error limits version specific. Splitting the machine
- generated error structs out to a file allows the values to be updated
- without changing pngstest.c itself. Since libpng 1.6 and 1.7 have
- slightly different error limits this simplifies maintenance. The
- makepngs.sh script has also been updated to more accurately reflect
- current problems in libpng 1.7 (John Bowler).
- Incorporated new test PNG files into make check. tests/pngstest-*
- are changed so that the new test files are divided into 8 groups by
- gamma and alpha channel. These tests have considerably better code
- and pixel-value coverage than contrib/pngsuite; however,coverage is
- still incomplete (John Bowler).
- Removed the '--strict' in 1.6 because of the double-gamma-correction
- warning, updated pngstest-errors.h for the errors detected with the
- new contrib/testspngs PNG test files (John Bowler).
- Worked around rgb-to-gray issues in libpng 1.6. The previous
- attempts to ignore the errors in the code aren't quite enough to
- deal with the 'channel selection' encoding added to libpng 1.7; abort.
- Fixed 'pow' macros in pngvalid.c. It is legal for 'pow' to be a
- macro, therefore the argument list cannot contain preprocessing
- directives. Make sure pow is a function where this happens. This is
- a minimal safe fix, the issue only arises in non-performance-critical
- code (bug report by Curtis Leach, fix by John Bowler).
- Added sPLT support to pngtest.c
- Prevent setting or writing over-length PLTE chunk (Cosmin Truta).
- Silently truncate over-length PLTE chunk while reading.
- Libpng incorrectly calculated the output rowbytes when the application
- decreased either the number of channels or the bit depth (or both) in
- a user transform. This was safe; libpng overallocated buffer space
- (potentially by quite a lot; up to 4 times the amount required) but,
- from 1.5.4 on, resulted in a png_error (John Bowler).
- Fixed some inconsequential cut-and-paste typos in png_set_cHRM_XYZ_fixed().
- Clarified COPYRIGHT information to state explicitly that versions
- are derived from previous versions.
- Removed much of the long list of previous versions from png.h and
- libpng.3.
+ libpng-1.6.20-README.txt
+ libpng-1.6.20-LICENSE.txt
+ libpng-1.6.20-*.asc (armored detached GPG signatures)
+
+Changes since the last public release (1.6.19):
+ Avoid potential pointer overflow/underflow in png_handle_sPLT() and
+ png_handle_pCAL() (Bug report by John Regehr).
+ Fixed incorrect implementation of png_set_PLTE() that uses png_ptr
+ not info_ptr, that left png_set_PLTE() open to the CVE-2015-8126
+ vulnerability.
+ Backported tests from libpng-1.7.0beta69.
+ Fixed an error in handling of bad zlib CMINFO field in pngfix, found by
+ American Fuzzy Lop, reported by Brian Carpenter. inflate() doesn't
+ immediately fault a bad CMINFO field; instead a 'too far back' error
+ happens later (at least some times). pngfix failed to limit CMINFO to
+ the allowed values but then assumed that window_bits was in range,
+ triggering an assert. The bug is mostly harmless; the PNG file cannot
+ be fixed.
+ In libpng 1.6 zlib initialization was changed to use the window size
+ in the zlib stream, not a fixed value. This causes some invalid images,
+ where CINFO is too large, to display 'correctly' if the rest of the
+ data is valid. This provides a workaround for zlib versions where the
+ error arises (ones that support the API change to use the window size
+ in the stream).
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit
diff --git a/src/3rdparty/libpng/CHANGES b/src/3rdparty/libpng/CHANGES
index 2e4d2bb292..28094fd26c 100644
--- a/src/3rdparty/libpng/CHANGES
+++ b/src/3rdparty/libpng/CHANGES
@@ -5409,11 +5409,43 @@ Version 1.6.19rc03 [November 3, 2015]
Version 1.6.19rc04 [November 5, 2015]
Fixed new bug with CRC error after reading an over-length palette
- (bug report by Cosmin Truta).
+ (bug report by Cosmin Truta) (CVE-2015-8126).
Version 1.6.19 [November 12, 2015]
Cleaned up coding style in png_handle_PLTE().
+Version 1.6.20beta01 [November 20, 2015]
+ Avoid potential pointer overflow/underflow in png_handle_sPLT() and
+ png_handle_pCAL() (Bug report by John Regehr).
+
+Version 1.6.20beta02 [November 23, 2015]
+ Fixed incorrect implementation of png_set_PLTE() that uses png_ptr
+ not info_ptr, that left png_set_PLTE() open to the CVE-2015-8126
+ vulnerability.
+
+Version 1.6.20beta03 [November 24, 2015]
+ Backported tests from libpng-1.7.0beta69.
+
+Version 1.6.20rc01 [November 26, 2015]
+ Fixed an error in handling of bad zlib CMINFO field in pngfix, found by
+ American Fuzzy Lop, reported by Brian Carpenter. inflate() doesn't
+ immediately fault a bad CMINFO field; instead a 'too far back' error
+ happens later (at least some times). pngfix failed to limit CMINFO to
+ the allowed values but then assumed that window_bits was in range,
+ triggering an assert. The bug is mostly harmless; the PNG file cannot
+ be fixed.
+
+Version 1.6.20rc02 [November 29, 2015]
+ In libpng 1.6 zlib initialization was changed to use the window size
+ in the zlib stream, not a fixed value. This causes some invalid images,
+ where CINFO is too large, to display 'correctly' if the rest of the
+ data is valid. This provides a workaround for zlib versions where the
+ error arises (ones that support the API change to use the window size
+ in the stream).
+
+Version 1.6.20 [December 3, 2015]
+ No changes.
+
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit
https://lists.sourceforge.net/lists/listinfo/png-mng-implement
diff --git a/src/3rdparty/libpng/LICENSE b/src/3rdparty/libpng/LICENSE
index 11f6ffe5db..82dbe117f6 100644
--- a/src/3rdparty/libpng/LICENSE
+++ b/src/3rdparty/libpng/LICENSE
@@ -10,7 +10,7 @@ this sentence.
This code is released under the libpng license.
-libpng versions 1.0.7, July 1, 2000, through 1.6.19, November 12, 2015, are
+libpng versions 1.0.7, July 1, 2000, through 1.6.20, December 3, 2015, are
Copyright (c) 2000-2002, 2004, 2006-2015 Glenn Randers-Pehrson, are
derived from libpng-1.0.6, and are distributed according to the same
disclaimer and license as libpng-1.0.6 with the following individuals
@@ -109,4 +109,4 @@ the additional disclaimers inserted at version 1.0.7.
Glenn Randers-Pehrson
glennrp at users.sourceforge.net
-November 12, 2015
+December 3, 2015
diff --git a/src/3rdparty/libpng/README b/src/3rdparty/libpng/README
index 17484e0fd7..59f1f918ae 100644
--- a/src/3rdparty/libpng/README
+++ b/src/3rdparty/libpng/README
@@ -1,4 +1,4 @@
-README for libpng version 1.6.19 - November 12, 2015 (shared library 16.0)
+README for libpng version 1.6.20 - December 3, 2015 (shared library 16.0)
See the note about version numbers near the top of png.h
See INSTALL for instructions on how to install libpng.
diff --git a/src/3rdparty/libpng/libpng-manual.txt b/src/3rdparty/libpng/libpng-manual.txt
index bc7a441cf2..87eeb2b583 100644
--- a/src/3rdparty/libpng/libpng-manual.txt
+++ b/src/3rdparty/libpng/libpng-manual.txt
@@ -1,6 +1,6 @@
libpng-manual.txt - A description on how to use and modify libpng
- libpng version 1.6.19 - November 12, 2015
+ libpng version 1.6.20 - December 3, 2015
Updated and distributed by Glenn Randers-Pehrson
<glennrp at users.sourceforge.net>
Copyright (c) 1998-2015 Glenn Randers-Pehrson
@@ -11,7 +11,7 @@ libpng-manual.txt - A description on how to use and modify libpng
Based on:
- libpng versions 0.97, January 1998, through 1.6.19 - November 12, 2015
+ libpng versions 0.97, January 1998, through 1.6.20 - December 3, 2015
Updated and distributed by Glenn Randers-Pehrson
Copyright (c) 1998-2015 Glenn Randers-Pehrson
@@ -2960,6 +2960,7 @@ width, height, bit_depth, and color_type must be the same in each call.
(array of png_color)
num_palette - number of entries in the palette
+
png_set_gAMA(png_ptr, info_ptr, file_gamma);
png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma);
@@ -4897,7 +4898,7 @@ a set of "safe" limits is applied in pngpriv.h. These can be overridden by
application calls to png_set_user_limits(), png_set_user_chunk_cache_max(),
and/or png_set_user_malloc_max() that increase or decrease the limits. Also,
in libpng-1.5.10 the default width and height limits were increased
-from 1,000,000 to 0x7ffffff (i.e., made unlimited). Therefore, the
+from 1,000,000 to 0x7fffffff (i.e., made unlimited). Therefore, the
limits are now
default safe
png_user_width_max 0x7fffffff 1,000,000
@@ -5323,7 +5324,7 @@ Since the PNG Development group is an ad-hoc body, we can't make
an official declaration.
This is your unofficial assurance that libpng from version 0.71 and
-upward through 1.6.19 are Y2K compliant. It is my belief that earlier
+upward through 1.6.20 are Y2K compliant. It is my belief that earlier
versions were also Y2K compliant.
Libpng only has two year fields. One is a 2-byte unsigned integer
diff --git a/src/3rdparty/libpng/png.c b/src/3rdparty/libpng/png.c
index 6fcfad72ec..c183e3f8fa 100644
--- a/src/3rdparty/libpng/png.c
+++ b/src/3rdparty/libpng/png.c
@@ -14,7 +14,7 @@
#include "pngpriv.h"
/* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_6_19 Your_png_h_is_not_version_1_6_19;
+typedef png_libpng_version_1_6_20 Your_png_h_is_not_version_1_6_20;
/* Tells libpng that we have already handled the first "num_bytes" bytes
* of the PNG file signature. If the PNG data is embedded into another
@@ -775,13 +775,13 @@ png_get_copyright(png_const_structrp png_ptr)
#else
# ifdef __STDC__
return PNG_STRING_NEWLINE \
- "libpng version 1.6.19 - November 12, 2015" PNG_STRING_NEWLINE \
+ "libpng version 1.6.20 - December 3, 2015" PNG_STRING_NEWLINE \
"Copyright (c) 1998-2015 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
"Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
"Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
PNG_STRING_NEWLINE;
# else
- return "libpng version 1.6.19 - November 12, 2015\
+ return "libpng version 1.6.20 - December 3, 2015\
Copyright (c) 1998-2015 Glenn Randers-Pehrson\
Copyright (c) 1996-1997 Andreas Dilger\
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
@@ -2343,7 +2343,7 @@ png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr,
* Fall through to "no match".
*/
png_chunk_report(png_ptr,
- "Not recognizing known sRGB profile that has been edited",
+ "Not recognizing known sRGB profile that has been edited",
PNG_CHUNK_WARNING);
break;
# endif
diff --git a/src/3rdparty/libpng/png.h b/src/3rdparty/libpng/png.h
index c83051b1ca..4d03dfc136 100644
--- a/src/3rdparty/libpng/png.h
+++ b/src/3rdparty/libpng/png.h
@@ -1,7 +1,7 @@
/* png.h - header file for PNG reference library
*
- * libpng version 1.6.19, November 12, 2015
+ * libpng version 1.6.20, December 3, 2015
*
* Copyright (c) 1998-2015 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
@@ -12,7 +12,8 @@
* Authors and maintainers:
* libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
* libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger
- * libpng versions 0.97, January 1998, through 1.6.19, November 12, 2015: Glenn
+ * libpng versions 0.97, January 1998, through 1.6.20, December 3, 2015:
+ * Glenn Randers-Pehrson.
* See also "Contributing Authors", below.
*/
@@ -24,7 +25,7 @@
*
* This code is released under the libpng license.
*
- * libpng versions 1.0.7, July 1, 2000, through 1.6.19, November 12, 2015, are
+ * libpng versions 1.0.7, July 1, 2000, through 1.6.20, December 3, 2015, are
* Copyright (c) 2000-2002, 2004, 2006-2015 Glenn Randers-Pehrson, are
* derived from libpng-1.0.6, and are distributed according to the same
* disclaimer and license as libpng-1.0.6 with the following individuals
@@ -185,7 +186,7 @@
* ...
* 1.5.23 15 10523 15.so.15.23[.0]
* ...
- * 1.6.19 16 10619 16.so.16.19[.0]
+ * 1.6.20 16 10620 16.so.16.20[.0]
*
* Henceforth the source version will match the shared-library major
* and minor numbers; the shared-library major version number will be
@@ -213,13 +214,13 @@
* Y2K compliance in libpng:
* =========================
*
- * November 12, 2015
+ * December 3, 2015
*
* Since the PNG Development group is an ad-hoc body, we can't make
* an official declaration.
*
* This is your unofficial assurance that libpng from version 0.71 and
- * upward through 1.6.19 are Y2K compliant. It is my belief that
+ * upward through 1.6.20 are Y2K compliant. It is my belief that
* earlier versions were also Y2K compliant.
*
* Libpng only has two year fields. One is a 2-byte unsigned integer
@@ -281,9 +282,9 @@
*/
/* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.6.19"
+#define PNG_LIBPNG_VER_STRING "1.6.20"
#define PNG_HEADER_VERSION_STRING \
- " libpng version 1.6.19 - November 12, 2015\n"
+ " libpng version 1.6.20 - December 3, 2015\n"
#define PNG_LIBPNG_VER_SONUM 16
#define PNG_LIBPNG_VER_DLLNUM 16
@@ -291,7 +292,7 @@
/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
#define PNG_LIBPNG_VER_MAJOR 1
#define PNG_LIBPNG_VER_MINOR 6
-#define PNG_LIBPNG_VER_RELEASE 19
+#define PNG_LIBPNG_VER_RELEASE 20
/* This should match the numeric part of the final component of
* PNG_LIBPNG_VER_STRING, omitting any leading zero:
@@ -322,7 +323,7 @@
* version 1.0.0 was mis-numbered 100 instead of 10000). From
* version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release
*/
-#define PNG_LIBPNG_VER 10619 /* 1.6.19 */
+#define PNG_LIBPNG_VER 10620 /* 1.6.20 */
/* Library configuration: these options cannot be changed after
* the library has been built.
@@ -432,7 +433,7 @@ extern "C" {
/* This triggers a compiler error in png.c, if png.c and png.h
* do not agree upon the version number.
*/
-typedef char* png_libpng_version_1_6_19;
+typedef char* png_libpng_version_1_6_20;
/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info.
*
diff --git a/src/3rdparty/libpng/pngconf.h b/src/3rdparty/libpng/pngconf.h
index f1b795b478..92f250000c 100644
--- a/src/3rdparty/libpng/pngconf.h
+++ b/src/3rdparty/libpng/pngconf.h
@@ -1,7 +1,7 @@
/* pngconf.h - machine configurable file for libpng
*
- * libpng version 1.6.19, July 23, 2015
+ * libpng version 1.6.20, December 3, 2015
*
* Copyright (c) 1998-2015 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
diff --git a/src/3rdparty/libpng/pngerror.c b/src/3rdparty/libpng/pngerror.c
index 0781866a89..bdb959ee51 100644
--- a/src/3rdparty/libpng/pngerror.c
+++ b/src/3rdparty/libpng/pngerror.c
@@ -768,7 +768,7 @@ png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN)
/* If control reaches this point, png_longjmp() must not return. The only
* choice is to terminate the whole process (or maybe the thread); to do
- * this the ANSI-C abort() function is used unless a different method is
+ * this the ANSI-C abort() function is used unless a different method is
* implemented by overriding the default configuration setting for
* PNG_ABORT().
*/
diff --git a/src/3rdparty/libpng/pnginfo.h b/src/3rdparty/libpng/pnginfo.h
index c8c874dd1e..4bd264b869 100644
--- a/src/3rdparty/libpng/pnginfo.h
+++ b/src/3rdparty/libpng/pnginfo.h
@@ -223,7 +223,7 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
/* Storage for unknown chunks that the library doesn't recognize. */
png_unknown_chunkp unknown_chunks;
- /* The type of this field is limited by the type of
+ /* The type of this field is limited by the type of
* png_struct::user_chunk_cache_max, else overflow can occur.
*/
int unknown_chunks_num;
diff --git a/src/3rdparty/libpng/pnglibconf.h b/src/3rdparty/libpng/pnglibconf.h
index 8b6da9eb2c..0dba5055f7 100644
--- a/src/3rdparty/libpng/pnglibconf.h
+++ b/src/3rdparty/libpng/pnglibconf.h
@@ -1,6 +1,6 @@
/* pnglibconf.h - library build configuration */
-/* libpng version 1.6.19, July 23, 2015 */
+/* libpng version 1.6.20 - December 3, 2015 */
/* Copyright (c) 1998-2014 Glenn Randers-Pehrson */
diff --git a/src/3rdparty/libpng/pngpread.c b/src/3rdparty/libpng/pngpread.c
index 9f68f99023..89ffc4018f 100644
--- a/src/3rdparty/libpng/pngpread.c
+++ b/src/3rdparty/libpng/pngpread.c
@@ -133,7 +133,7 @@ png_process_some_data(png_structrp png_ptr, png_inforp info_ptr)
void /* PRIVATE */
png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr)
{
- png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */
+ png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */
num_to_check = 8 - num_checked;
if (png_ptr->buffer_size < num_to_check)
@@ -662,7 +662,7 @@ png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
* change the current behavior (see comments in inflate.c
* for why this doesn't happen at present with zlib 1.2.5).
*/
- ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
+ ret = PNG_INFLATE(png_ptr, Z_SYNC_FLUSH);
/* Check for any failure before proceeding. */
if (ret != Z_OK && ret != Z_STREAM_END)
diff --git a/src/3rdparty/libpng/pngpriv.h b/src/3rdparty/libpng/pngpriv.h
index f7a45477a4..c06deee68d 100644
--- a/src/3rdparty/libpng/pngpriv.h
+++ b/src/3rdparty/libpng/pngpriv.h
@@ -1229,6 +1229,14 @@ PNG_INTERNAL_FUNCTION(void,png_read_finish_row,(png_structrp png_ptr),
/* Initialize the row buffers, etc. */
PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY);
+#if PNG_ZLIB_VERNUM >= 0x1240
+PNG_INTERNAL_FUNCTION(int,png_zlib_inflate,(png_structrp png_ptr, int flush),
+ PNG_EMPTY);
+# define PNG_INFLATE(pp, flush) png_zlib_inflate(pp, flush)
+#else /* Zlib < 1.2.4 */
+# define PNG_INFLATE(pp, flush) inflate(&(pp)->zstream, flush)
+#endif /* Zlib < 1.2.4 */
+
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
/* Optional call to update the users info structure */
PNG_INTERNAL_FUNCTION(void,png_read_transform_info,(png_structrp png_ptr,
diff --git a/src/3rdparty/libpng/pngread.c b/src/3rdparty/libpng/pngread.c
index 48aae84881..9cb4d2e41d 100644
--- a/src/3rdparty/libpng/pngread.c
+++ b/src/3rdparty/libpng/pngread.c
@@ -2838,7 +2838,6 @@ png_image_read_colormap(png_voidp argument)
default:
png_error(png_ptr, "invalid PNG color type");
/*NOT REACHED*/
- break;
}
/* Now deal with the output processing */
diff --git a/src/3rdparty/libpng/pngrutil.c b/src/3rdparty/libpng/pngrutil.c
index ee584a8c40..6189251352 100644
--- a/src/3rdparty/libpng/pngrutil.c
+++ b/src/3rdparty/libpng/pngrutil.c
@@ -1,7 +1,7 @@
/* pngrutil.c - utilities to read a PNG file
*
- * Last changed in libpng 1.6.19 [November 12, 2015]
+ * Last changed in libpng 1.6.20 [December 3, 2015]
* Copyright (c) 1998-2015 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@@ -377,10 +377,16 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) ==
PNG_OPTION_ON)
+ {
window_bits = 15;
+ png_ptr->zstream_start = 0; /* fixed window size */
+ }
else
+ {
window_bits = 0;
+ png_ptr->zstream_start = 1;
+ }
# else
# define window_bits 0
# endif
@@ -429,6 +435,31 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
#endif
}
+#if PNG_ZLIB_VERNUM >= 0x1240
+/* Handle the start of the inflate stream if we called inflateInit2(strm,0);
+ * in this case some zlib versions skip validation of the CINFO field and, in
+ * certain circumstances, libpng may end up displaying an invalid image, in
+ * contrast to implementations that call zlib in the normal way (e.g. libpng
+ * 1.5).
+ */
+int /* PRIVATE */
+png_zlib_inflate(png_structrp png_ptr, int flush)
+{
+ if (png_ptr->zstream_start && png_ptr->zstream.avail_in > 0)
+ {
+ if ((*png_ptr->zstream.next_in >> 4) > 7)
+ {
+ png_ptr->zstream.msg = "invalid window size (libpng)";
+ return Z_DATA_ERROR;
+ }
+
+ png_ptr->zstream_start = 0;
+ }
+
+ return inflate(&png_ptr->zstream, flush);
+}
+#endif /* Zlib >= 1.2.4 */
+
#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED
/* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to
* allow the caller to do multiple calls if required. If the 'finish' flag is
@@ -522,7 +553,7 @@ png_inflate(png_structrp png_ptr, png_uint_32 owner, int finish,
* the previous chunk of input data. Tell zlib if we have reached the
* end of the output buffer.
*/
- ret = inflate(&png_ptr->zstream, avail_out > 0 ? Z_NO_FLUSH :
+ ret = PNG_INFLATE(png_ptr, avail_out > 0 ? Z_NO_FLUSH :
(finish ? Z_FINISH : Z_SYNC_FLUSH));
} while (ret == Z_OK);
@@ -771,7 +802,7 @@ png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size,
* the available output is produced; this allows reading of truncated
* streams.
*/
- ret = inflate(&png_ptr->zstream,
+ ret = PNG_INFLATE(png_ptr,
*chunk_bytes > 0 ? Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH));
}
while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0));
@@ -1670,7 +1701,7 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
++entry_start;
/* A sample depth should follow the separator, and we should be on it */
- if (entry_start > buffer + length - 2)
+ if (length < 2U || entry_start > buffer + (length - 2U))
{
png_warning(png_ptr, "malformed sPLT chunk");
return;
@@ -2174,7 +2205,7 @@ png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
/* We need to have at least 12 bytes after the purpose string
* in order to get the parameter information.
*/
- if (endptr <= buf + 12)
+ if (endptr - buf <= 12)
{
png_chunk_benign_error(png_ptr, "invalid");
return;
@@ -4039,7 +4070,7 @@ png_read_IDAT_data(png_structrp png_ptr, png_bytep output,
*
* TODO: deal more elegantly with truncated IDAT lists.
*/
- ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
+ ret = PNG_INFLATE(png_ptr, Z_NO_FLUSH);
/* Take the unconsumed output back. */
if (output != NULL)
diff --git a/src/3rdparty/libpng/pngset.c b/src/3rdparty/libpng/pngset.c
index 05a2134dbb..8fd7965fca 100644
--- a/src/3rdparty/libpng/pngset.c
+++ b/src/3rdparty/libpng/pngset.c
@@ -520,8 +520,8 @@ png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr,
if (png_ptr == NULL || info_ptr == NULL)
return;
- max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
- (1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
+ max_palette_length = (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
+ (1 << info_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
if (num_palette < 0 || num_palette > (int) max_palette_length)
{
@@ -1573,7 +1573,7 @@ png_set_user_limits (png_structrp png_ptr, png_uint_32 user_width_max,
{
/* Images with dimensions larger than these limits will be
* rejected by png_set_IHDR(). To accept any PNG datastream
- * regardless of dimensions, set both limits to 0x7ffffff.
+ * regardless of dimensions, set both limits to 0x7fffffff.
*/
if (png_ptr == NULL)
return;
diff --git a/src/3rdparty/libpng/pngstruct.h b/src/3rdparty/libpng/pngstruct.h
index c8c0e46e8b..d0bcc7914a 100644
--- a/src/3rdparty/libpng/pngstruct.h
+++ b/src/3rdparty/libpng/pngstruct.h
@@ -263,6 +263,9 @@ struct png_struct_def
/* pixel depth used for the row buffers */
png_byte transformed_pixel_depth;
/* pixel depth after read/write transforms */
+#if PNG_ZLIB_VERNUM >= 0x1240
+ png_byte zstream_start; /* at start of an input zlib stream */
+#endif /* Zlib >= 1.2.4 */
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
png_uint_16 filler; /* filler bytes for pixel expansion */
#endif
diff --git a/src/3rdparty/libpng/pngwutil.c b/src/3rdparty/libpng/pngwutil.c
index adc4729c24..0ee102b5fb 100644
--- a/src/3rdparty/libpng/pngwutil.c
+++ b/src/3rdparty/libpng/pngwutil.c
@@ -2563,7 +2563,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
if (filter_to_do == PNG_FILTER_SUB)
/* It's the only filter so no testing is needed */
{
- (void) png_setup_sub_row(png_ptr, bpp, row_bytes, mins);
+ (void) png_setup_sub_row(png_ptr, bpp, row_bytes, mins);
best_row = png_ptr->try_row;
}
@@ -2572,7 +2572,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
png_size_t sum;
png_size_t lmins = mins;
- sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins);
+ sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins);
if (sum < mins)
{
@@ -2598,7 +2598,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
png_size_t sum;
png_size_t lmins = mins;
- sum = png_setup_up_row(png_ptr, row_bytes, lmins);
+ sum = png_setup_up_row(png_ptr, row_bytes, lmins);
if (sum < mins)
{
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 46cfe9e2b9..86aa9b9e7a 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -98,6 +98,11 @@ extern char *__progname;
#if defined(Q_OS_LINUX) && (defined(__GLIBC__) || QT_HAS_INCLUDE(<sys/syscall.h>))
# include <sys/syscall.h>
+
+# if defined(Q_OS_ANDROID) && !defined(SYS_gettid)
+# define SYS_gettid __NR_gettid
+# endif
+
static long qt_gettid()
{
// no error handling
diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h
index 1200c3b5a5..e709050011 100644
--- a/src/corelib/global/qtypeinfo.h
+++ b/src/corelib/global/qtypeinfo.h
@@ -118,14 +118,14 @@ public:
*/
// apply defaults for a generic QTypeInfo<T> that didn't provide the new values
template <typename T, typename = void>
-struct QTypeInfoQuery : QTypeInfo<T>
+struct QTypeInfoQuery : public QTypeInfo<T>
{
enum { isRelocatable = !QTypeInfo<T>::isStatic };
};
// if QTypeInfo<T>::isRelocatable exists, use it
template <typename T>
-struct QTypeInfoQuery<T, typename QtPrivate::QEnableIf<QTypeInfo<T>::isRelocatable || true>::Type> : QTypeInfo<T>
+struct QTypeInfoQuery<T, typename QtPrivate::QEnableIf<QTypeInfo<T>::isRelocatable || true>::Type> : public QTypeInfo<T>
{};
/*!
diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp
index ef787832a4..5d8b567c8c 100644
--- a/src/corelib/io/qprocess_win.cpp
+++ b/src/corelib/io/qprocess_win.cpp
@@ -684,10 +684,7 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
QIncrementalSleepTimer timer(msecs);
forever {
- // Check if we have any data pending: the pipe writer has
- // bytes waiting to written, or it has written data since the
- // last time we called stdinChannel.writer->waitForWrite().
- bool pendingDataInPipe = stdinChannel.writer && (stdinChannel.writer->bytesToWrite() || stdinChannel.writer->hadWritten());
+ bool pendingDataInPipe = stdinChannel.writer && stdinChannel.writer->bytesToWrite();
// If we don't have pending data, and our write buffer is
// empty, we fail.
@@ -815,7 +812,6 @@ qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen)
stdinChannel.writer = new QWindowsPipeWriter(stdinChannel.pipe[1], q);
QObjectPrivate::connect(stdinChannel.writer, &QWindowsPipeWriter::canWrite,
this, &QProcessPrivate::_q_canWrite);
- stdinChannel.writer->start();
}
return stdinChannel.writer->write(data, maxlen);
diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp
index 9e3cb9ab4d..9bd5a9e3b6 100644
--- a/src/corelib/io/qstandardpaths_win.cpp
+++ b/src/corelib/io/qstandardpaths_win.cpp
@@ -117,6 +117,7 @@ static inline void appendTestMode(QString &path)
// Map QStandardPaths::StandardLocation to CLSID of SHGetSpecialFolderPath()
static int writableSpecialFolderClsid(QStandardPaths::StandardLocation type)
{
+#ifndef Q_OS_WINCE
static const int clsids[] = {
CSIDL_DESKTOPDIRECTORY, // DesktopLocation
CSIDL_PERSONAL, // DocumentsLocation
@@ -136,6 +137,27 @@ static int writableSpecialFolderClsid(QStandardPaths::StandardLocation type)
CSIDL_APPDATA, // AppDataLocation ("Roaming" path)
CSIDL_LOCAL_APPDATA, // AppConfigLocation ("Local" path)
};
+#else // !Q_OS_WINCE
+ static const int clsids[] = {
+ CSIDL_DESKTOPDIRECTORY, // DesktopLocation
+ CSIDL_PERSONAL, // DocumentsLocation
+ CSIDL_FONTS, // FontsLocation
+ CSIDL_PROGRAMS, // ApplicationsLocation
+ CSIDL_MYMUSIC, // MusicLocation
+ CSIDL_MYVIDEO, // MoviesLocation
+ CSIDL_MYPICTURES, // PicturesLocation
+ -1, -1, // TempLocation/HomeLocation
+ CSIDL_APPDATA, // AppLocalDataLocation, AppLocalDataLocation = DataLocation
+ -1, // CacheLocation
+ CSIDL_APPDATA, // GenericDataLocation
+ -1, // RuntimeLocation
+ CSIDL_APPDATA, // ConfigLocation
+ -1, -1, // DownloadLocation/GenericCacheLocation
+ CSIDL_APPDATA, // GenericConfigLocation
+ CSIDL_APPDATA, // AppDataLocation
+ CSIDL_APPDATA, // AppConfigLocation
+ };
+#endif // Q_OS_WINCE
Q_STATIC_ASSERT(sizeof(clsids) / sizeof(clsids[0]) == size_t(QStandardPaths::AppConfigLocation + 1));
return size_t(type) < sizeof(clsids) / sizeof(clsids[0]) ? clsids[type] : -1;
diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp
index 95232385b2..15fb276be9 100644
--- a/src/corelib/io/qwindowspipereader.cpp
+++ b/src/corelib/io/qwindowspipereader.cpp
@@ -38,28 +38,40 @@
****************************************************************************/
#include "qwindowspipereader_p.h"
-#include "qwinoverlappedionotifier_p.h"
-#include <qdebug.h>
+#include "qiodevice_p.h"
#include <qelapsedtimer.h>
-#include <qeventloop.h>
QT_BEGIN_NAMESPACE
+QWindowsPipeReader::Overlapped::Overlapped(QWindowsPipeReader *reader)
+ : pipeReader(reader)
+{
+}
+
+void QWindowsPipeReader::Overlapped::clear()
+{
+ ZeroMemory(this, sizeof(OVERLAPPED));
+}
+
+
QWindowsPipeReader::QWindowsPipeReader(QObject *parent)
: QObject(parent),
handle(INVALID_HANDLE_VALUE),
+ overlapped(this),
readBufferMaxSize(0),
actualReadBufferSize(0),
stopped(true),
readSequenceStarted(false),
+ notifiedCalled(false),
pipeBroken(false),
- readyReadEmitted(false)
+ readyReadPending(false),
+ inReadyRead(false)
{
- dataReadNotifier = new QWinOverlappedIoNotifier(this);
- connect(dataReadNotifier, &QWinOverlappedIoNotifier::notified, this, &QWindowsPipeReader::notified);
+ connect(this, &QWindowsPipeReader::_q_queueReadyRead,
+ this, &QWindowsPipeReader::emitPendingReadyRead, Qt::QueuedConnection);
}
-static bool qt_cancelIo(HANDLE handle, OVERLAPPED *overlapped)
+bool qt_cancelIo(HANDLE handle, OVERLAPPED *overlapped)
{
typedef BOOL (WINAPI *PtrCancelIoEx)(HANDLE, LPOVERLAPPED);
static PtrCancelIoEx ptrCancelIoEx = 0;
@@ -88,12 +100,6 @@ void QWindowsPipeReader::setHandle(HANDLE hPipeReadEnd)
actualReadBufferSize = 0;
handle = hPipeReadEnd;
pipeBroken = false;
- readyReadEmitted = false;
- stopped = false;
- if (hPipeReadEnd != INVALID_HANDLE_VALUE) {
- dataReadNotifier->setHandle(hPipeReadEnd);
- dataReadNotifier->setEnabled(true);
- }
}
/*!
@@ -104,19 +110,15 @@ void QWindowsPipeReader::stop()
{
stopped = true;
if (readSequenceStarted) {
- if (qt_cancelIo(handle, &overlapped)) {
- dataReadNotifier->waitForNotified(-1, &overlapped);
- } else {
+ if (!qt_cancelIo(handle, &overlapped)) {
const DWORD dwError = GetLastError();
if (dwError != ERROR_NOT_FOUND) {
qErrnoWarning(dwError, "QWindowsPipeReader: qt_cancelIo on handle %x failed.",
handle);
}
}
+ waitForNotification(-1);
}
- readSequenceStarted = false;
- dataReadNotifier->setEnabled(false);
- handle = INVALID_HANDLE_VALUE;
}
/*!
@@ -174,11 +176,10 @@ bool QWindowsPipeReader::canReadLine() const
\internal
Will be called whenever the read operation completes.
*/
-void QWindowsPipeReader::notified(quint32 numberOfBytesRead, quint32 errorCode,
- OVERLAPPED *notifiedOverlapped)
+void QWindowsPipeReader::notified(DWORD errorCode, DWORD numberOfBytesRead)
{
- if (&overlapped != notifiedOverlapped)
- return;
+ notifiedCalled = true;
+ readSequenceStarted = false;
switch (errorCode) {
case ERROR_SUCCESS:
@@ -202,8 +203,6 @@ void QWindowsPipeReader::notified(quint32 numberOfBytesRead, quint32 errorCode,
break;
}
- readSequenceStarted = false;
-
// After the reader was stopped, the only reason why this function can be called is the
// completion of a cancellation. No signals should be emitted, and no new read sequence should
// be started in this case.
@@ -218,13 +217,15 @@ void QWindowsPipeReader::notified(quint32 numberOfBytesRead, quint32 errorCode,
actualReadBufferSize += numberOfBytesRead;
readBuffer.truncate(actualReadBufferSize);
startAsyncRead();
- readyReadEmitted = true;
- emit readyRead();
+ if (!readyReadPending) {
+ readyReadPending = true;
+ emit _q_queueReadyRead(QWindowsPipeReader::QPrivateSignal());
+ }
}
/*!
\internal
- Reads data from the socket into the readbuffer
+ Reads data from the pipe into the readbuffer.
*/
void QWindowsPipeReader::startAsyncRead()
{
@@ -244,43 +245,41 @@ void QWindowsPipeReader::startAsyncRead()
char *ptr = readBuffer.reserve(bytesToRead);
+ stopped = false;
readSequenceStarted = true;
- ZeroMemory(&overlapped, sizeof(overlapped));
- if (ReadFile(handle, ptr, bytesToRead, NULL, &overlapped)) {
- // We get notified by the QWinOverlappedIoNotifier - even in the synchronous case.
- return;
- } else {
+ overlapped.clear();
+ if (!ReadFileEx(handle, ptr, bytesToRead, &overlapped, &readFileCompleted)) {
+ readSequenceStarted = false;
+
const DWORD dwError = GetLastError();
switch (dwError) {
- case ERROR_IO_PENDING:
- // This is not an error. We're getting notified, when data arrives.
- return;
- case ERROR_MORE_DATA:
- // This is not an error. The synchronous read succeeded.
- // We're connected to a message mode pipe and the message
- // didn't fit into the pipe's system buffer.
- // We're getting notified by the QWinOverlappedIoNotifier.
- break;
case ERROR_BROKEN_PIPE:
case ERROR_PIPE_NOT_CONNECTED:
- {
- // It may happen, that the other side closes the connection directly
- // after writing data. Then we must set the appropriate socket state.
- readSequenceStarted = false;
- pipeBroken = true;
- emit pipeClosed();
- return;
- }
+ // It may happen, that the other side closes the connection directly
+ // after writing data. Then we must set the appropriate socket state.
+ pipeBroken = true;
+ emit pipeClosed();
+ break;
default:
- readSequenceStarted = false;
emit winError(dwError, QLatin1String("QWindowsPipeReader::startAsyncRead"));
- return;
+ break;
}
}
}
/*!
\internal
+ Called when ReadFileEx finished the read operation.
+ */
+void QWindowsPipeReader::readFileCompleted(DWORD errorCode, DWORD numberOfBytesTransfered,
+ OVERLAPPED *overlappedBase)
+{
+ Overlapped *overlapped = static_cast<Overlapped *>(overlappedBase);
+ overlapped->pipeReader->notified(errorCode, numberOfBytesTransfered);
+}
+
+/*!
+ \internal
Returns the number of available bytes in the pipe.
Sets QWindowsPipeReader::pipeBroken to true if the connection is broken.
*/
@@ -298,17 +297,60 @@ DWORD QWindowsPipeReader::checkPipeState()
return 0;
}
+bool QWindowsPipeReader::waitForNotification(int timeout)
+{
+ QElapsedTimer t;
+ t.start();
+ notifiedCalled = false;
+ int msecs = timeout;
+ while (SleepEx(msecs == -1 ? INFINITE : msecs, TRUE) == WAIT_IO_COMPLETION) {
+ if (notifiedCalled)
+ return true;
+
+ // Some other I/O completion routine was called. Wait some more.
+ msecs = qt_subtract_from_timeout(timeout, t.elapsed());
+ if (!msecs)
+ break;
+ }
+ return notifiedCalled;
+}
+
+void QWindowsPipeReader::emitPendingReadyRead()
+{
+ if (readyReadPending) {
+ readyReadPending = false;
+ inReadyRead = true;
+ emit readyRead();
+ inReadyRead = false;
+ }
+}
+
/*!
Waits for the completion of the asynchronous read operation.
- Returns \c true, if we've emitted the readyRead signal.
+ Returns \c true, if we've emitted the readyRead signal (non-recursive case)
+ or readyRead will be emitted by the event loop (recursive case).
*/
bool QWindowsPipeReader::waitForReadyRead(int msecs)
{
if (!readSequenceStarted)
return false;
- readyReadEmitted = false;
- dataReadNotifier->waitForNotified(msecs, &overlapped);
- return readyReadEmitted;
+
+ if (readyReadPending) {
+ if (!inReadyRead)
+ emitPendingReadyRead();
+ return true;
+ }
+
+ if (!waitForNotification(msecs))
+ return false;
+
+ if (readyReadPending) {
+ if (!inReadyRead)
+ emitPendingReadyRead();
+ return true;
+ }
+
+ return false;
}
/*!
diff --git a/src/corelib/io/qwindowspipereader_p.h b/src/corelib/io/qwindowspipereader_p.h
index d389d0cc9f..74ff5250ac 100644
--- a/src/corelib/io/qwindowspipereader_p.h
+++ b/src/corelib/io/qwindowspipereader_p.h
@@ -51,7 +51,6 @@
// We mean it.
//
-#include <qbytearray.h>
#include <qobject.h>
#include <private/qringbuffer_p.h>
@@ -59,9 +58,6 @@
QT_BEGIN_NAMESPACE
-
-class QWinOverlappedIoNotifier;
-
class Q_CORE_EXPORT QWindowsPipeReader : public QObject
{
Q_OBJECT
@@ -70,6 +66,7 @@ public:
~QWindowsPipeReader();
void setHandle(HANDLE hPipeReadEnd);
+ void startAsyncRead();
void stop();
void setMaxReadBufferSize(qint64 size) { readBufferMaxSize = size; }
@@ -82,31 +79,42 @@ public:
bool waitForReadyRead(int msecs);
bool waitForPipeClosed(int msecs);
- void startAsyncRead();
bool isReadOperationActive() const { return readSequenceStarted; }
Q_SIGNALS:
void winError(ulong, const QString &);
void readyRead();
void pipeClosed();
-
-private Q_SLOTS:
- void notified(quint32 numberOfBytesRead, quint32 errorCode, OVERLAPPED *notifiedOverlapped);
+ void _q_queueReadyRead(QPrivateSignal);
private:
+ static void CALLBACK readFileCompleted(DWORD errorCode, DWORD numberOfBytesTransfered,
+ OVERLAPPED *overlappedBase);
+ void notified(DWORD errorCode, DWORD numberOfBytesRead);
DWORD checkPipeState();
+ bool waitForNotification(int timeout);
+ void emitPendingReadyRead();
+
+ class Overlapped : public OVERLAPPED
+ {
+ Q_DISABLE_COPY(Overlapped)
+ public:
+ explicit Overlapped(QWindowsPipeReader *reader);
+ void clear();
+ QWindowsPipeReader *pipeReader;
+ };
-private:
HANDLE handle;
- OVERLAPPED overlapped;
- QWinOverlappedIoNotifier *dataReadNotifier;
+ Overlapped overlapped;
qint64 readBufferMaxSize;
QRingBuffer readBuffer;
qint64 actualReadBufferSize;
bool stopped;
bool readSequenceStarted;
+ bool notifiedCalled;
bool pipeBroken;
- bool readyReadEmitted;
+ bool readyReadPending;
+ bool inReadyRead;
};
QT_END_NAMESPACE
diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp
index c7144d2c6b..79e7d13eb5 100644
--- a/src/corelib/io/qwindowspipewriter.cpp
+++ b/src/corelib/io/qwindowspipewriter.cpp
@@ -38,144 +38,177 @@
****************************************************************************/
#include "qwindowspipewriter_p.h"
+#include "qiodevice_p.h"
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_THREAD
+extern bool qt_cancelIo(HANDLE handle, OVERLAPPED *overlapped); // from qwindowspipereader.cpp
-QWindowsPipeWriter::QWindowsPipeWriter(HANDLE pipe, QObject * parent)
- : QThread(parent),
- writePipe(INVALID_HANDLE_VALUE),
- quitNow(false),
- hasWritten(false)
+
+QWindowsPipeWriter::Overlapped::Overlapped(QWindowsPipeWriter *pipeWriter)
+ : pipeWriter(pipeWriter)
+{
+}
+
+void QWindowsPipeWriter::Overlapped::clear()
{
- DuplicateHandle(GetCurrentProcess(), pipe, GetCurrentProcess(),
- &writePipe, 0, FALSE, DUPLICATE_SAME_ACCESS);
+ ZeroMemory(this, sizeof(OVERLAPPED));
+}
+
+
+QWindowsPipeWriter::QWindowsPipeWriter(HANDLE pipeWriteEnd, QObject *parent)
+ : QObject(parent),
+ handle(pipeWriteEnd),
+ overlapped(this),
+ numberOfBytesToWrite(0),
+ pendingBytesWrittenValue(0),
+ stopped(true),
+ writeSequenceStarted(false),
+ notifiedCalled(false),
+ bytesWrittenPending(false),
+ inBytesWritten(false)
+{
+ connect(this, &QWindowsPipeWriter::_q_queueBytesWritten,
+ this, &QWindowsPipeWriter::emitPendingBytesWrittenValue, Qt::QueuedConnection);
}
QWindowsPipeWriter::~QWindowsPipeWriter()
{
- lock.lock();
- quitNow = true;
- waitCondition.wakeOne();
- lock.unlock();
- if (!wait(30000))
- terminate();
- CloseHandle(writePipe);
+ stop();
}
bool QWindowsPipeWriter::waitForWrite(int msecs)
{
- QMutexLocker locker(&lock);
- bool hadWritten = hasWritten;
- hasWritten = false;
- if (hadWritten)
+ if (!writeSequenceStarted)
+ return false;
+
+ if (bytesWrittenPending) {
+ if (!inBytesWritten)
+ emitPendingBytesWrittenValue();
return true;
- if (!waitCondition.wait(&lock, msecs))
+ }
+
+ if (!waitForNotification(msecs))
return false;
- hadWritten = hasWritten;
- hasWritten = false;
- return hadWritten;
+
+ if (bytesWrittenPending) {
+ if (!inBytesWritten)
+ emitPendingBytesWrittenValue();
+ return true;
+ }
+
+ return false;
}
-qint64 QWindowsPipeWriter::write(const char *ptr, qint64 maxlen)
+qint64 QWindowsPipeWriter::bytesToWrite() const
{
- if (!isRunning())
- return -1;
-
- QMutexLocker locker(&lock);
- data.append(ptr, maxlen);
- waitCondition.wakeOne();
- return maxlen;
+ return numberOfBytesToWrite;
}
-class QPipeWriterOverlapped
+void QWindowsPipeWriter::emitPendingBytesWrittenValue()
{
-public:
- QPipeWriterOverlapped()
- {
- overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (bytesWrittenPending) {
+ bytesWrittenPending = false;
+ const qint64 bytes = pendingBytesWrittenValue;
+ pendingBytesWrittenValue = 0;
+
+ inBytesWritten = true;
+ emit bytesWritten(bytes);
+ inBytesWritten = false;
+ emit canWrite();
}
+}
- ~QPipeWriterOverlapped()
- {
- CloseHandle(overlapped.hEvent);
- }
+void QWindowsPipeWriter::writeFileCompleted(DWORD errorCode, DWORD numberOfBytesTransfered,
+ OVERLAPPED *overlappedBase)
+{
+ Overlapped *overlapped = static_cast<Overlapped *>(overlappedBase);
+ overlapped->pipeWriter->notified(errorCode, numberOfBytesTransfered);
+}
- void prepare()
- {
- const HANDLE hEvent = overlapped.hEvent;
- ZeroMemory(&overlapped, sizeof overlapped);
- overlapped.hEvent = hEvent;
+/*!
+ \internal
+ Will be called whenever the write operation completes.
+ */
+void QWindowsPipeWriter::notified(DWORD errorCode, DWORD numberOfBytesWritten)
+{
+ notifiedCalled = true;
+ writeSequenceStarted = false;
+ numberOfBytesToWrite = 0;
+
+ switch (errorCode) {
+ case ERROR_SUCCESS:
+ break;
+ case ERROR_OPERATION_ABORTED:
+ if (stopped)
+ break;
+ // fall through
+ default:
+ qErrnoWarning(errorCode, "QWindowsPipeWriter: asynchronous write failed.");
+ break;
}
- OVERLAPPED *operator&()
- {
- return &overlapped;
+ // After the writer was stopped, the only reason why this function can be called is the
+ // completion of a cancellation. No signals should be emitted, and no new write sequence should
+ // be started in this case.
+ if (stopped)
+ return;
+
+ pendingBytesWrittenValue += qint64(numberOfBytesWritten);
+ if (!bytesWrittenPending) {
+ bytesWrittenPending = true;
+ emit _q_queueBytesWritten(QWindowsPipeWriter::QPrivateSignal());
}
+}
-private:
- OVERLAPPED overlapped;
-};
+bool QWindowsPipeWriter::waitForNotification(int timeout)
+{
+ QElapsedTimer t;
+ t.start();
+ notifiedCalled = false;
+ int msecs = timeout;
+ while (SleepEx(msecs == -1 ? INFINITE : msecs, TRUE) == WAIT_IO_COMPLETION) {
+ if (notifiedCalled)
+ return true;
+
+ // Some other I/O completion routine was called. Wait some more.
+ msecs = qt_subtract_from_timeout(timeout, t.elapsed());
+ if (!msecs)
+ break;
+ }
+ return notifiedCalled;
+}
-void QWindowsPipeWriter::run()
+qint64 QWindowsPipeWriter::write(const char *ptr, qint64 maxlen)
{
- QPipeWriterOverlapped overl;
- forever {
- lock.lock();
- while(data.isEmpty() && (!quitNow)) {
- waitCondition.wakeOne();
- waitCondition.wait(&lock);
- }
+ if (writeSequenceStarted)
+ return 0;
+
+ overlapped.clear();
+ numberOfBytesToWrite = maxlen;
+ stopped = false;
+ writeSequenceStarted = true;
+ if (!WriteFileEx(handle, ptr, maxlen, &overlapped, &writeFileCompleted)) {
+ writeSequenceStarted = false;
+ qErrnoWarning("QWindowsPipeWriter::write failed.");
+ }
- if (quitNow) {
- lock.unlock();
- quitNow = false;
- break;
- }
+ return maxlen;
+}
- QByteArray copy = data;
-
- lock.unlock();
-
- const char *ptrData = copy.data();
- qint64 maxlen = copy.size();
- qint64 totalWritten = 0;
- overl.prepare();
- while ((!quitNow) && totalWritten < maxlen) {
- DWORD written = 0;
- if (!WriteFile(writePipe, ptrData + totalWritten,
- maxlen - totalWritten, &written, &overl)) {
- const DWORD writeError = GetLastError();
- if (writeError == 0xE8/*NT_STATUS_INVALID_USER_BUFFER*/) {
- // give the os a rest
- msleep(100);
- continue;
- }
- if (writeError != ERROR_IO_PENDING) {
- qErrnoWarning(writeError, "QWindowsPipeWriter: async WriteFile failed.");
- return;
- }
- if (!GetOverlappedResult(writePipe, &overl, &written, TRUE)) {
- qErrnoWarning(GetLastError(), "QWindowsPipeWriter: GetOverlappedResult failed.");
- return;
- }
+void QWindowsPipeWriter::stop()
+{
+ stopped = true;
+ if (writeSequenceStarted) {
+ if (!qt_cancelIo(handle, &overlapped)) {
+ const DWORD dwError = GetLastError();
+ if (dwError != ERROR_NOT_FOUND) {
+ qErrnoWarning(dwError, "QWindowsPipeWriter: qt_cancelIo on handle %x failed.",
+ handle);
}
- totalWritten += written;
-#if defined QPIPEWRITER_DEBUG
- qDebug("QWindowsPipeWriter::run() wrote %d %d/%d bytes",
- written, int(totalWritten), int(maxlen));
-#endif
- lock.lock();
- data.remove(0, written);
- hasWritten = true;
- lock.unlock();
}
- emit bytesWritten(totalWritten);
- emit canWrite();
+ waitForNotification(-1);
}
}
-#endif //QT_NO_THREAD
-
QT_END_NAMESPACE
diff --git a/src/corelib/io/qwindowspipewriter_p.h b/src/corelib/io/qwindowspipewriter_p.h
index 49fb85ebdd..945cbd18bf 100644
--- a/src/corelib/io/qwindowspipewriter_p.h
+++ b/src/corelib/io/qwindowspipewriter_p.h
@@ -52,16 +52,11 @@
//
#include <qelapsedtimer.h>
-#include <qthread.h>
-#include <qmutex.h>
-#include <qwaitcondition.h>
+#include <qobject.h>
#include <qt_windows.h>
QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_THREAD
-
#define SLEEPMIN 10
#define SLEEPMAX 500
@@ -110,45 +105,50 @@ private:
int nextSleep;
};
-class Q_CORE_EXPORT QWindowsPipeWriter : public QThread
+class Q_CORE_EXPORT QWindowsPipeWriter : public QObject
{
Q_OBJECT
-
-Q_SIGNALS:
- void canWrite();
- void bytesWritten(qint64 bytes);
-
public:
- explicit QWindowsPipeWriter(HANDLE writePipe, QObject * parent = 0);
+ explicit QWindowsPipeWriter(HANDLE pipeWriteEnd, QObject *parent = 0);
~QWindowsPipeWriter();
- bool waitForWrite(int msecs);
qint64 write(const char *data, qint64 maxlen);
+ void stop();
+ bool waitForWrite(int msecs);
+ qint64 bytesToWrite() const;
- qint64 bytesToWrite() const
- {
- QMutexLocker locker(&lock);
- return data.size();
- }
-
- bool hadWritten() const
- {
- return hasWritten;
- }
-
-protected:
- void run();
+Q_SIGNALS:
+ void canWrite();
+ void bytesWritten(qint64 bytes);
+ void _q_queueBytesWritten(QPrivateSignal);
private:
- QByteArray data;
- QWaitCondition waitCondition;
- mutable QMutex lock;
- HANDLE writePipe;
- volatile bool quitNow;
- bool hasWritten;
-};
+ static void CALLBACK writeFileCompleted(DWORD errorCode, DWORD numberOfBytesTransfered,
+ OVERLAPPED *overlappedBase);
+ void notified(DWORD errorCode, DWORD numberOfBytesWritten);
+ bool waitForNotification(int timeout);
+ void emitPendingBytesWrittenValue();
-#endif //QT_NO_THREAD
+ class Overlapped : public OVERLAPPED
+ {
+ Q_DISABLE_COPY(Overlapped)
+ public:
+ explicit Overlapped(QWindowsPipeWriter *pipeWriter);
+ void clear();
+
+ QWindowsPipeWriter *pipeWriter;
+ };
+
+ HANDLE handle;
+ Overlapped overlapped;
+ qint64 numberOfBytesToWrite;
+ qint64 pendingBytesWrittenValue;
+ bool stopped;
+ bool writeSequenceStarted;
+ bool notifiedCalled;
+ bool bytesWrittenPending;
+ bool inBytesWritten;
+};
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp
index bef105b184..a6f61afc90 100644
--- a/src/corelib/kernel/qeventdispatcher_winrt.cpp
+++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp
@@ -216,8 +216,10 @@ bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags)
const QVector<HANDLE> timerHandles = d->timerIdToHandle.values().toVector();
if (waitTime)
emit aboutToBlock();
+ bool timerEventsSent = false;
DWORD waitResult = WaitForMultipleObjectsEx(timerHandles.count(), timerHandles.constData(), FALSE, waitTime, TRUE);
- if (waitResult >= WAIT_OBJECT_0 && waitResult < WAIT_OBJECT_0 + timerHandles.count()) {
+ while (waitResult >= WAIT_OBJECT_0 && waitResult < WAIT_OBJECT_0 + timerHandles.count()) {
+ timerEventsSent = true;
const HANDLE handle = timerHandles.value(waitResult - WAIT_OBJECT_0);
ResetEvent(handle);
const int timerId = d->timerHandleToId.value(handle);
@@ -232,12 +234,10 @@ bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags)
// Update timer's targetTime
const quint64 targetTime = qt_msectime() + info.interval;
info.targetTime = targetTime;
- emit awake();
- return true;
+ waitResult = WaitForMultipleObjectsEx(timerHandles.count(), timerHandles.constData(), FALSE, 0, TRUE);
}
emit awake();
-
- if (userEventsSent)
+ if (timerEventsSent || userEventsSent)
return true;
// We cannot wait infinitely like on other platforms, as
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index a070ddd805..1f3d3dcfc7 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -119,8 +119,8 @@ public:
Q_INVOKABLE explicit QObject(QObject *parent=Q_NULLPTR);
virtual ~QObject();
- virtual bool event(QEvent *);
- virtual bool eventFilter(QObject *, QEvent *);
+ virtual bool event(QEvent *event);
+ virtual bool eventFilter(QObject *watched, QEvent *event);
#ifdef Q_QDOC
static QString tr(const char *sourceText, const char *comment = Q_NULLPTR, int n = -1);
@@ -195,9 +195,9 @@ public:
inline const QObjectList &children() const { return d_ptr->children; }
- void setParent(QObject *);
- void installEventFilter(QObject *);
- void removeEventFilter(QObject *);
+ void setParent(QObject *parent);
+ void installEventFilter(QObject *filterObj);
+ void removeEventFilter(QObject *obj);
static QMetaObject::Connection connect(const QObject *sender, const char *signal,
const QObject *receiver, const char *member, Qt::ConnectionType = Qt::AutoConnection);
@@ -428,9 +428,9 @@ protected:
int receivers(const char* signal) const;
bool isSignalConnected(const QMetaMethod &signal) const;
- virtual void timerEvent(QTimerEvent *);
- virtual void childEvent(QChildEvent *);
- virtual void customEvent(QEvent *);
+ virtual void timerEvent(QTimerEvent *event);
+ virtual void childEvent(QChildEvent *event);
+ virtual void customEvent(QEvent *event);
virtual void connectNotify(const QMetaMethod &signal);
virtual void disconnectNotify(const QMetaMethod &signal);
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index 48b94abae5..8a797772fc 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -310,8 +310,9 @@ QThreadPrivate::~QThreadPrivate()
The effect of the \a priority parameter is dependent on the
operating system's scheduling policy. In particular, the \a priority
will be ignored on systems that do not support thread priorities
- (such as on Linux, see http://linux.die.net/man/2/sched_setscheduler
- for more details).
+ (such as on Linux, see the
+ \l {http://linux.die.net/man/2/sched_setscheduler}{sched_setscheduler}
+ documentation for more details).
\sa run(), terminate()
*/
diff --git a/src/corelib/tools/qrect.h b/src/corelib/tools/qrect.h
index 31fdc8ce6b..b376b6b999 100644
--- a/src/corelib/tools/qrect.h
+++ b/src/corelib/tools/qrect.h
@@ -252,7 +252,7 @@ Q_DECL_CONSTEXPR inline QPoint QRect::bottomLeft() const Q_DECL_NOTHROW
{ return QPoint(x1, y2); }
Q_DECL_CONSTEXPR inline QPoint QRect::center() const Q_DECL_NOTHROW
-{ return QPoint((x1+x2)/2, (y1+y2)/2); }
+{ return QPoint(int((qint64(x1)+x2)/2), int((qint64(y1)+y2)/2)); } // cast avoids overflow on addition
Q_DECL_CONSTEXPR inline int QRect::width() const Q_DECL_NOTHROW
{ return x2 - x1 + 1; }
diff --git a/src/corelib/tools/qtimezone.cpp b/src/corelib/tools/qtimezone.cpp
index 4672248945..3c7417d64e 100644
--- a/src/corelib/tools/qtimezone.cpp
+++ b/src/corelib/tools/qtimezone.cpp
@@ -67,7 +67,7 @@ static QTimeZonePrivate *newBackendTimeZone()
#elif defined Q_OS_UNIX
return new QTzTimeZonePrivate();
// Registry based timezone backend not available on WinRT
-#elif defined Q_OS_WIN && !defined Q_OS_WINRT
+#elif defined Q_OS_WIN
return new QWinTimeZonePrivate();
#elif defined QT_USE_ICU
return new QIcuTimeZonePrivate();
@@ -94,7 +94,7 @@ static QTimeZonePrivate *newBackendTimeZone(const QByteArray &ianaId)
#elif defined Q_OS_UNIX
return new QTzTimeZonePrivate(ianaId);
// Registry based timezone backend not available on WinRT
-#elif defined Q_OS_WIN && !defined Q_OS_WINRT
+#elif defined Q_OS_WIN
return new QWinTimeZonePrivate(ianaId);
#elif defined QT_USE_ICU
return new QIcuTimeZonePrivate(ianaId);
diff --git a/src/corelib/tools/qtimezoneprivate_win.cpp b/src/corelib/tools/qtimezoneprivate_win.cpp
index 1d19f01b4e..f84b66fa99 100644
--- a/src/corelib/tools/qtimezoneprivate_win.cpp
+++ b/src/corelib/tools/qtimezoneprivate_win.cpp
@@ -48,6 +48,10 @@
QT_BEGIN_NAMESPACE
+#ifndef Q_OS_WINRT
+#define QT_USE_REGISTRY_TIMEZONE 1
+#endif
+
/*
Private
@@ -65,9 +69,10 @@ QT_BEGIN_NAMESPACE
// Vista introduced support for historic data, see MSDN docs on DYNAMIC_TIME_ZONE_INFORMATION
// http://msdn.microsoft.com/en-gb/library/windows/desktop/ms724253%28v=vs.85%29.aspx
-
+#ifdef QT_USE_REGISTRY_TIMEZONE
static const char tzRegPath[] = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones";
static const char currTzRegPath[] = "SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation";
+#endif
enum {
MIN_YEAR = -292275056,
@@ -129,6 +134,7 @@ static bool equalTzi(const TIME_ZONE_INFORMATION &tzi1, const TIME_ZONE_INFORMAT
&& wcscmp(tzi1.DaylightName, tzi2.DaylightName) == 0);
}
+#ifdef QT_USE_REGISTRY_TIMEZONE
static bool openRegistryKey(const QString &keyPath, HKEY *key)
{
return (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (const wchar_t*)keyPath.utf16(), 0, KEY_READ, key)
@@ -203,9 +209,61 @@ static TIME_ZONE_INFORMATION getRegistryTzi(const QByteArray &windowsId, bool *o
return tzi;
}
+#else // QT_USE_REGISTRY_TIMEZONE
+struct QWinDynamicTimeZone
+{
+ QString standardName;
+ QString daylightName;
+ QString timezoneName;
+ qint32 bias;
+ bool daylightTime;
+};
+
+typedef QHash<QByteArray, QWinDynamicTimeZone> QWinRTTimeZoneHash;
+
+Q_GLOBAL_STATIC(QWinRTTimeZoneHash, gTimeZones)
+
+static void enumerateTimeZones()
+{
+ DYNAMIC_TIME_ZONE_INFORMATION dtzInfo;
+ quint32 index = 0;
+ QString prevTimeZoneKeyName;
+ while (SUCCEEDED(EnumDynamicTimeZoneInformation(index++, &dtzInfo))) {
+ QWinDynamicTimeZone item;
+ item.timezoneName = QString::fromWCharArray(dtzInfo.TimeZoneKeyName);
+ // As soon as key name repeats, break. Some systems continue to always
+ // return the last item independent of index being out of range
+ if (item.timezoneName == prevTimeZoneKeyName)
+ break;
+ item.standardName = QString::fromWCharArray(dtzInfo.StandardName);
+ item.daylightName = QString::fromWCharArray(dtzInfo.DaylightName);
+ item.daylightTime = !dtzInfo.DynamicDaylightTimeDisabled;
+ item.bias = dtzInfo.Bias;
+ gTimeZones->insert(item.timezoneName.toUtf8(), item);
+ prevTimeZoneKeyName = item.timezoneName;
+ }
+}
+
+static DYNAMIC_TIME_ZONE_INFORMATION dynamicInfoForId(const QByteArray &windowsId)
+{
+ DYNAMIC_TIME_ZONE_INFORMATION dtzInfo;
+ quint32 index = 0;
+ QString prevTimeZoneKeyName;
+ while (SUCCEEDED(EnumDynamicTimeZoneInformation(index++, &dtzInfo))) {
+ const QString timeZoneName = QString::fromWCharArray(dtzInfo.TimeZoneKeyName);
+ if (timeZoneName == QLatin1String(windowsId))
+ break;
+ if (timeZoneName == prevTimeZoneKeyName)
+ break;
+ prevTimeZoneKeyName = timeZoneName;
+ }
+ return dtzInfo;
+}
+#endif // QT_USE_REGISTRY_TIMEZONE
static QList<QByteArray> availableWindowsIds()
{
+#ifdef QT_USE_REGISTRY_TIMEZONE
// TODO Consider caching results in a global static, very unlikely to change.
QList<QByteArray> list;
HKEY key = NULL;
@@ -223,10 +281,16 @@ static QList<QByteArray> availableWindowsIds()
RegCloseKey(key);
}
return list;
+#else // QT_USE_REGISTRY_TIMEZONE
+ if (gTimeZones->isEmpty())
+ enumerateTimeZones();
+ return gTimeZones->keys();
+#endif // QT_USE_REGISTRY_TIMEZONE
}
static QByteArray windowsSystemZoneId()
{
+#ifdef QT_USE_REGISTRY_TIMEZONE
// On Vista and later is held in the value TimeZoneKeyName in key currTzRegPath
QString id;
HKEY key = NULL;
@@ -248,6 +312,11 @@ static QByteArray windowsSystemZoneId()
if (equalTzi(getRegistryTzi(winId, &ok), sysTzi))
return winId;
}
+#else // QT_USE_REGISTRY_TIMEZONE
+ DYNAMIC_TIME_ZONE_INFORMATION dtzi;
+ if (SUCCEEDED(GetDynamicTimeZoneInformation(&dtzi)))
+ return QString::fromWCharArray(dtzi.TimeZoneKeyName).toLocal8Bit();
+#endif // QT_USE_REGISTRY_TIMEZONE
// If we can't determine the current ID use UTC
return QTimeZonePrivate::utcQByteArray();
@@ -368,6 +437,7 @@ void QWinTimeZonePrivate::init(const QByteArray &ianaId)
}
if (!m_windowsId.isEmpty()) {
+#ifdef QT_USE_REGISTRY_TIMEZONE
// Open the base TZI for the time zone
HKEY baseKey = NULL;
const QString baseKeyPath = QString::fromUtf8(tzRegPath) + QLatin1Char('\\')
@@ -404,6 +474,34 @@ void QWinTimeZonePrivate::init(const QByteArray &ianaId)
}
RegCloseKey(baseKey);
}
+#else // QT_USE_REGISTRY_TIMEZONE
+ if (gTimeZones->isEmpty())
+ enumerateTimeZones();
+ QWinRTTimeZoneHash::const_iterator it = gTimeZones->find(m_windowsId);
+ if (it != gTimeZones->constEnd()) {
+ m_displayName = it->timezoneName;
+ m_standardName = it->standardName;
+ m_daylightName = it->daylightName;
+ DWORD firstYear = 0;
+ DWORD lastYear = 0;
+ DYNAMIC_TIME_ZONE_INFORMATION dtzi = dynamicInfoForId(m_windowsId);
+ GetDynamicTimeZoneInformationEffectiveYears(&dtzi, &firstYear, &lastYear);
+ // If there is no dynamic information, you can still query for
+ // year 0, which helps simplifying following part
+ for (DWORD year = firstYear; year <= lastYear; ++year) {
+ TIME_ZONE_INFORMATION tzi;
+ if (!GetTimeZoneInformationForYear(year, &dtzi, &tzi))
+ continue;
+ QWinTransitionRule rule;
+ rule.standardTimeBias = tzi.Bias + tzi.StandardBias;
+ rule.daylightTimeBias = tzi.Bias + tzi.DaylightBias - rule.standardTimeBias;
+ rule.standardTimeRule = tzi.StandardDate;
+ rule.daylightTimeRule = tzi.DaylightDate;
+ rule.startYear = year;
+ m_tranRules.append(rule);
+ }
+ }
+#endif // QT_USE_REGISTRY_TIMEZONE
}
// If there are no rules then we failed to find a windowsId or any tzi info
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index e367e6e716..93dc71c3d8 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -144,9 +144,11 @@ else:unix {
SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp tools/qtimezoneprivate_tz.cpp
}
else:win32 {
- SOURCES += tools/qelapsedtimer_win.cpp tools/qlocale_win.cpp
- !winrt: SOURCES += tools/qtimezoneprivate_win.cpp
+ SOURCES += tools/qelapsedtimer_win.cpp \
+ tools/qlocale_win.cpp \
+ tools/qtimezoneprivate_win.cpp
winphone: LIBS_PRIVATE += -lWindowsPhoneGlobalizationUtil
+ winrt-*-msvc2013: LIBS += advapi32.lib
} else:integrity:SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp
else:SOURCES += tools/qelapsedtimer_generic.cpp
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index 94b91865ab..105714ee64 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -487,6 +487,11 @@ QDBusSpyCallEvent::~QDBusSpyCallEvent()
void QDBusSpyCallEvent::placeMetaCall(QObject *)
{
+ invokeSpyHooks(msg, hooks, hookCount);
+}
+
+inline void QDBusSpyCallEvent::invokeSpyHooks(const QDBusMessage &msg, const Hook *hooks, int hookCount)
+{
// call the spy hook list
for (int i = 0; i < hookCount; ++i)
hooks[i](msg);
@@ -515,7 +520,12 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg)
{
if (!ref.load())
return false;
- if (!dispatchEnabled && !QDBusMessagePrivate::isLocal(amsg)) {
+
+ // local message are always delivered, regardless of filtering
+ // or whether the dispatcher is enabled
+ bool isLocal = QDBusMessagePrivate::isLocal(amsg);
+
+ if (!dispatchEnabled && !isLocal) {
// queue messages only, we'll handle them later
qDBusDebug() << this << "delivery is suspended";
pendingMessages << amsg;
@@ -529,13 +539,23 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg)
// let them see the signal too
return false;
case QDBusMessage::MethodCallMessage:
- // run it through the spy filters (if any) before the regular processing
+ // run it through the spy filters (if any) before the regular processing:
+ // a) if it's a local message, we're in the caller's thread, so invoke the filter directly
+ // b) if it's an external message, post to the main thread
if (Q_UNLIKELY(qDBusSpyHookList.exists()) && qApp) {
const QDBusSpyHookList &list = *qDBusSpyHookList;
- qDBusDebug() << this << "invoking message spies";
- QCoreApplication::postEvent(qApp, new QDBusSpyCallEvent(this, QDBusConnection(this),
- amsg, list.constData(), list.size()));
- return true;
+ if (isLocal) {
+ Q_ASSERT(QThread::currentThread() != thread());
+ qDBusDebug() << this << "invoking message spies directly";
+ QDBusSpyCallEvent::invokeSpyHooks(amsg, list.constData(), list.size());
+ } else {
+ qDBusDebug() << this << "invoking message spies via event";
+ QCoreApplication::postEvent(qApp, new QDBusSpyCallEvent(this, QDBusConnection(this),
+ amsg, list.constData(), list.size()));
+
+ // we'll be called back, so return
+ return true;
+ }
}
handleObjectCall(amsg);
@@ -1456,9 +1476,9 @@ void QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg)
// that means the dispatchLock mutex is locked
// must not call out to user code in that case
//
- // however, if the message is internal, handleMessage was called
- // directly and no lock is in place. We can therefore call out to
- // user code, if necessary
+ // however, if the message is internal, handleMessage was called directly
+ // (user's thread) and no lock is in place. We can therefore call out to
+ // user code, if necessary.
ObjectTreeNode result;
int usedLength;
QThread *objThread = 0;
@@ -1497,12 +1517,14 @@ void QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg)
usedLength, msg));
return;
} else if (objThread != QThread::currentThread()) {
- // synchronize with other thread
+ // looped-back message, targeting another thread:
+ // synchronize with it
postEventToThread(HandleObjectCallPostEventAction, result.obj,
new QDBusActivateObjectEvent(QDBusConnection(this), this, result,
usedLength, msg, &sem));
semWait = true;
} else {
+ // looped-back message, targeting current thread
semWait = false;
}
} // release the lock
diff --git a/src/dbus/qdbusintegrator_p.h b/src/dbus/qdbusintegrator_p.h
index 89043148e3..470baeb692 100644
--- a/src/dbus/qdbusintegrator_p.h
+++ b/src/dbus/qdbusintegrator_p.h
@@ -151,6 +151,7 @@ public:
{}
~QDBusSpyCallEvent();
void placeMetaCall(QObject *) Q_DECL_OVERRIDE;
+ static inline void invokeSpyHooks(const QDBusMessage &msg, const Hook *hooks, int hookCount);
QDBusConnection conn; // keeps the refcount in QDBusConnectionPrivate up
QDBusMessage msg;
diff --git a/src/gui/kernel/qshapedpixmapdndwindow.cpp b/src/gui/kernel/qshapedpixmapdndwindow.cpp
index 2cfbc4caa4..40bf15b807 100644
--- a/src/gui/kernel/qshapedpixmapdndwindow.cpp
+++ b/src/gui/kernel/qshapedpixmapdndwindow.cpp
@@ -48,52 +48,31 @@
QT_BEGIN_NAMESPACE
QShapedPixmapWindow::QShapedPixmapWindow(QScreen *screen)
- : QWindow(screen),
- m_backingStore(0),
- m_useCompositing(true)
+ : m_useCompositing(true)
{
+ setScreen(screen);
QSurfaceFormat format;
format.setAlphaBufferSize(8);
setFormat(format);
- setSurfaceType(RasterSurface);
- setFlags(Qt::ToolTip | Qt::FramelessWindowHint |
- Qt::X11BypassWindowManagerHint | Qt::WindowTransparentForInput | Qt::WindowDoesNotAcceptFocus);
- create();
- m_backingStore = new QBackingStore(this);
+ setFlags(Qt::ToolTip | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint
+ | Qt::WindowTransparentForInput | Qt::WindowDoesNotAcceptFocus);
}
QShapedPixmapWindow::~QShapedPixmapWindow()
{
- delete m_backingStore;
- m_backingStore = 0;
-}
-
-void QShapedPixmapWindow::render()
-{
- QRect rect(QPoint(), geometry().size());
-
- m_backingStore->beginPaint(rect);
-
- QPaintDevice *device = m_backingStore->paintDevice();
-
- {
- QPainter p(device);
- if (m_useCompositing)
- p.setCompositionMode(QPainter::CompositionMode_Source);
- else
- p.fillRect(rect, QGuiApplication::palette().base());
- p.drawPixmap(0, 0, m_pixmap);
- }
-
- m_backingStore->endPaint();
- m_backingStore->flush(rect);
}
void QShapedPixmapWindow::setPixmap(const QPixmap &pixmap)
{
m_pixmap = pixmap;
- if (!m_useCompositing)
- setMask(m_pixmap.mask());
+ if (!m_useCompositing) {
+ const QBitmap mask = m_pixmap.mask();
+ if (!mask.isNull()) {
+ if (!handle())
+ create();
+ setMask(mask);
+ }
+ }
}
void QShapedPixmapWindow::setHotspot(const QPoint &hotspot)
@@ -101,19 +80,28 @@ void QShapedPixmapWindow::setHotspot(const QPoint &hotspot)
m_hotSpot = hotspot;
}
-void QShapedPixmapWindow::updateGeometry(const QPoint &pos)
+void QShapedPixmapWindow::paintEvent(QPaintEvent *)
{
- if (m_pixmap.isNull())
- m_backingStore->resize(QSize(1,1));
- else if (m_backingStore->size() != m_pixmap.size())
- m_backingStore->resize(m_pixmap.size());
-
- setGeometry(QRect(pos - m_hotSpot, m_backingStore->size()));
+ if (!m_pixmap.isNull()) {
+ const QRect rect(QPoint(0, 0), size());
+ QPainter painter(this);
+ if (m_useCompositing)
+ painter.setCompositionMode(QPainter::CompositionMode_Source);
+ else
+ painter.fillRect(rect, QGuiApplication::palette().base());
+ painter.drawPixmap(rect, m_pixmap);
+ }
}
-void QShapedPixmapWindow::exposeEvent(QExposeEvent *)
+void QShapedPixmapWindow::updateGeometry(const QPoint &pos)
{
- render();
+ QSize size(1, 1);
+ if (!m_pixmap.isNull()) {
+ size = qFuzzyCompare(m_pixmap.devicePixelRatio(), 1.0)
+ ? m_pixmap.size()
+ : (QSizeF(m_pixmap.size()) / m_pixmap.devicePixelRatio()).toSize();
+ }
+ setGeometry(QRect(pos - m_hotSpot, size));
}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qshapedpixmapdndwindow_p.h b/src/gui/kernel/qshapedpixmapdndwindow_p.h
index 65a4e3cfa7..21cecba9e8 100644
--- a/src/gui/kernel/qshapedpixmapdndwindow_p.h
+++ b/src/gui/kernel/qshapedpixmapdndwindow_p.h
@@ -51,21 +51,18 @@
// We mean it.
//
-#include <QtGui/QWindow>
+#include <QtGui/QRasterWindow>
#include <QtGui/QPixmap>
-#include <QtGui/QBackingStore>
QT_BEGIN_NAMESPACE
-class QShapedPixmapWindow : public QWindow
+class QShapedPixmapWindow : public QRasterWindow
{
Q_OBJECT
public:
explicit QShapedPixmapWindow(QScreen *screen = 0);
~QShapedPixmapWindow();
- void render();
-
void setUseCompositing(bool on) { m_useCompositing = on; }
void setPixmap(const QPixmap &pixmap);
void setHotspot(const QPoint &hotspot);
@@ -73,10 +70,9 @@ public:
void updateGeometry(const QPoint &pos);
protected:
- void exposeEvent(QExposeEvent *) Q_DECL_OVERRIDE;
+ void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
private:
- QBackingStore *m_backingStore;
QPixmap m_pixmap;
QPoint m_hotSpot;
bool m_useCompositing;
diff --git a/src/gui/painting/qcosmeticstroker.cpp b/src/gui/painting/qcosmeticstroker.cpp
index ba0d1871d1..4965762d74 100644
--- a/src/gui/painting/qcosmeticstroker.cpp
+++ b/src/gui/painting/qcosmeticstroker.cpp
@@ -68,8 +68,8 @@ static inline uint sourceOver(uint d, uint color)
inline static int F16Dot16FixedDiv(int x, int y)
{
if (qAbs(x) > 0x7fff)
- return (((qlonglong)x) << 16) / y;
- return (x << 16) / y;
+ return qlonglong(x) * (1<<16) / y;
+ return x * (1<<16) / y;
}
typedef void (*DrawPixel)(QCosmeticStroker *stroker, int x, int y, int coverage);
@@ -441,14 +441,14 @@ void QCosmeticStroker::calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal
qSwap(x1, x2);
}
int xinc = F16Dot16FixedDiv(x2 - x1, y2 - y1);
- int x = x1 << 10;
+ int x = x1 * (1<<10);
int y = (y1 + 32) >> 6;
int ys = (y2 + 32) >> 6;
int round = (xinc > 0) ? 32 : 0;
if (y != ys) {
- x += ( ((((y << 6) + round - y1))) * xinc ) >> 6;
+ x += ((y * (1<<6)) + round - y1) * xinc >> 6;
if (swapped) {
lastPixel.x = x >> 16;
@@ -480,7 +480,7 @@ void QCosmeticStroker::calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal
int round = (yinc > 0) ? 32 : 0;
if (x != xs) {
- y += ( ((((x << 6) + round - x1))) * yinc ) >> 6;
+ y += ((x * (1<<6)) + round - x1) * yinc >> 6;
if (swapped) {
lastPixel.x = x;
@@ -759,7 +759,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
dir = QCosmeticStroker::BottomToTop;
}
int xinc = F16Dot16FixedDiv(x2 - x1, y2 - y1);
- int x = x1 << 10;
+ int x = x1 * (1<<10);
if ((stroker->lastDir ^ QCosmeticStroker::VerticalMask) == dir)
caps |= swapped ? QCosmeticStroker::CapEnd : QCosmeticStroker::CapBegin;
@@ -771,7 +771,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
int round = (xinc > 0) ? 32 : 0;
if (y != ys) {
- x += ( ((((y << 6) + round - y1))) * xinc ) >> 6;
+ x += ((y * (1<<6)) + round - y1) * xinc >> 6;
// calculate first and last pixel and perform dropout control
QCosmeticStroker::Point first;
@@ -810,7 +810,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
stroker->lastDir = dir;
stroker->lastAxisAligned = axisAligned;
- Dasher dasher(stroker, swapped, y << 6, ys << 6);
+ Dasher dasher(stroker, swapped, y * (1<<6), ys * (1<<6));
do {
if (dasher.on())
@@ -836,7 +836,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
dir = QCosmeticStroker::RightToLeft;
}
int yinc = F16Dot16FixedDiv(y2 - y1, x2 - x1);
- int y = y1 << 10;
+ int y = y1 * (1<<10);
if ((stroker->lastDir ^ QCosmeticStroker::HorizontalMask) == dir)
caps |= swapped ? QCosmeticStroker::CapEnd : QCosmeticStroker::CapBegin;
@@ -848,7 +848,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
int round = (yinc > 0) ? 32 : 0;
if (x != xs) {
- y += ( ((((x << 6) + round - x1))) * yinc ) >> 6;
+ y += ((x * (1<<6)) + round - x1) * yinc >> 6;
// calculate first and last pixel to perform dropout control
QCosmeticStroker::Point first;
@@ -886,7 +886,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
stroker->lastDir = dir;
stroker->lastAxisAligned = axisAligned;
- Dasher dasher(stroker, swapped, x << 6, xs << 6);
+ Dasher dasher(stroker, swapped, x * (1<<6), xs * (1<<6));
do {
if (dasher.on())
@@ -929,7 +929,7 @@ static bool drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx
caps = swapCaps(caps);
}
- int x = (x1 - 32) << 10;
+ int x = (x1 - 32) * (1<<10);
x -= ( ((y1 & 63) - 32) * xinc ) >> 6;
capAdjust(caps, y1, y2, x, xinc);
@@ -992,7 +992,7 @@ static bool drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx
caps = swapCaps(caps);
}
- int y = (y1 - 32) << 10;
+ int y = (y1 - 32) * (1<<10);
y -= ( ((x1 & 63) - 32) * yinc ) >> 6;
capAdjust(caps, x1, x2, y, yinc);
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 898b268070..7e18250087 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -137,7 +137,7 @@ extern bool qt_is_gui_used;
Q_GUI_EXPORT int qt_defaultDpiX()
{
- if (qApp->testAttribute(Qt::AA_Use96Dpi))
+ if (QCoreApplication::instance()->testAttribute(Qt::AA_Use96Dpi))
return 96;
if (!qt_is_gui_used)
@@ -152,7 +152,7 @@ Q_GUI_EXPORT int qt_defaultDpiX()
Q_GUI_EXPORT int qt_defaultDpiY()
{
- if (qApp->testAttribute(Qt::AA_Use96Dpi))
+ if (QCoreApplication::instance()->testAttribute(Qt::AA_Use96Dpi))
return 96;
if (!qt_is_gui_used)
diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp
index ca6093227d..6065e17d9b 100644
--- a/src/gui/text/qrawfont.cpp
+++ b/src/gui/text/qrawfont.cpp
@@ -614,8 +614,7 @@ QByteArray QRawFont::fontTable(const char *tagName) const
if (!d->isValid())
return QByteArray();
- const quint32 *tagId = reinterpret_cast<const quint32 *>(tagName);
- return d->fontEngine->getSfntTable(qToBigEndian(*tagId));
+ return d->fontEngine->getSfntTable(MAKE_TAG(tagName[0], tagName[1], tagName[2], tagName[3]));
}
/*!
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
index 43eb85f1af..3adf71ccfb 100644
--- a/src/network/access/qhttpthreaddelegate.cpp
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -128,7 +128,7 @@ static QByteArray makeCacheKey(QUrl &url, QNetworkProxy *proxy)
{
QString result;
QUrl copy = url;
- QString scheme = copy.scheme().toLower();
+ QString scheme = copy.scheme();
bool isEncrypted = scheme == QLatin1String("https");
copy.setPort(copy.port(isEncrypted ? 443 : 80));
if (scheme == QLatin1String("preconnect-http")) {
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 995643a15a..d2b1a8a912 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -1125,42 +1125,40 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
Q_D(QNetworkAccessManager);
bool isLocalFile = req.url().isLocalFile();
- QString scheme = req.url().scheme().toLower();
+ QString scheme = req.url().scheme();
// fast path for GET on file:// URLs
// The QNetworkAccessFileBackend will right now only be used for PUT
- if ((op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation)
- && (isLocalFile || scheme == QLatin1String("qrc")
-#if defined(Q_OS_ANDROID)
+ if (op == QNetworkAccessManager::GetOperation
+ || op == QNetworkAccessManager::HeadOperation) {
+ if (isLocalFile
+#ifdef Q_OS_ANDROID
|| scheme == QLatin1String("assets")
#endif
- )) {
- return new QNetworkReplyFileImpl(this, req, op);
- }
+ || scheme == QLatin1String("qrc")) {
+ return new QNetworkReplyFileImpl(this, req, op);
+ }
- if ((op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation)
- && scheme == QLatin1String("data")) {
- return new QNetworkReplyDataImpl(this, req, op);
- }
+ if (scheme == QLatin1String("data"))
+ return new QNetworkReplyDataImpl(this, req, op);
- // A request with QNetworkRequest::AlwaysCache does not need any bearer management
- QNetworkRequest::CacheLoadControl mode =
- static_cast<QNetworkRequest::CacheLoadControl>(
- req.attribute(QNetworkRequest::CacheLoadControlAttribute,
+ // A request with QNetworkRequest::AlwaysCache does not need any bearer management
+ QNetworkRequest::CacheLoadControl mode =
+ static_cast<QNetworkRequest::CacheLoadControl>(
+ req.attribute(QNetworkRequest::CacheLoadControlAttribute,
QNetworkRequest::PreferNetwork).toInt());
- if (mode == QNetworkRequest::AlwaysCache
- && (op == QNetworkAccessManager::GetOperation
- || op == QNetworkAccessManager::HeadOperation)) {
- // FIXME Implement a QNetworkReplyCacheImpl instead, see QTBUG-15106
- QNetworkReplyImpl *reply = new QNetworkReplyImpl(this);
- QNetworkReplyImplPrivate *priv = reply->d_func();
- priv->manager = this;
- priv->backend = new QNetworkAccessCacheBackend();
- priv->backend->manager = this->d_func();
- priv->backend->setParent(reply);
- priv->backend->reply = priv;
- priv->setup(op, req, outgoingData);
- return reply;
+ if (mode == QNetworkRequest::AlwaysCache) {
+ // FIXME Implement a QNetworkReplyCacheImpl instead, see QTBUG-15106
+ QNetworkReplyImpl *reply = new QNetworkReplyImpl(this);
+ QNetworkReplyImplPrivate *priv = reply->d_func();
+ priv->manager = this;
+ priv->backend = new QNetworkAccessCacheBackend();
+ priv->backend->manager = this->d_func();
+ priv->backend->setParent(reply);
+ priv->backend->reply = priv;
+ priv->setup(op, req, outgoingData);
+ return reply;
+ }
}
#ifndef QT_NO_BEARERMANAGEMENT
diff --git a/src/network/access/qnetworkcookiejar.cpp b/src/network/access/qnetworkcookiejar.cpp
index 412b8d859d..398895e92f 100644
--- a/src/network/access/qnetworkcookiejar.cpp
+++ b/src/network/access/qnetworkcookiejar.cpp
@@ -224,7 +224,7 @@ QList<QNetworkCookie> QNetworkCookieJar::cookiesForUrl(const QUrl &url) const
Q_D(const QNetworkCookieJar);
const QDateTime now = QDateTime::currentDateTimeUtc();
QList<QNetworkCookie> result;
- bool isEncrypted = url.scheme().toLower() == QLatin1String("https");
+ bool isEncrypted = url.scheme() == QLatin1String("https");
// scan our cookies for something that matches
QList<QNetworkCookie>::ConstIterator it = d->allCookies.constBegin(),
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index aed05575e3..e1323527f6 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -634,7 +634,7 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq
httpRequest.setUrl(url);
httpRequest.setRedirectCount(newHttpRequest.maximumRedirectsAllowed());
- QString scheme = url.scheme().toLower();
+ QString scheme = url.scheme();
bool ssl = (scheme == QLatin1String("https")
|| scheme == QLatin1String("preconnect-https"));
q->setAttribute(QNetworkRequest::ConnectionEncryptedAttribute, ssl);
diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp
index c188918024..f674cd5c2e 100644
--- a/src/network/access/qnetworkrequest.cpp
+++ b/src/network/access/qnetworkrequest.cpp
@@ -806,10 +806,10 @@ static QByteArray headerValue(QNetworkRequest::KnownHeaders header, const QVaria
return QByteArray();
}
-static QNetworkRequest::KnownHeaders parseHeaderName(const QByteArray &headerName)
+static int parseHeaderName(const QByteArray &headerName)
{
if (headerName.isEmpty())
- return QNetworkRequest::KnownHeaders(-1);
+ return -1;
switch (tolower(headerName.at(0))) {
case 'c':
@@ -841,7 +841,7 @@ static QNetworkRequest::KnownHeaders parseHeaderName(const QByteArray &headerNam
break;
}
- return QNetworkRequest::KnownHeaders(-1); // nothing found
+ return -1; // nothing found
}
static QVariant parseHttpDate(const QByteArray &raw)
@@ -1012,8 +1012,10 @@ void QNetworkHeadersPrivate::setRawHeaderInternal(const QByteArray &key, const Q
void QNetworkHeadersPrivate::parseAndSetHeader(const QByteArray &key, const QByteArray &value)
{
// is it a known header?
- QNetworkRequest::KnownHeaders parsedKey = parseHeaderName(key);
- if (parsedKey != QNetworkRequest::KnownHeaders(-1)) {
+ const int parsedKeyAsInt = parseHeaderName(key);
+ if (parsedKeyAsInt != -1) {
+ const QNetworkRequest::KnownHeaders parsedKey
+ = static_cast<QNetworkRequest::KnownHeaders>(parsedKeyAsInt);
if (value.isNull()) {
cookedHeaders.remove(parsedKey);
} else if (parsedKey == QNetworkRequest::ContentLengthHeader
diff --git a/src/network/socket/qlocalserver_win.cpp b/src/network/socket/qlocalserver_win.cpp
index dae1f82063..8cb3449343 100644
--- a/src/network/socket/qlocalserver_win.cpp
+++ b/src/network/socket/qlocalserver_win.cpp
@@ -198,6 +198,9 @@ bool QLocalServerPrivate::addListener()
memset(&listener.overlapped, 0, sizeof(listener.overlapped));
listener.overlapped.hEvent = eventHandle;
+
+ // Beware! ConnectNamedPipe will reset the eventHandle to non-signaled.
+ // Callers of addListener must check all listeners for connections.
if (!ConnectNamedPipe(listener.handle, &listener.overlapped)) {
switch (GetLastError()) {
case ERROR_IO_PENDING:
@@ -205,7 +208,6 @@ bool QLocalServerPrivate::addListener()
break;
case ERROR_PIPE_CONNECTED:
listener.connected = true;
- SetEvent(eventHandle);
break;
default:
CloseHandle(listener.handle);
@@ -257,6 +259,8 @@ bool QLocalServerPrivate::listen(const QString &name)
for (int i = 0; i < SYSTEM_MAX_PENDING_SOCKETS; ++i)
if (!addListener())
return false;
+
+ _q_onNewConnection();
return true;
}
@@ -270,37 +274,43 @@ void QLocalServerPrivate::_q_onNewConnection()
{
Q_Q(QLocalServer);
DWORD dummy;
-
- // Reset first, otherwise we could reset an event which was asserted
- // immediately after we checked the conn status.
- ResetEvent(eventHandle);
-
- // Testing shows that there is indeed absolutely no guarantee which listener gets
- // a client connection first, so there is no way around polling all of them.
- for (int i = 0; i < listeners.size(); ) {
- HANDLE handle = listeners[i].handle;
- if (listeners[i].connected
- || GetOverlappedResult(handle, &listeners[i].overlapped, &dummy, FALSE))
- {
- listeners.removeAt(i);
-
- addListener();
-
- if (pendingConnections.size() > maxPendingConnections)
- connectionEventNotifier->setEnabled(false);
-
- // Make this the last thing so connected slots can wreak the least havoc
- q->incomingConnection((quintptr)handle);
- } else {
- if (GetLastError() != ERROR_IO_INCOMPLETE) {
- q->close();
- setError(QLatin1String("QLocalServerPrivate::_q_onNewConnection"));
- return;
+ bool tryAgain;
+ do {
+ tryAgain = false;
+
+ // Reset first, otherwise we could reset an event which was asserted
+ // immediately after we checked the conn status.
+ ResetEvent(eventHandle);
+
+ // Testing shows that there is indeed absolutely no guarantee which listener gets
+ // a client connection first, so there is no way around polling all of them.
+ for (int i = 0; i < listeners.size(); ) {
+ HANDLE handle = listeners[i].handle;
+ if (listeners[i].connected
+ || GetOverlappedResult(handle, &listeners[i].overlapped, &dummy, FALSE))
+ {
+ listeners.removeAt(i);
+
+ addListener();
+
+ if (pendingConnections.size() > maxPendingConnections)
+ connectionEventNotifier->setEnabled(false);
+ else
+ tryAgain = true;
+
+ // Make this the last thing so connected slots can wreak the least havoc
+ q->incomingConnection((quintptr)handle);
+ } else {
+ if (GetLastError() != ERROR_IO_INCOMPLETE) {
+ q->close();
+ setError(QLatin1String("QLocalServerPrivate::_q_onNewConnection"));
+ return;
+ }
+
+ ++i;
}
-
- ++i;
}
- }
+ } while (tryAgain);
}
void QLocalServerPrivate::closeServer()
diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp
index 70a738864b..7f9b8a7b06 100644
--- a/src/network/socket/qlocalsocket_win.cpp
+++ b/src/network/socket/qlocalsocket_win.cpp
@@ -220,7 +220,6 @@ qint64 QLocalSocket::writeData(const char *data, qint64 maxSize)
d->pipeWriter = new QWindowsPipeWriter(d->handle, this);
connect(d->pipeWriter, SIGNAL(canWrite()), this, SLOT(_q_canWrite()));
connect(d->pipeWriter, SIGNAL(bytesWritten(qint64)), this, SIGNAL(bytesWritten(qint64)));
- d->pipeWriter->start();
}
return d->pipeWriter->write(data, maxSize);
}
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index fcc267e7cc..b86b69cad4 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -399,6 +399,10 @@ bool QSslSocketBackendPrivate::initSslContext()
if (!ace.isEmpty()
&& !QHostAddress().setAddress(tlsHostName)
&& !(configuration.sslOptions & QSsl::SslOptionDisableServerNameIndication)) {
+ // We don't send the trailing dot from the host header if present see
+ // https://tools.ietf.org/html/rfc6066#section-3
+ if (ace.endsWith('.'))
+ ace.chop(1);
if (!q_SSL_ctrl(ssl, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, ace.data()))
qCWarning(lcSsl, "could not set SSL_CTRL_SET_TLSEXT_HOSTNAME, Server Name Indication disabled");
}
@@ -632,10 +636,12 @@ void QSslSocketPrivate::resetDefaultCiphers()
// Unconditionally exclude ADH and AECDH ciphers since they offer no MITM protection
if (!ciph.name().toLower().startsWith(QLatin1String("adh")) &&
!ciph.name().toLower().startsWith(QLatin1String("exp-adh")) &&
- !ciph.name().toLower().startsWith(QLatin1String("aecdh")))
+ !ciph.name().toLower().startsWith(QLatin1String("aecdh"))) {
ciphers << ciph;
- if (ciph.usedBits() >= 128)
- defaultCiphers << ciph;
+
+ if (ciph.usedBits() >= 128)
+ defaultCiphers << ciph;
+ }
}
}
}
diff --git a/src/platformsupport/clipboard/qmacmime.mm b/src/platformsupport/clipboard/qmacmime.mm
index 8a750b8dcb..2ad734b8b9 100644
--- a/src/platformsupport/clipboard/qmacmime.mm
+++ b/src/platformsupport/clipboard/qmacmime.mm
@@ -643,7 +643,7 @@ QList<QByteArray> QMacPasteboardMimeFileUri::convertFromMime(const QString &mime
QUrl url = urls.at(i).toUrl();
if (url.scheme().isEmpty())
url.setScheme(QLatin1String("file"));
- if (url.scheme().toLower() == QLatin1String("file")) {
+ if (url.scheme() == QLatin1String("file")) {
if (url.host().isEmpty())
url.setHost(QLatin1String("localhost"));
url.setPath(url.path().normalized(QString::NormalizationForm_D));
@@ -722,7 +722,7 @@ QList<QByteArray> QMacPasteboardMimeUrl::convertFromMime(const QString &mime, QV
QUrl url = urls.at(i).toUrl();
if (url.scheme().isEmpty())
url.setScheme(QLatin1String("file"));
- if (url.scheme().toLower() == QLatin1String("file")) {
+ if (url.scheme() == QLatin1String("file")) {
if (url.host().isEmpty())
url.setHost(QLatin1String("localhost"));
url.setPath(url.path().normalized(QString::NormalizationForm_D));
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h
index 18673a3667..fa05626d18 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.h
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h
@@ -57,7 +57,11 @@ public:
QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
void flush(QWindow *widget, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
+#ifndef QT_NO_OPENGL
QImage toImage() const Q_DECL_OVERRIDE;
+#else
+ QImage toImage() const; // No QPlatformBackingStore::toImage() for NO_OPENGL builds.
+#endif
void resize (const QSize &size, const QRegion &) Q_DECL_OVERRIDE;
bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE;
void beginPaint(const QRegion &region) Q_DECL_OVERRIDE;
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index f98ddbb14f..c021a551a7 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -428,14 +428,18 @@ void QCocoaIntegration::updateScreens()
}
siblings << screen;
}
+
+ // Set virtual siblings list. All screens in mScreens are siblings, because we ignored the
+ // mirrors. Note that some of the screens we update the siblings list for here may be deleted
+ // below, but update anyway to keep the to-be-deleted screens out of the siblings list.
+ foreach (QCocoaScreen* screen, mScreens)
+ screen->setVirtualSiblings(siblings);
+
// Now the leftovers in remainingScreens are no longer current, so we can delete them.
foreach (QCocoaScreen* screen, remainingScreens) {
mScreens.removeOne(screen);
destroyScreen(screen);
}
- // All screens in mScreens are siblings, because we ignored the mirrors.
- foreach (QCocoaScreen* screen, mScreens)
- screen->setVirtualSiblings(siblings);
}
QCocoaScreen *QCocoaIntegration::screenAtIndex(int index)
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h
index 64299c6cd2..64eeabcc2d 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.h
+++ b/src/plugins/platforms/cocoa/qcocoamenu.h
@@ -81,8 +81,6 @@ public:
inline NSMenu *nsMenu() const
{ return m_nativeMenu; }
- inline NSMenuItem *nsMenuItem() const
- { return m_nativeItem; }
inline bool isVisible() const { return m_visible; }
@@ -91,11 +89,9 @@ public:
QList<QCocoaMenuItem *> items() const;
QList<QCocoaMenuItem *> merged() const;
- void setMenuBar(QCocoaMenuBar *menuBar);
- QCocoaMenuBar *menuBar() const;
- void setContainingMenuItem(QCocoaMenuItem *menuItem);
- QCocoaMenuItem *containingMenuItem() const;
+ void setAttachedItem(NSMenuItem *item);
+ NSMenuItem *attachedItem() const;
private:
QCocoaMenuItem *itemOrNull(int index) const;
@@ -103,13 +99,10 @@ private:
QList<QCocoaMenuItem *> m_menuItems;
NSMenu *m_nativeMenu;
- NSMenuItem *m_nativeItem;
- NSObject *m_delegate;
+ NSMenuItem *m_attachedItem;
bool m_enabled;
bool m_visible;
quintptr m_tag;
- QCocoaMenuBar *m_menuBar;
- QCocoaMenuItem *m_containingMenuItem;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index 8c576c7cbe..3fc98c071f 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -102,6 +102,28 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate);
return self;
}
+- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu
+{
+ Q_ASSERT(m_menu->nsMenu() == menu);
+ return m_menu->items().count();
+}
+
+- (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel
+{
+ Q_UNUSED(index);
+ Q_ASSERT(m_menu->nsMenu() == menu);
+ if (shouldCancel) {
+ // TODO detach all submenus
+ return NO;
+ }
+
+ QCocoaMenuItem *menuItem = reinterpret_cast<QCocoaMenuItem *>(item.tag);
+ if (m_menu->items().contains(menuItem)) {
+ if (QCocoaMenu *itemSubmenu = menuItem->menu())
+ itemSubmenu->setAttachedItem(item);
+ }
+ return YES;
+}
- (void)menu:(NSMenu*)menu willHighlightItem:(NSMenuItem*)item
{
@@ -234,20 +256,16 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate);
QT_BEGIN_NAMESPACE
QCocoaMenu::QCocoaMenu() :
+ m_attachedItem(0),
m_enabled(true),
m_visible(true),
- m_tag(0),
- m_menuBar(0),
- m_containingMenuItem(0)
+ m_tag(0)
{
QMacAutoReleasePool pool;
- m_delegate = [[QCocoaMenuDelegate alloc] initWithMenu:this];
- m_nativeItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
m_nativeMenu = [[NSMenu alloc] initWithTitle:@"Untitled"];
[m_nativeMenu setAutoenablesItems:YES];
- m_nativeMenu.delegate = (QCocoaMenuDelegate *) m_delegate;
- [m_nativeItem setSubmenu:m_nativeMenu];
+ m_nativeMenu.delegate = [[QCocoaMenuDelegate alloc] initWithMenu:this];
}
QCocoaMenu::~QCocoaMenu()
@@ -257,14 +275,11 @@ QCocoaMenu::~QCocoaMenu()
SET_COCOA_MENU_ANCESTOR(item, 0);
}
- if (m_containingMenuItem)
- m_containingMenuItem->clearMenu(this);
-
QMacAutoReleasePool pool;
- [m_nativeItem setSubmenu:nil];
+ NSObject *delegate = m_nativeMenu.delegate;
+ m_nativeMenu.delegate = nil;
+ [delegate release];
[m_nativeMenu release];
- [m_delegate release];
- [m_nativeItem release];
}
void QCocoaMenu::setText(const QString &text)
@@ -272,7 +287,6 @@ void QCocoaMenu::setText(const QString &text)
QMacAutoReleasePool pool;
QString stripped = qt_mac_removeAmpersandEscapes(text);
[m_nativeMenu setTitle:QCFString::toNSString(stripped)];
- [m_nativeItem setTitle:QCFString::toNSString(stripped)];
}
void QCocoaMenu::setMinimumWidth(int width)
@@ -313,17 +327,13 @@ void QCocoaMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *
void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem)
{
- [item->nsItem() setTarget:m_delegate];
+ item->nsItem().target = m_nativeMenu.delegate;
if (!item->menu())
[item->nsItem() setAction:@selector(itemFired:)];
if (item->isMerged())
return;
- if ([item->nsItem() menu]) {
- qWarning("Menu item is already in a menu, remove it from the other menu first before inserting");
- return;
- }
// if the item we're inserting before is merged, skip along until
// we find a non-merged real item to insert ahead of.
while (beforeItem && beforeItem->isMerged()) {
@@ -451,12 +461,11 @@ void QCocoaMenu::setEnabled(bool enabled)
bool QCocoaMenu::isEnabled() const
{
- return [m_nativeItem isEnabled];
+ return m_attachedItem ? [m_attachedItem isEnabled] : m_enabled;
}
void QCocoaMenu::setVisible(bool visible)
{
- [m_nativeItem setSubmenu:(visible ? m_nativeMenu : nil)];
m_visible = visible;
}
@@ -593,8 +602,6 @@ void QCocoaMenu::syncModalState(bool modal)
if (!m_enabled)
modal = true;
- [m_nativeItem setEnabled:!modal];
-
foreach (QCocoaMenuItem *item, m_menuItems) {
if (item->menu()) { // recurse into submenus
item->menu()->syncModalState(modal);
@@ -605,25 +612,24 @@ void QCocoaMenu::syncModalState(bool modal)
}
}
-void QCocoaMenu::setMenuBar(QCocoaMenuBar *menuBar)
+void QCocoaMenu::setAttachedItem(NSMenuItem *item)
{
- m_menuBar = menuBar;
- SET_COCOA_MENU_ANCESTOR(this, menuBar);
-}
+ if (item == m_attachedItem)
+ return;
-QCocoaMenuBar *QCocoaMenu::menuBar() const
-{
- return m_menuBar;
-}
+ if (m_attachedItem)
+ m_attachedItem.submenu = nil;
+
+ m_attachedItem = item;
+
+ if (m_attachedItem)
+ m_attachedItem.submenu = m_nativeMenu;
-void QCocoaMenu::setContainingMenuItem(QCocoaMenuItem *menuItem)
-{
- m_containingMenuItem = menuItem;
}
-QCocoaMenuItem *QCocoaMenu::containingMenuItem() const
+NSMenuItem *QCocoaMenu::attachedItem() const
{
- return m_containingMenuItem;
+ return m_attachedItem;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.h b/src/plugins/platforms/cocoa/qcocoamenubar.h
index 0521bcd430..7ce2059450 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.h
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.h
@@ -77,10 +77,10 @@ private:
static QCocoaMenuBar *findGlobalMenubar();
bool shouldDisable(QCocoaWindow *active) const;
- void insertNativeMenu(QCocoaMenu *menu, QCocoaMenu *beforeMenu);
- void removeNativeMenu(QCocoaMenu *menu);
- QList<QCocoaMenu*> m_menus;
+ NSMenuItem *nativeItemForMenu(QCocoaMenu *menu) const;
+
+ QList<QPointer<QCocoaMenu> > m_menus;
NSMenu *m_nativeMenu;
QCocoaWindow *m_window;
};
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm
index c9a42e9d8e..e8b3823012 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm
@@ -57,7 +57,6 @@ static inline QCocoaMenuLoader *getMenuLoader()
return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)];
}
-
QCocoaMenuBar::QCocoaMenuBar() :
m_window(0)
{
@@ -74,11 +73,20 @@ QCocoaMenuBar::~QCocoaMenuBar()
#ifdef QT_COCOA_ENABLE_MENU_DEBUG
qDebug() << "~QCocoaMenuBar" << this;
#endif
+ foreach (QCocoaMenu *menu, m_menus) {
+ if (!menu)
+ continue;
+ NSMenuItem *item = nativeItemForMenu(menu);
+ if (menu->attachedItem() == item)
+ menu->setAttachedItem(nil);
+ }
+
[m_nativeMenu release];
static_menubars.removeOne(this);
if (m_window && m_window->menubar() == this) {
m_window->setMenubar(0);
+
// Delete the children first so they do not cause
// the native menu items to be hidden after
// the menu bar was updated
@@ -87,24 +95,6 @@ QCocoaMenuBar::~QCocoaMenuBar()
}
}
-void QCocoaMenuBar::insertNativeMenu(QCocoaMenu *menu, QCocoaMenu *beforeMenu)
-{
- QMacAutoReleasePool pool;
-
- if (beforeMenu) {
- NSUInteger nativeIndex = [m_nativeMenu indexOfItem:beforeMenu->nsMenuItem()];
- [m_nativeMenu insertItem: menu->nsMenuItem() atIndex: nativeIndex];
- } else {
- [m_nativeMenu addItem: menu->nsMenuItem()];
- }
-
- menu->setMenuBar(this);
- syncMenu(static_cast<QPlatformMenu *>(menu));
- if (menu->isVisible()) {
- [m_nativeMenu setSubmenu: menu->nsMenu() forItem: menu->nsMenuItem()];
- }
-}
-
void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *before)
{
QCocoaMenu *menu = static_cast<QCocoaMenu *>(platformMenu);
@@ -113,31 +103,40 @@ void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *befor
qDebug() << "QCocoaMenuBar" << this << "insertMenu" << menu << "before" << before;
#endif
- if (m_menus.contains(menu)) {
+ if (m_menus.contains(QPointer<QCocoaMenu>(menu))) {
qWarning("This menu already belongs to the menubar, remove it first");
return;
}
- if (beforeMenu && !m_menus.contains(beforeMenu)) {
+ if (beforeMenu && !m_menus.contains(QPointer<QCocoaMenu>(beforeMenu))) {
qWarning("The before menu does not belong to the menubar");
return;
}
- m_menus.insert(beforeMenu ? m_menus.indexOf(beforeMenu) : m_menus.size(), menu);
- if (!menu->menuBar())
- insertNativeMenu(menu, beforeMenu);
- if (m_window && m_window->window()->isActive())
- updateMenuBarImmediately();
-}
+ int insertionIndex = beforeMenu ? m_menus.indexOf(beforeMenu) : m_menus.size();
+ m_menus.insert(insertionIndex, menu);
+
+ {
+ QMacAutoReleasePool pool;
+ NSMenuItem *item = [[[NSMenuItem alloc] init] autorelease];
+ item.tag = reinterpret_cast<NSInteger>(menu);
+
+ if (beforeMenu) {
+ // QMenuBar::toNSMenu() exposes the native menubar and
+ // the user could have inserted its own items in there.
+ // Same remark applies to removeMenu().
+ NSMenuItem *beforeItem = nativeItemForMenu(beforeMenu);
+ NSInteger nativeIndex = [m_nativeMenu indexOfItem:beforeItem];
+ [m_nativeMenu insertItem:item atIndex:nativeIndex];
+ } else {
+ [m_nativeMenu addItem:item];
+ }
+ }
-void QCocoaMenuBar::removeNativeMenu(QCocoaMenu *menu)
-{
- QMacAutoReleasePool pool;
+ syncMenu(menu);
- if (menu->menuBar() == this)
- menu->setMenuBar(0);
- NSUInteger realIndex = [m_nativeMenu indexOfItem:menu->nsMenuItem()];
- [m_nativeMenu removeItemAtIndex: realIndex];
+ if (m_window && m_window->window()->isActive())
+ updateMenuBarImmediately();
}
void QCocoaMenuBar::removeMenu(QPlatformMenu *platformMenu)
@@ -147,8 +146,17 @@ void QCocoaMenuBar::removeMenu(QPlatformMenu *platformMenu)
qWarning("Trying to remove a menu that does not belong to the menubar");
return;
}
+
+ NSMenuItem *item = nativeItemForMenu(menu);
+ if (menu->attachedItem() == item)
+ menu->setAttachedItem(nil);
m_menus.removeOne(menu);
- removeNativeMenu(menu);
+
+ QMacAutoReleasePool pool;
+
+ // See remark in insertMenu().
+ NSInteger nativeIndex = [m_nativeMenu indexOfItem:item];
+ [m_nativeMenu removeItemAtIndex:nativeIndex];
}
void QCocoaMenuBar::syncMenu(QPlatformMenu *menu)
@@ -170,7 +178,16 @@ void QCocoaMenuBar::syncMenu(QPlatformMenu *menu)
break;
}
}
- [cocoaMenu->nsMenuItem() setHidden:shouldHide];
+
+ nativeItemForMenu(cocoaMenu).hidden = shouldHide;
+}
+
+NSMenuItem *QCocoaMenuBar::nativeItemForMenu(QCocoaMenu *menu) const
+{
+ if (!menu)
+ return nil;
+
+ return [m_nativeMenu itemWithTag:reinterpret_cast<NSInteger>(menu)];
}
void QCocoaMenuBar::handleReparent(QWindow *newParentWindow)
@@ -297,24 +314,16 @@ void QCocoaMenuBar::updateMenuBarImmediately()
qDebug() << "QCocoaMenuBar" << "updateMenuBarImmediately" << cw;
#endif
bool disableForModal = mb->shouldDisable(cw);
- // force a sync?
- foreach (QCocoaMenu *m, mb->m_menus) {
- mb->syncMenu(m);
- m->syncModalState(disableForModal);
- }
- // reparent shared menu items if necessary.
- // We browse the list in reverse order to be sure that the next items are redrawn before the current ones,
- // in this way we are sure that "beforeMenu" (see below) is part of the native menu before "m" is redraw
- for (int i = mb->m_menus.size() - 1; i >= 0; i--) {
- QCocoaMenu *m = mb->m_menus.at(i);
- QCocoaMenuBar *menuBar = m->menuBar();
- if (menuBar != mb) {
- QCocoaMenu *beforeMenu = i < (mb->m_menus.size() - 1) ? mb->m_menus.at(i + 1) : 0;
- if (menuBar)
- menuBar->removeNativeMenu(m);
- mb->insertNativeMenu(m, beforeMenu);
- }
+ foreach (QCocoaMenu *menu, mb->m_menus) {
+ if (!menu)
+ continue;
+ NSMenuItem *item = mb->nativeItemForMenu(menu);
+ menu->setAttachedItem(item);
+ SET_COCOA_MENU_ANCESTOR(menu, mb);
+ // force a sync?
+ mb->syncMenu(menu);
+ menu->syncModalState(disableForModal);
}
QCocoaMenuLoader *loader = getMenuLoader();
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.h b/src/plugins/platforms/cocoa/qcocoamenuitem.h
index 0d6f67959b..bba9ce3963 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.h
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.h
@@ -93,7 +93,6 @@ public:
inline bool isSeparator() const { return m_isSeparator; }
QCocoaMenu *menu() const { return m_menu; }
- void clearMenu(QCocoaMenu *menu);
MenuRole effectiveRole() const;
private:
@@ -105,7 +104,7 @@ private:
QString m_text;
bool m_textSynced;
QIcon m_icon;
- QCocoaMenu *m_menu;
+ QPointer<QCocoaMenu> m_menu;
bool m_isVisible;
bool m_enabled;
bool m_isSeparator;
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index 9e4f0b9ad1..de0271ce4d 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -142,15 +142,12 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu)
if (m_menu) {
if (COCOA_MENU_ANCESTOR(m_menu) == this)
SET_COCOA_MENU_ANCESTOR(m_menu, 0);
- if (m_menu->containingMenuItem() == this)
- m_menu->setContainingMenuItem(0);
}
QMacAutoReleasePool pool;
m_menu = static_cast<QCocoaMenu *>(menu);
if (m_menu) {
SET_COCOA_MENU_ANCESTOR(m_menu, this);
- m_menu->setContainingMenuItem(this);
} else {
// we previously had a menu, but no longer
// clear out our item so the nexy sync() call builds a new one
@@ -159,12 +156,6 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu)
}
}
-void QCocoaMenuItem::clearMenu(QCocoaMenu *menu)
-{
- if (menu == m_menu)
- m_menu = 0;
-}
-
void QCocoaMenuItem::setVisible(bool isVisible)
{
m_isVisible = isVisible;
@@ -226,14 +217,6 @@ NSMenuItem *QCocoaMenuItem::sync()
m_native = nil;
}
- if (m_menu) {
- if (m_native != m_menu->nsMenuItem()) {
- [m_native release];
- m_native = [m_menu->nsMenuItem() retain];
- [m_native setTag:reinterpret_cast<NSInteger>(this)];
- }
- }
-
if ((m_role != NoRole && !m_textSynced) || m_merged) {
NSMenuItem *mergeItem = nil;
QCocoaMenuLoader *loader = getMenuLoader();
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index eb65f7e061..b501358acc 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -414,6 +414,7 @@ QCocoaWindow::~QCocoaWindow()
#endif
QMacAutoReleasePool pool;
+ [m_nsWindow makeFirstResponder:nil];
[m_nsWindow setContentView:nil];
[m_nsWindow.helper detachFromPlatformWindow];
if (m_isNSWindowChild) {
@@ -1004,7 +1005,15 @@ void QCocoaWindow::raise()
[parentNSWindow removeChildWindow:m_nsWindow];
[parentNSWindow addChildWindow:m_nsWindow ordered:NSWindowAbove];
} else {
- [m_nsWindow orderFront: m_nsWindow];
+ {
+ // Clean up autoreleased temp objects from orderFront immediately.
+ // Failure to do so has been observed to cause leaks also beyond any outer
+ // autorelease pool (for example around a complete QWindow
+ // construct-show-raise-hide-delete cyle), counter to expected autoreleasepool
+ // behavior.
+ QMacAutoReleasePool pool;
+ [m_nsWindow orderFront: m_nsWindow];
+ }
static bool raiseProcess = qt_mac_resolveOption(true, "QT_MAC_SET_RAISE_PROCESS");
if (raiseProcess) {
ProcessSerialNumber psn;
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index 48de7d56f8..5b2370b69d 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -1253,7 +1253,12 @@ QList<int> QWindowsKeyMapper::possibleKeys(const QKeyEvent *e) const
{
QList<int> result;
- const KeyboardLayoutItem &kbItem = keyLayout[e->nativeVirtualKey()];
+
+ const quint32 nativeVirtualKey = e->nativeVirtualKey();
+ if (nativeVirtualKey > 255)
+ return result;
+
+ const KeyboardLayoutItem &kbItem = keyLayout[nativeVirtualKey];
if (!kbItem.exists)
return result;
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index 4c4d553b2d..47e68ae0af 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -39,8 +39,10 @@
#include "qwinrtbackingstore.h"
#include "qwinrtinputcontext.h"
#include "qwinrtcursor.h"
+#include "qwinrtwindow.h"
#include <private/qeventdispatcher_winrt_p.h>
+#include <QtCore/QLoggingCategory>
#include <QtGui/QSurfaceFormat>
#include <QtGui/QGuiApplication>
#include <qpa/qwindowsysteminterface.h>
@@ -469,6 +471,7 @@ QWinRTScreen::QWinRTScreen()
: d_ptr(new QWinRTScreenPrivate)
{
Q_D(QWinRTScreen);
+ qCDebug(lcQpaWindows) << __FUNCTION__;
d->orientation = Qt::PrimaryOrientation;
d->touchDevice = Q_NULLPTR;
@@ -553,6 +556,7 @@ QWinRTScreen::QWinRTScreen()
QWinRTScreen::~QWinRTScreen()
{
Q_D(QWinRTScreen);
+ qCDebug(lcQpaWindows) << __FUNCTION__ << this;
// Unregister callbacks
HRESULT hr;
@@ -631,6 +635,12 @@ QDpi QWinRTScreen::logicalDpi() const
return QDpi(d->logicalDpi, d->logicalDpi);
}
+qreal QWinRTScreen::pixelDensity() const
+{
+ Q_D(const QWinRTScreen);
+ return qRound(d->logicalDpi / 96);
+}
+
qreal QWinRTScreen::scaleFactor() const
{
Q_D(const QWinRTScreen);
@@ -697,6 +707,8 @@ Xaml::IDependencyObject *QWinRTScreen::canvas() const
void QWinRTScreen::setStatusBarVisibility(bool visible, QWindow *window)
{
Q_D(QWinRTScreen);
+ qCDebug(lcQpaWindows) << __FUNCTION__ << window << visible;
+
const Qt::WindowFlags windowType = window->flags() & Qt::WindowType_Mask;
if (!window || (windowType != Qt::Window && windowType != Qt::Dialog))
return;
@@ -768,6 +780,7 @@ QWindow *QWinRTScreen::topWindow() const
void QWinRTScreen::addWindow(QWindow *window)
{
Q_D(QWinRTScreen);
+ qCDebug(lcQpaWindows) << __FUNCTION__ << window;
if (window == topWindow())
return;
@@ -785,6 +798,7 @@ void QWinRTScreen::addWindow(QWindow *window)
void QWinRTScreen::removeWindow(QWindow *window)
{
Q_D(QWinRTScreen);
+ qCDebug(lcQpaWindows) << __FUNCTION__ << window;
#ifdef Q_OS_WINPHONE
if (window->visibility() == QWindow::Minimized)
@@ -1131,6 +1145,7 @@ HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *
hr = d->coreWindow->get_Bounds(&size);
RETURN_OK_IF_FAILED("Failed to get window bounds");
d->logicalSize = QSizeF(size.Width, size.Height);
+ qCDebug(lcQpaWindows) << __FUNCTION__ << d->logicalSize;
QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry());
QPlatformScreen::resizeMaximizedWindows();
handleExpose();
@@ -1140,6 +1155,7 @@ HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *
HRESULT QWinRTScreen::onActivated(ICoreWindow *, IWindowActivatedEventArgs *args)
{
Q_D(QWinRTScreen);
+ qCDebug(lcQpaWindows) << __FUNCTION__;
CoreWindowActivationState activationState;
args->get_WindowActivationState(&activationState);
@@ -1159,6 +1175,8 @@ HRESULT QWinRTScreen::onActivated(ICoreWindow *, IWindowActivatedEventArgs *args
HRESULT QWinRTScreen::onClosed(ICoreWindow *, ICoreWindowEventArgs *)
{
+ qCDebug(lcQpaWindows) << __FUNCTION__;
+
foreach (QWindow *w, QGuiApplication::topLevelWindows())
QWindowSystemInterface::handleCloseEvent(w);
return S_OK;
@@ -1170,6 +1188,7 @@ HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *, IVisibilityChangedEvent
boolean visible;
HRESULT hr = args ? args->get_Visible(&visible) : d->coreWindow->get_Visible(&visible);
RETURN_OK_IF_FAILED("Failed to get visibility.");
+ qCDebug(lcQpaWindows) << __FUNCTION__ << visible;
QWindowSystemInterface::handleApplicationStateChanged(visible ? Qt::ApplicationActive : Qt::ApplicationHidden);
if (visible)
handleExpose();
@@ -1179,7 +1198,7 @@ HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *, IVisibilityChangedEvent
HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable *)
{
Q_D(QWinRTScreen);
-
+ qCDebug(lcQpaWindows) << __FUNCTION__;
DisplayOrientations displayOrientation;
HRESULT hr = d->displayInformation->get_CurrentOrientation(&displayOrientation);
RETURN_OK_IF_FAILED("Failed to get current orientations.");
@@ -1187,7 +1206,8 @@ HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable *
Qt::ScreenOrientation newOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation)));
if (d->orientation != newOrientation) {
d->orientation = newOrientation;
-#ifdef Q_OS_WINPHONE
+ qCDebug(lcQpaWindows) << " New orientation:" << newOrientation;
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
onSizeChanged(nullptr, nullptr);
#endif
QWindowSystemInterface::handleScreenOrientationChange(screen(), d->orientation);
@@ -1211,6 +1231,8 @@ HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *)
hr = d->displayInformation->get_ResolutionScale(&resolutionScale);
d->scaleFactor = qreal(resolutionScale) / 100;
#endif
+ qCDebug(lcQpaWindows) << __FUNCTION__ << "Scale Factor:" << d->scaleFactor;
+
RETURN_OK_IF_FAILED("Failed to get scale factor");
FLOAT dpi;
@@ -1225,6 +1247,8 @@ HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *)
hr = d->displayInformation->get_RawDpiY(&dpi);
RETURN_OK_IF_FAILED("Failed to get y raw DPI.");
d->physicalDpi.second = dpi ? dpi : 96.0;
+ qCDebug(lcQpaWindows) << __FUNCTION__ << "Logical DPI:" << d->logicalDpi
+ << "Physical DPI:" << d->physicalDpi;
return S_OK;
}
@@ -1232,12 +1256,14 @@ HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *)
#ifdef Q_OS_WINPHONE
HRESULT QWinRTScreen::onStatusBarShowing(IStatusBar *, IInspectable *)
{
+ qCDebug(lcQpaWindows) << __FUNCTION__;
onSizeChanged(nullptr, nullptr);
return S_OK;
}
HRESULT QWinRTScreen::onStatusBarHiding(IStatusBar *, IInspectable *)
{
+ qCDebug(lcQpaWindows) << __FUNCTION__;
onSizeChanged(nullptr, nullptr);
return S_OK;
}
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h
index 0043b2cfa3..ac9db9bfef 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.h
+++ b/src/plugins/platforms/winrt/qwinrtscreen.h
@@ -93,6 +93,7 @@ public:
QImage::Format format() const Q_DECL_OVERRIDE;
QSizeF physicalSize() const Q_DECL_OVERRIDE;
QDpi logicalDpi() const Q_DECL_OVERRIDE;
+ qreal pixelDensity() const Q_DECL_OVERRIDE;
qreal scaleFactor() const;
QPlatformCursor *cursor() const Q_DECL_OVERRIDE;
Qt::KeyboardModifiers keyboardModifiers() const;
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index 9409de2406..ea20ef7a04 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -429,6 +429,7 @@ void QXcbDrag::move(const QPoint &globalPos)
xcb_client_message_event_t enter;
enter.response_type = XCB_CLIENT_MESSAGE;
+ enter.sequence = 0;
enter.window = target;
enter.format = 32;
enter.type = atom(QXcbAtom::XdndEnter);
@@ -457,6 +458,7 @@ void QXcbDrag::move(const QPoint &globalPos)
xcb_client_message_event_t move;
move.response_type = XCB_CLIENT_MESSAGE;
+ move.sequence = 0;
move.window = target;
move.format = 32;
move.type = atom(QXcbAtom::XdndPosition);
@@ -485,6 +487,7 @@ void QXcbDrag::drop(const QPoint &globalPos)
xcb_client_message_event_t drop;
drop.response_type = XCB_CLIENT_MESSAGE;
+ drop.sequence = 0;
drop.window = current_target;
drop.format = 32;
drop.type = atom(QXcbAtom::XdndDrop);
@@ -746,6 +749,7 @@ void QXcbDrag::handle_xdnd_position(QPlatformWindow *w, const xcb_client_message
xcb_client_message_event_t response;
response.response_type = XCB_CLIENT_MESSAGE;
+ response.sequence = 0;
response.window = xdnd_dragsource;
response.format = 32;
response.type = atom(QXcbAtom::XdndStatus);
@@ -892,6 +896,7 @@ void QXcbDrag::send_leave()
xcb_client_message_event_t leave;
leave.response_type = XCB_CLIENT_MESSAGE;
+ leave.sequence = 0;
leave.window = current_target;
leave.format = 32;
leave.type = atom(QXcbAtom::XdndLeave);
@@ -962,6 +967,7 @@ void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *e
xcb_client_message_event_t finished;
finished.response_type = XCB_CLIENT_MESSAGE;
+ finished.sequence = 0;
finished.window = xdnd_dragsource;
finished.format = 32;
finished.type = atom(QXcbAtom::XdndFinished);
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 18b0667390..67a9b2f190 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -367,6 +367,7 @@ void QXcbScreen::sendStartupMessage(const QByteArray &message) const
ev.response_type = XCB_CLIENT_MESSAGE;
ev.format = 8;
ev.type = connection()->atom(QXcbAtom::_NET_STARTUP_INFO_BEGIN);
+ ev.sequence = 0;
ev.window = rootWindow;
int sent = 0;
int length = message.length() + 1; // include NUL byte
diff --git a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
index cfed556ec9..5522af86de 100644
--- a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
+++ b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
@@ -100,9 +100,9 @@ xcb_window_t QXcbSystemTrayTracker::locateTrayWindow(const QXcbConnection *conne
void QXcbSystemTrayTracker::requestSystemTrayWindowDock(xcb_window_t window) const
{
xcb_client_message_event_t trayRequest;
- memset(&trayRequest, 0, sizeof(trayRequest));
trayRequest.response_type = XCB_CLIENT_MESSAGE;
trayRequest.format = 32;
+ trayRequest.sequence = 0;
trayRequest.window = m_trayWindow;
trayRequest.type = m_trayAtom;
trayRequest.data.data32[0] = XCB_CURRENT_TIME;
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 42e7d5da2c..13eecbfb4f 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -1111,21 +1111,37 @@ QXcbWindow::NetWmStates QXcbWindow::netWmStates()
void QXcbWindow::setNetWmStates(NetWmStates states)
{
QVector<xcb_atom_t> atoms;
- if (states & NetWmStateAbove)
+
+ xcb_get_property_cookie_t get_cookie =
+ xcb_get_property_unchecked(xcb_connection(), 0, m_window, atom(QXcbAtom::_NET_WM_STATE),
+ XCB_ATOM_ATOM, 0, 1024);
+
+ xcb_get_property_reply_t *reply =
+ xcb_get_property_reply(xcb_connection(), get_cookie, NULL);
+
+ if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM && reply->value_len > 0) {
+ const xcb_atom_t *data = static_cast<const xcb_atom_t *>(xcb_get_property_value(reply));
+ atoms.resize(reply->value_len);
+ memcpy((void *)&atoms.first(), (void *)data, reply->value_len * sizeof(xcb_atom_t));
+ }
+
+ free(reply);
+
+ if (states & NetWmStateAbove && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_ABOVE)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_ABOVE));
- if (states & NetWmStateBelow)
+ if (states & NetWmStateBelow && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_BELOW)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_BELOW));
- if (states & NetWmStateFullScreen)
+ if (states & NetWmStateFullScreen && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN));
- if (states & NetWmStateMaximizedHorz)
+ if (states & NetWmStateMaximizedHorz && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ));
- if (states & NetWmStateMaximizedVert)
+ if (states & NetWmStateMaximizedVert && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT));
- if (states & NetWmStateModal)
+ if (states & NetWmStateModal && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MODAL)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MODAL));
- if (states & NetWmStateStaysOnTop)
+ if (states & NetWmStateStaysOnTop && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP));
- if (states & NetWmStateDemandsAttention)
+ if (states & NetWmStateDemandsAttention && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION));
if (atoms.isEmpty()) {
@@ -1245,6 +1261,7 @@ void QXcbWindow::changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two)
event.response_type = XCB_CLIENT_MESSAGE;
event.format = 32;
+ event.sequence = 0;
event.window = m_window;
event.type = atom(QXcbAtom::_NET_WM_STATE);
event.data.data32[0] = set ? 1 : 0;
@@ -1286,6 +1303,7 @@ void QXcbWindow::setWindowState(Qt::WindowState state)
event.response_type = XCB_CLIENT_MESSAGE;
event.format = 32;
+ event.sequence = 0;
event.window = m_window;
event.type = atom(QXcbAtom::WM_CHANGE_STATE);
event.data.data32[0] = XCB_WM_STATE_ICONIC;
@@ -1690,6 +1708,7 @@ void QXcbWindow::requestActivateWindow()
event.response_type = XCB_CLIENT_MESSAGE;
event.format = 32;
+ event.sequence = 0;
event.window = m_window;
event.type = atom(QXcbAtom::_NET_ACTIVE_WINDOW);
event.data.data32[0] = 1;
@@ -2636,6 +2655,7 @@ bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner)
xcb_client_message_event_t xev;
xev.response_type = XCB_CLIENT_MESSAGE;
xev.type = moveResize;
+ xev.sequence = 0;
xev.window = xcb_window();
xev.format = 32;
const QPoint globalPos = window()->mapToGlobal(pos);
@@ -2664,6 +2684,7 @@ void QXcbWindow::sendXEmbedMessage(xcb_window_t window, quint32 message,
event.response_type = XCB_CLIENT_MESSAGE;
event.format = 32;
+ event.sequence = 0;
event.window = window;
event.type = atom(QXcbAtom::_XEMBED);
event.data.data32[0] = connection()->time();
diff --git a/src/sql/kernel/qsqlresult.h b/src/sql/kernel/qsqlresult.h
index ad5f615a52..c6611c925f 100644
--- a/src/sql/kernel/qsqlresult.h
+++ b/src/sql/kernel/qsqlresult.h
@@ -44,6 +44,9 @@
#include <QtCore/qvector.h>
#include <QtSql/qsql.h>
+// for testing:
+class tst_QSqlQuery;
+
QT_BEGIN_NAMESPACE
@@ -60,6 +63,8 @@ class Q_SQL_EXPORT QSqlResult
Q_DECLARE_PRIVATE(QSqlResult)
friend class QSqlQuery;
friend class QSqlTableModelPrivate;
+ // for testing:
+ friend class ::tst_QSqlQuery;
public:
virtual ~QSqlResult();
diff --git a/src/testlib/Qt5TestConfigExtras.cmake.in b/src/testlib/Qt5TestConfigExtras.cmake.in
new file mode 100644
index 0000000000..2a575958ae
--- /dev/null
+++ b/src/testlib/Qt5TestConfigExtras.cmake.in
@@ -0,0 +1,5 @@
+
+set_property(TARGET Qt5::Test
+ APPEND PROPERTY
+ INTERFACE_COMPILE_DEFINITIONS QT_TESTCASE_BUILDDIR=\\\"\${CMAKE_BINARY_DIR}\\\"
+)
diff --git a/src/widgets/dialogs/qerrormessage.cpp b/src/widgets/dialogs/qerrormessage.cpp
index c5e764236a..77d9eb29ac 100644
--- a/src/widgets/dialogs/qerrormessage.cpp
+++ b/src/widgets/dialogs/qerrormessage.cpp
@@ -402,4 +402,6 @@ void QErrorMessagePrivate::retranslateStrings()
QT_END_NAMESPACE
+#include "moc_qerrormessage.cpp"
+
#endif // QT_NO_ERRORMESSAGE
diff --git a/src/widgets/dialogs/qfileinfogatherer.cpp b/src/widgets/dialogs/qfileinfogatherer.cpp
index b20db8fc7c..014792ea93 100644
--- a/src/widgets/dialogs/qfileinfogatherer.cpp
+++ b/src/widgets/dialogs/qfileinfogatherer.cpp
@@ -345,3 +345,5 @@ void QFileInfoGatherer::fetch(const QFileInfo &fileInfo, QElapsedTimer &base, bo
#endif // QT_NO_FILESYSTEMMODEL
QT_END_NAMESPACE
+
+#include "moc_qfileinfogatherer_p.cpp"
diff --git a/src/widgets/dialogs/qsidebar.cpp b/src/widgets/dialogs/qsidebar.cpp
index 1b1eb6472e..d86cddab61 100644
--- a/src/widgets/dialogs/qsidebar.cpp
+++ b/src/widgets/dialogs/qsidebar.cpp
@@ -515,4 +515,6 @@ bool QSidebar::event(QEvent * event)
QT_END_NAMESPACE
+#include "moc_qsidebar_p.cpp"
+
#endif
diff --git a/src/widgets/effects/qgraphicseffect.cpp b/src/widgets/effects/qgraphicseffect.cpp
index abeb153e53..4d1d1e9896 100644
--- a/src/widgets/effects/qgraphicseffect.cpp
+++ b/src/widgets/effects/qgraphicseffect.cpp
@@ -1235,4 +1235,7 @@ void QGraphicsOpacityEffect::draw(QPainter *painter)
QT_END_NAMESPACE
+#include "moc_qgraphicseffect.cpp"
+#include "moc_qgraphicseffect_p.cpp"
+
#endif //QT_NO_GRAPHICSEFFECT
diff --git a/src/widgets/effects/qpixmapfilter.cpp b/src/widgets/effects/qpixmapfilter.cpp
index 1d4014cbae..1ff4f8e88a 100644
--- a/src/widgets/effects/qpixmapfilter.cpp
+++ b/src/widgets/effects/qpixmapfilter.cpp
@@ -1345,4 +1345,6 @@ void QPixmapDropShadowFilter::draw(QPainter *p,
QT_END_NAMESPACE
+#include "moc_qpixmapfilter_p.cpp"
+
#endif //QT_NO_GRAPHICSEFFECT
diff --git a/src/widgets/graphicsview/qgraphicsanchorlayout.cpp b/src/widgets/graphicsview/qgraphicsanchorlayout.cpp
index f20203cd80..176ce694a0 100644
--- a/src/widgets/graphicsview/qgraphicsanchorlayout.cpp
+++ b/src/widgets/graphicsview/qgraphicsanchorlayout.cpp
@@ -529,4 +529,7 @@ QSizeF QGraphicsAnchorLayout::sizeHint(Qt::SizeHint which, const QSizeF &constra
}
QT_END_NAMESPACE
+
+#include "moc_qgraphicsanchorlayout.cpp"
+
#endif //QT_NO_GRAPHICSVIEW
diff --git a/src/widgets/graphicsview/qgraphicsitemanimation.cpp b/src/widgets/graphicsview/qgraphicsitemanimation.cpp
index 5e12e67a86..c5687ee9b3 100644
--- a/src/widgets/graphicsview/qgraphicsitemanimation.cpp
+++ b/src/widgets/graphicsview/qgraphicsitemanimation.cpp
@@ -594,4 +594,6 @@ void QGraphicsItemAnimation::afterAnimationStep(qreal step)
QT_END_NAMESPACE
+#include "moc_qgraphicsitemanimation.cpp"
+
#endif // QT_NO_GRAPHICSVIEW
diff --git a/src/widgets/graphicsview/qgraphicsscenelinearindex.cpp b/src/widgets/graphicsview/qgraphicsscenelinearindex.cpp
index bd09570c4a..06f9125612 100644
--- a/src/widgets/graphicsview/qgraphicsscenelinearindex.cpp
+++ b/src/widgets/graphicsview/qgraphicsscenelinearindex.cpp
@@ -91,3 +91,4 @@
Add the \a item from the index.
*/
+#include "moc_qgraphicsscenelinearindex_p.cpp"
diff --git a/src/widgets/graphicsview/qgraphicswidget.cpp b/src/widgets/graphicsview/qgraphicswidget.cpp
index e7fca55550..d52aff5131 100644
--- a/src/widgets/graphicsview/qgraphicswidget.cpp
+++ b/src/widgets/graphicsview/qgraphicswidget.cpp
@@ -2417,4 +2417,6 @@ void QGraphicsWidget::dumpFocusChain()
QT_END_NAMESPACE
+#include "moc_qgraphicswidget.cpp"
+
#endif //QT_NO_GRAPHICSVIEW
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index 9135d1a23c..da4492a684 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -4401,7 +4401,20 @@ QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes,
QItemViewPaintPairs paintPairs = draggablePaintPairs(indexes, r);
if (paintPairs.isEmpty())
return QPixmap();
- QPixmap pixmap(r->size());
+
+ qreal scale = 1.0f;
+
+ Q_Q(const QAbstractItemView);
+ QWidget *window = q->window();
+ if (window) {
+ QWindow *windowHandle = window->windowHandle();
+ if (windowHandle)
+ scale = windowHandle->devicePixelRatio();
+ }
+
+ QPixmap pixmap(r->size() * scale);
+ pixmap.setDevicePixelRatio(scale);
+
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
QStyleOptionViewItem option = viewOptionsV1();
diff --git a/src/widgets/itemviews/qcolumnviewgrip.cpp b/src/widgets/itemviews/qcolumnviewgrip.cpp
index d2d1819cf7..f7d6e6d2b0 100644
--- a/src/widgets/itemviews/qcolumnviewgrip.cpp
+++ b/src/widgets/itemviews/qcolumnviewgrip.cpp
@@ -189,4 +189,6 @@ originalXLocation(-1)
QT_END_NAMESPACE
+#include "moc_qcolumnviewgrip_p.cpp"
+
#endif // QT_NO_QCOLUMNVIEW
diff --git a/src/widgets/itemviews/qitemeditorfactory.cpp b/src/widgets/itemviews/qitemeditorfactory.cpp
index 9b7de87e32..5356ce3ad0 100644
--- a/src/widgets/itemviews/qitemeditorfactory.cpp
+++ b/src/widgets/itemviews/qitemeditorfactory.cpp
@@ -613,4 +613,6 @@ QT_END_NAMESPACE
#include "qitemeditorfactory.moc"
#endif
+#include "moc_qitemeditorfactory_p.cpp"
+
#endif // QT_NO_ITEMVIEWS
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
index c7085a0dc2..3303aac6ed 100644
--- a/src/widgets/itemviews/qlistview.cpp
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -3301,4 +3301,6 @@ QSize QListView::viewportSizeHint() const
QT_END_NAMESPACE
+#include "moc_qlistview.cpp"
+
#endif // QT_NO_LISTVIEW
diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp
index 434e819d9c..9b34e89ef0 100644
--- a/src/widgets/itemviews/qlistwidget.cpp
+++ b/src/widgets/itemviews/qlistwidget.cpp
@@ -1975,5 +1975,6 @@ bool QListWidget::event(QEvent *e)
QT_END_NAMESPACE
#include "moc_qlistwidget.cpp"
+#include "moc_qlistwidget_p.cpp"
#endif // QT_NO_LISTWIDGET
diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp
index 9c2db0e0e4..ed83ef7b85 100644
--- a/src/widgets/itemviews/qtablewidget.cpp
+++ b/src/widgets/itemviews/qtablewidget.cpp
@@ -2721,5 +2721,6 @@ void QTableWidget::dropEvent(QDropEvent *event) {
QT_END_NAMESPACE
#include "moc_qtablewidget.cpp"
+#include "moc_qtablewidget_p.cpp"
#endif // QT_NO_TABLEWIDGET
diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp
index 9e65879f32..74ca7d2827 100644
--- a/src/widgets/itemviews/qtreewidget.cpp
+++ b/src/widgets/itemviews/qtreewidget.cpp
@@ -3466,5 +3466,6 @@ bool QTreeWidget::event(QEvent *e)
QT_END_NAMESPACE
#include "moc_qtreewidget.cpp"
+#include "moc_qtreewidget_p.cpp"
#endif // QT_NO_TREEWIDGET
diff --git a/src/widgets/kernel/qboxlayout.cpp b/src/widgets/kernel/qboxlayout.cpp
index d167690468..f2e3df5314 100644
--- a/src/widgets/kernel/qboxlayout.cpp
+++ b/src/widgets/kernel/qboxlayout.cpp
@@ -1354,3 +1354,5 @@ QVBoxLayout::~QVBoxLayout()
}
QT_END_NAMESPACE
+
+#include "moc_qboxlayout.cpp"
diff --git a/src/widgets/kernel/qdesktopwidget.cpp b/src/widgets/kernel/qdesktopwidget.cpp
index 488665ff5f..fceb061867 100644
--- a/src/widgets/kernel/qdesktopwidget.cpp
+++ b/src/widgets/kernel/qdesktopwidget.cpp
@@ -274,3 +274,4 @@ void QDesktopWidget::resizeEvent(QResizeEvent *)
QT_END_NAMESPACE
#include "moc_qdesktopwidget.cpp"
+#include "moc_qdesktopwidget_p.cpp"
diff --git a/src/widgets/kernel/qformlayout.cpp b/src/widgets/kernel/qformlayout.cpp
index 2ee7716ac3..9b346a2c50 100644
--- a/src/widgets/kernel/qformlayout.cpp
+++ b/src/widgets/kernel/qformlayout.cpp
@@ -2114,3 +2114,5 @@ void QFormLayout::dump() const
#endif
QT_END_NAMESPACE
+
+#include "moc_qformlayout.cpp"
diff --git a/src/widgets/kernel/qgridlayout.cpp b/src/widgets/kernel/qgridlayout.cpp
index f3d294bd77..b58e7fdc9e 100644
--- a/src/widgets/kernel/qgridlayout.cpp
+++ b/src/widgets/kernel/qgridlayout.cpp
@@ -1692,3 +1692,5 @@ void QGridLayout::invalidate()
}
QT_END_NAMESPACE
+
+#include "moc_qgridlayout.cpp"
diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp
index 6c94d81e43..240f525722 100644
--- a/src/widgets/kernel/qlayout.cpp
+++ b/src/widgets/kernel/qlayout.cpp
@@ -1477,3 +1477,5 @@ QSize QLayout::closestAcceptableSize(const QWidget *widget, const QSize &size)
}
QT_END_NAMESPACE
+
+#include "moc_qlayout.cpp"
diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp
index f3c86ea306..5071c56763 100644
--- a/src/widgets/kernel/qopenglwidget.cpp
+++ b/src/widgets/kernel/qopenglwidget.cpp
@@ -1349,3 +1349,5 @@ bool QOpenGLWidget::event(QEvent *e)
}
QT_END_NAMESPACE
+
+#include "moc_qopenglwidget.cpp"
diff --git a/src/widgets/kernel/qshortcut.cpp b/src/widgets/kernel/qshortcut.cpp
index 77efaf1632..bf162249d0 100644
--- a/src/widgets/kernel/qshortcut.cpp
+++ b/src/widgets/kernel/qshortcut.cpp
@@ -658,3 +658,5 @@ bool QShortcut::event(QEvent *e)
#endif // QT_NO_SHORTCUT
QT_END_NAMESPACE
+
+#include "moc_qshortcut.cpp"
diff --git a/src/widgets/kernel/qsizepolicy.cpp b/src/widgets/kernel/qsizepolicy.cpp
index 63024fcf42..66fa350f81 100644
--- a/src/widgets/kernel/qsizepolicy.cpp
+++ b/src/widgets/kernel/qsizepolicy.cpp
@@ -512,3 +512,5 @@ QDebug operator<<(QDebug dbg, const QSizePolicy &p)
#endif
QT_END_NAMESPACE
+
+#include "moc_qsizepolicy.cpp"
diff --git a/src/widgets/kernel/qstackedlayout.cpp b/src/widgets/kernel/qstackedlayout.cpp
index 05f7f39f0f..006b3e8588 100644
--- a/src/widgets/kernel/qstackedlayout.cpp
+++ b/src/widgets/kernel/qstackedlayout.cpp
@@ -596,3 +596,5 @@ void QStackedLayout::setStackingMode(StackingMode stackingMode)
}
QT_END_NAMESPACE
+
+#include "moc_qstackedlayout.cpp"
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index ec5a68eeef..027bf63a2e 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -1892,7 +1892,6 @@ void QWidgetPrivate::deleteTLSysExtra()
if (extra->topextra->window) {
extra->topextra->window->destroy();
}
- setWinId(0);
delete extra->topextra->window;
extra->topextra->window = 0;
@@ -7245,7 +7244,7 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
if (q->isVisible())
hide_sys();
data.crect = QRect(x, y, w, h);
- } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) {
+ } else if (q->testAttribute(Qt::WA_OutsideWSRange)) {
q->setAttribute(Qt::WA_OutsideWSRange, false);
needsShow = true;
}
diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h
index cce31e4011..43ca76ac7c 100644
--- a/src/widgets/kernel/qwidget.h
+++ b/src/widgets/kernel/qwidget.h
@@ -612,43 +612,43 @@ Q_SIGNALS:
protected:
// Event handlers
- bool event(QEvent *) Q_DECL_OVERRIDE;
- virtual void mousePressEvent(QMouseEvent *);
- virtual void mouseReleaseEvent(QMouseEvent *);
- virtual void mouseDoubleClickEvent(QMouseEvent *);
- virtual void mouseMoveEvent(QMouseEvent *);
+ bool event(QEvent *event) Q_DECL_OVERRIDE;
+ virtual void mousePressEvent(QMouseEvent *event);
+ virtual void mouseReleaseEvent(QMouseEvent *event);
+ virtual void mouseDoubleClickEvent(QMouseEvent *event);
+ virtual void mouseMoveEvent(QMouseEvent *event);
#ifndef QT_NO_WHEELEVENT
- virtual void wheelEvent(QWheelEvent *);
-#endif
- virtual void keyPressEvent(QKeyEvent *);
- virtual void keyReleaseEvent(QKeyEvent *);
- virtual void focusInEvent(QFocusEvent *);
- virtual void focusOutEvent(QFocusEvent *);
- virtual void enterEvent(QEvent *);
- virtual void leaveEvent(QEvent *);
- virtual void paintEvent(QPaintEvent *);
- virtual void moveEvent(QMoveEvent *);
- virtual void resizeEvent(QResizeEvent *);
- virtual void closeEvent(QCloseEvent *);
+ virtual void wheelEvent(QWheelEvent *event);
+#endif
+ virtual void keyPressEvent(QKeyEvent *event);
+ virtual void keyReleaseEvent(QKeyEvent *event);
+ virtual void focusInEvent(QFocusEvent *event);
+ virtual void focusOutEvent(QFocusEvent *event);
+ virtual void enterEvent(QEvent *event);
+ virtual void leaveEvent(QEvent *event);
+ virtual void paintEvent(QPaintEvent *event);
+ virtual void moveEvent(QMoveEvent *event);
+ virtual void resizeEvent(QResizeEvent *event);
+ virtual void closeEvent(QCloseEvent *event);
#ifndef QT_NO_CONTEXTMENU
- virtual void contextMenuEvent(QContextMenuEvent *);
+ virtual void contextMenuEvent(QContextMenuEvent *event);
#endif
#ifndef QT_NO_TABLETEVENT
- virtual void tabletEvent(QTabletEvent *);
+ virtual void tabletEvent(QTabletEvent *event);
#endif
#ifndef QT_NO_ACTION
- virtual void actionEvent(QActionEvent *);
+ virtual void actionEvent(QActionEvent *event);
#endif
#ifndef QT_NO_DRAGANDDROP
- virtual void dragEnterEvent(QDragEnterEvent *);
- virtual void dragMoveEvent(QDragMoveEvent *);
- virtual void dragLeaveEvent(QDragLeaveEvent *);
- virtual void dropEvent(QDropEvent *);
+ virtual void dragEnterEvent(QDragEnterEvent *event);
+ virtual void dragMoveEvent(QDragMoveEvent *event);
+ virtual void dragLeaveEvent(QDragLeaveEvent *event);
+ virtual void dropEvent(QDropEvent *event);
#endif
- virtual void showEvent(QShowEvent *);
- virtual void hideEvent(QHideEvent *);
+ virtual void showEvent(QShowEvent *event);
+ virtual void hideEvent(QHideEvent *event);
virtual bool nativeEvent(const QByteArray &eventType, void *message, long *result);
// Misc. protected functions
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index fe5b3cc85d..91af7a4cb0 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -74,7 +74,6 @@ QT_BEGIN_NAMESPACE
// Extra QWidget data
// - to minimize memory usage for members that are seldom used.
// - top-level widgets have extra extra data to reduce cost further
-class QWidgetWindow;
class QPaintEngine;
class QPixmap;
class QWidgetBackingStore;
@@ -160,7 +159,7 @@ struct QTLWExtra {
QWidgetBackingStoreTracker backingStoreTracker;
QBackingStore *backingStore;
QPainter *sharedPainter;
- QWidgetWindow *window;
+ QWindow *window;
QOpenGLContext *shareContext;
// Implicit pointers (shared_null).
diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp
index 03f62582ff..9025160e5c 100644
--- a/src/widgets/kernel/qwidgetbackingstore.cpp
+++ b/src/widgets/kernel/qwidgetbackingstore.cpp
@@ -1631,3 +1631,5 @@ void QWidgetPrivate::repaint_sys(const QRegion &rgn)
QT_END_NAMESPACE
+
+#include "moc_qwidgetbackingstore_p.cpp"
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index def371c36e..c22841dd56 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -1007,3 +1007,5 @@ void QWidgetWindow::updateObjectName()
}
QT_END_NAMESPACE
+
+#include "moc_qwidgetwindow_p.cpp"
diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp
index 462a41ce5d..d7f4b1f989 100644
--- a/src/widgets/kernel/qwindowcontainer.cpp
+++ b/src/widgets/kernel/qwindowcontainer.cpp
@@ -403,3 +403,5 @@ void QWindowContainer::parentWasLowered(QWidget *parent)
}
QT_END_NAMESPACE
+
+#include "moc_qwindowcontainer_p.cpp"
diff --git a/src/widgets/statemachine/qbasickeyeventtransition.cpp b/src/widgets/statemachine/qbasickeyeventtransition.cpp
index e1b4e262e8..fe2edca613 100644
--- a/src/widgets/statemachine/qbasickeyeventtransition.cpp
+++ b/src/widgets/statemachine/qbasickeyeventtransition.cpp
@@ -203,4 +203,6 @@ void QBasicKeyEventTransition::onTransition(QEvent *)
QT_END_NAMESPACE
+#include "moc_qbasickeyeventtransition_p.cpp"
+
#endif //QT_NO_STATEMACHINE
diff --git a/src/widgets/statemachine/qbasicmouseeventtransition.cpp b/src/widgets/statemachine/qbasicmouseeventtransition.cpp
index 6ca76ce1b1..39c69b95f5 100644
--- a/src/widgets/statemachine/qbasicmouseeventtransition.cpp
+++ b/src/widgets/statemachine/qbasicmouseeventtransition.cpp
@@ -208,4 +208,6 @@ void QBasicMouseEventTransition::onTransition(QEvent *)
QT_END_NAMESPACE
+#include "moc_qbasicmouseeventtransition_p.cpp"
+
#endif //QT_NO_STATEMACHINE
diff --git a/src/widgets/statemachine/qkeyeventtransition.cpp b/src/widgets/statemachine/qkeyeventtransition.cpp
index ef5151d1eb..0e9f8458c2 100644
--- a/src/widgets/statemachine/qkeyeventtransition.cpp
+++ b/src/widgets/statemachine/qkeyeventtransition.cpp
@@ -174,4 +174,6 @@ void QKeyEventTransition::onTransition(QEvent *event)
QT_END_NAMESPACE
+#include "moc_qkeyeventtransition.cpp"
+
#endif //QT_NO_STATEMACHINE
diff --git a/src/widgets/statemachine/qmouseeventtransition.cpp b/src/widgets/statemachine/qmouseeventtransition.cpp
index d287bb23aa..047a9779fe 100644
--- a/src/widgets/statemachine/qmouseeventtransition.cpp
+++ b/src/widgets/statemachine/qmouseeventtransition.cpp
@@ -202,4 +202,6 @@ void QMouseEventTransition::onTransition(QEvent *event)
QT_END_NAMESPACE
+#include "moc_qmouseeventtransition.cpp"
+
#endif //QT_NO_STATEMACHINE
diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp
index 1cd91a26ee..3bab2f5dbe 100644
--- a/src/widgets/styles/qfusionstyle.cpp
+++ b/src/widgets/styles/qfusionstyle.cpp
@@ -3741,4 +3741,6 @@ QPixmap QFusionStyle::standardPixmap(StandardPixmap standardPixmap, const QStyle
QT_END_NAMESPACE
+#include "moc_qfusionstyle_p.cpp"
+
#endif // QT_NO_STYLE_FUSION || QT_PLUGIN
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
index 782077fe70..d29ff93382 100644
--- a/src/widgets/styles/qmacstyle_mac.mm
+++ b/src/widgets/styles/qmacstyle_mac.mm
@@ -1102,17 +1102,67 @@ static QAquaWidgetSize qt_aqua_guess_size(const QWidget *widg, QSize large, QSiz
}
#endif
-static void qt_drawFocusRingOnPath(CGContextRef cg, NSBezierPath *focusRingPath)
+void QMacStylePrivate::drawFocusRing(QPainter *p, const QRect &targetRect, int hMargin, int vMargin, qreal radius) const
{
- CGContextSaveGState(cg);
- [NSGraphicsContext saveGraphicsState];
- [NSGraphicsContext setCurrentContext:[NSGraphicsContext
- graphicsContextWithGraphicsPort:(CGContextRef)cg flipped:NO]];
- NSSetFocusRingStyle(NSFocusRingOnly);
- [focusRingPath setClip]; // Clear clip path to avoid artifacts when rendering the cursor at zero pos
- [focusRingPath fill];
- [NSGraphicsContext restoreGraphicsState];
- CGContextRestoreGState(cg);
+ qreal pixelRatio = p->device()->devicePixelRatioF();
+ static const QString keyFormat = QLatin1String("$qt_focusring%1-%2-%3-%4");
+ const QString &key = keyFormat.arg(hMargin).arg(vMargin).arg(radius).arg(pixelRatio);
+ QPixmap focusRingPixmap;
+ const qreal size = radius * 2 + 5;
+
+ if (!QPixmapCache::find(key, focusRingPixmap)) {
+ focusRingPixmap = QPixmap((QSize(size, size) + 2 * QSize(hMargin, vMargin)) * pixelRatio);
+ focusRingPixmap.fill(Qt::transparent);
+ focusRingPixmap.setDevicePixelRatio(pixelRatio);
+ {
+ QMacAutoReleasePool pool;
+ NSBezierPath *focusRingPath;
+ if (radius > 0)
+ focusRingPath = [NSBezierPath bezierPathWithRoundedRect:NSMakeRect(hMargin, vMargin, size, size)
+ xRadius:radius
+ yRadius:radius];
+ else
+ focusRingPath = [NSBezierPath bezierPathWithRect:NSMakeRect(hMargin, vMargin, size, size)];
+ [NSGraphicsContext saveGraphicsState];
+ QMacCGContext gc(&focusRingPixmap);
+ [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:(CGContextRef)gc
+ flipped:NO]];
+ NSSetFocusRingStyle(NSFocusRingOnly);
+ [focusRingPath fill];
+ [NSGraphicsContext restoreGraphicsState];
+ }
+ QPixmapCache::insert(key, focusRingPixmap);
+ }
+
+ // Add 2 for the actual ring tickness going inwards
+ const qreal hCornerSize = 2 + hMargin + radius;
+ const qreal vCornerSize = 2 + vMargin + radius;
+ const qreal shCornerSize = hCornerSize * pixelRatio;
+ const qreal svCornerSize = vCornerSize * pixelRatio;
+ // top-left corner
+ p->drawPixmap(QPointF(targetRect.left(), targetRect.top()), focusRingPixmap,
+ QRectF(0, 0, shCornerSize, svCornerSize));
+ // top-right corner
+ p->drawPixmap(QPointF(targetRect.right() - hCornerSize + 1, targetRect.top()), focusRingPixmap,
+ QRectF(focusRingPixmap.width() - shCornerSize, 0, shCornerSize, svCornerSize));
+ // bottom-left corner
+ p->drawPixmap(QPointF(targetRect.left(), targetRect.bottom() - vCornerSize + 1), focusRingPixmap,
+ QRectF(0, focusRingPixmap.height() - svCornerSize, shCornerSize, svCornerSize));
+ // bottom-right corner
+ p->drawPixmap(QPointF(targetRect.right() - hCornerSize + 1, targetRect.bottom() - vCornerSize + 1), focusRingPixmap,
+ QRect(focusRingPixmap.width() - shCornerSize, focusRingPixmap.height() - svCornerSize, shCornerSize, svCornerSize));
+ // top edge
+ p->drawPixmap(QRectF(targetRect.left() + hCornerSize, targetRect.top(), targetRect.width() - 2 * hCornerSize, vCornerSize), focusRingPixmap,
+ QRect(shCornerSize, 0, focusRingPixmap.width() - 2 * shCornerSize, svCornerSize));
+ // bottom edge
+ p->drawPixmap(QRectF(targetRect.left() + hCornerSize, targetRect.bottom() - vCornerSize + 1, targetRect.width() - 2 * hCornerSize, vCornerSize), focusRingPixmap,
+ QRect(shCornerSize, focusRingPixmap.height() - svCornerSize, focusRingPixmap.width() - 2 * shCornerSize, svCornerSize));
+ // left edge
+ p->drawPixmap(QRectF(targetRect.left(), targetRect.top() + vCornerSize, hCornerSize, targetRect.height() - 2 * vCornerSize), focusRingPixmap,
+ QRect(0, svCornerSize, shCornerSize, focusRingPixmap.width() - 2 * svCornerSize));
+ // right edge
+ p->drawPixmap(QRectF(targetRect.right() - hCornerSize + 1, targetRect.top() + vCornerSize, hCornerSize, targetRect.height() - 2 * vCornerSize), focusRingPixmap,
+ QRect(focusRingPixmap.width() - shCornerSize, svCornerSize, shCornerSize, focusRingPixmap.width() - 2 * svCornerSize));
}
QAquaWidgetSize QMacStylePrivate::effectiveAquaSizeConstrain(const QStyleOption *option,
@@ -3924,12 +3974,11 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
}
}
- NSBezierPath *pushButtonFocusRingPath;
- if (bdi.kind == kThemeBevelButton)
- pushButtonFocusRingPath = [NSBezierPath bezierPathWithRect:NSRectFromCGRect(focusRect)];
- else
- pushButtonFocusRingPath = [NSBezierPath bezierPathWithRoundedRect:NSRectFromCGRect(focusRect) xRadius:4 yRadius:4];
- qt_drawFocusRingOnPath(cg, pushButtonFocusRingPath);
+ const qreal radius = bdi.kind == kThemeBevelButton ? 0 : 4;
+ const int hMargin = proxy()->pixelMetric(QStyle::PM_FocusFrameHMargin, btn, w);
+ const int vMargin = proxy()->pixelMetric(QStyle::PM_FocusFrameVMargin, btn, w);
+ const QRect focusTargetRect(focusRect.origin.x, focusRect.origin.y, focusRect.size.width, focusRect.size.height);
+ d->drawFocusRing(p, focusTargetRect.adjusted(-hMargin, -vMargin, hMargin, vMargin), hMargin, vMargin, radius);
}
if (hasMenu && (!usingYosemiteOrLater || bdi.kind == kThemeBevelButton)) {
@@ -4367,12 +4416,9 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
}
break;
case CE_FocusFrame: {
- int xOff = proxy()->pixelMetric(PM_FocusFrameHMargin, opt, w);
- int yOff = proxy()->pixelMetric(PM_FocusFrameVMargin, opt, w);
- NSRect rect = NSMakeRect(xOff+opt->rect.x(), yOff+opt->rect.y(), opt->rect.width() - 2 * xOff,
- opt->rect.height() - 2 * yOff);
- NSBezierPath *focusFramePath = [NSBezierPath bezierPathWithRect:rect];
- qt_drawFocusRingOnPath(cg, focusFramePath);
+ const int hMargin = proxy()->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, w);
+ const int vMargin = proxy()->pixelMetric(QStyle::PM_FocusFrameVMargin, opt, w);
+ d->drawFocusRing(p, opt->rect, hMargin, vMargin);
break; }
case CE_MenuItem:
case CE_MenuEmptyArea:
diff --git a/src/widgets/styles/qmacstyle_mac_p_p.h b/src/widgets/styles/qmacstyle_mac_p_p.h
index 53dd2b7a23..31ba8c3464 100644
--- a/src/widgets/styles/qmacstyle_mac_p_p.h
+++ b/src/widgets/styles/qmacstyle_mac_p_p.h
@@ -218,6 +218,8 @@ public:
void drawNSViewInRect(QCocoaWidget widget, NSView *view, const QRect &rect, QPainter *p, bool isQWidget = true, QCocoaDrawRectBlock drawRectBlock = nil) const;
void resolveCurrentNSView(QWindow *window);
+ void drawFocusRing(QPainter *p, const QRect &targetRect, int hMargin, int vMargin, qreal radius = 0) const;
+
public:
mutable QPointer<QObject> pressedButton;
mutable QPointer<QObject> defaultButton;
diff --git a/src/widgets/styles/qproxystyle.cpp b/src/widgets/styles/qproxystyle.cpp
index df152d1f39..182c974729 100644
--- a/src/widgets/styles/qproxystyle.cpp
+++ b/src/widgets/styles/qproxystyle.cpp
@@ -429,4 +429,6 @@ int QProxyStyle::layoutSpacing(QSizePolicy::ControlType control1,
QT_END_NAMESPACE
+#include "moc_qproxystyle.cpp"
+
#endif // QT_NO_STYLE_PROXY
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
index 26bb227e29..103c49496e 100644
--- a/src/widgets/styles/qstyle.cpp
+++ b/src/widgets/styles/qstyle.cpp
@@ -2424,3 +2424,5 @@ void QStyle::setProxy(QStyle *style)
}
QT_END_NAMESPACE
+
+#include "moc_qstyle.cpp"
diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h
index 0f9c9379f5..0f1259160e 100644
--- a/src/widgets/styles/qstyle.h
+++ b/src/widgets/styles/qstyle.h
@@ -72,13 +72,13 @@ public:
QStyle();
virtual ~QStyle();
- virtual void polish(QWidget *);
- virtual void unpolish(QWidget *);
+ virtual void polish(QWidget *widget);
+ virtual void unpolish(QWidget *widget);
- virtual void polish(QApplication *);
- virtual void unpolish(QApplication *);
+ virtual void polish(QApplication *application);
+ virtual void unpolish(QApplication *application);
- virtual void polish(QPalette &);
+ virtual void polish(QPalette &palette);
virtual QRect itemTextRect(const QFontMetrics &fm, const QRect &r,
int flags, bool enabled,
diff --git a/src/widgets/styles/qstyleanimation.cpp b/src/widgets/styles/qstyleanimation.cpp
index 53af663dcd..67e2ee3225 100644
--- a/src/widgets/styles/qstyleanimation.cpp
+++ b/src/widgets/styles/qstyleanimation.cpp
@@ -365,4 +365,6 @@ void QScrollbarStyleAnimation::updateCurrentTime(int time)
QT_END_NAMESPACE
+#include "moc_qstyleanimation_p.cpp"
+
#endif //QT_NO_ANIMATION
diff --git a/src/widgets/styles/qstyleplugin.cpp b/src/widgets/styles/qstyleplugin.cpp
index 464cc95827..b29ff0b9a1 100644
--- a/src/widgets/styles/qstyleplugin.cpp
+++ b/src/widgets/styles/qstyleplugin.cpp
@@ -105,3 +105,5 @@ QStylePlugin::~QStylePlugin()
}
QT_END_NAMESPACE
+
+#include "moc_qstyleplugin.cpp"
diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp
index d8af8c5de8..36aa312ce8 100644
--- a/src/widgets/styles/qwindowsstyle.cpp
+++ b/src/widgets/styles/qwindowsstyle.cpp
@@ -2403,4 +2403,6 @@ QIcon QWindowsStyle::standardIcon(StandardPixmap standardIcon, const QStyleOptio
QT_END_NAMESPACE
+#include "moc_qwindowsstyle_p.cpp"
+
#endif // QT_NO_STYLE_WINDOWS
diff --git a/src/widgets/styles/qwindowsstyle_p.h b/src/widgets/styles/qwindowsstyle_p.h
index 37b78c9523..f9d174d3c6 100644
--- a/src/widgets/styles/qwindowsstyle_p.h
+++ b/src/widgets/styles/qwindowsstyle_p.h
@@ -103,7 +103,6 @@ protected:
private:
Q_DISABLE_COPY(QWindowsStyle)
Q_DECLARE_PRIVATE(QWindowsStyle)
- void *reserved;
};
#endif // QT_NO_STYLE_WINDOWS
diff --git a/src/widgets/styles/qwindowsxpstyle_p.h b/src/widgets/styles/qwindowsxpstyle_p.h
index a3981ad104..61bb508511 100644
--- a/src/widgets/styles/qwindowsxpstyle_p.h
+++ b/src/widgets/styles/qwindowsxpstyle_p.h
@@ -99,7 +99,6 @@ private:
Q_DISABLE_COPY(QWindowsXPStyle)
Q_DECLARE_PRIVATE(QWindowsXPStyle)
friend class QStyleFactory;
- void *reserved;
};
#endif // QT_NO_STYLE_WINDOWSXP
diff --git a/src/widgets/util/qcompleter.cpp b/src/widgets/util/qcompleter.cpp
index 9f167f5924..083a4a4f27 100644
--- a/src/widgets/util/qcompleter.cpp
+++ b/src/widgets/util/qcompleter.cpp
@@ -1886,4 +1886,6 @@ QT_END_NAMESPACE
#include "moc_qcompleter.cpp"
+#include "moc_qcompleter_p.cpp"
+
#endif // QT_NO_COMPLETER
diff --git a/src/widgets/util/qflickgesture.cpp b/src/widgets/util/qflickgesture.cpp
index 933db1711b..4f08664784 100644
--- a/src/widgets/util/qflickgesture.cpp
+++ b/src/widgets/util/qflickgesture.cpp
@@ -715,4 +715,6 @@ void QFlickGestureRecognizer::reset(QGesture *state)
QT_END_NAMESPACE
+#include "moc_qflickgesture_p.cpp"
+
#endif // QT_NO_GESTURES
diff --git a/src/widgets/util/qscroller.cpp b/src/widgets/util/qscroller.cpp
index 02e3c2b82a..2e48208402 100644
--- a/src/widgets/util/qscroller.cpp
+++ b/src/widgets/util/qscroller.cpp
@@ -2063,3 +2063,6 @@ qreal QScrollerPrivate::nextSnapPos(qreal p, int dir, Qt::Orientation orientatio
*/
QT_END_NAMESPACE
+
+#include "moc_qscroller.cpp"
+#include "moc_qscroller_p.cpp"
diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp
index 59f7fae28e..3606b7c773 100644
--- a/src/widgets/util/qsystemtrayicon.cpp
+++ b/src/widgets/util/qsystemtrayicon.cpp
@@ -772,3 +772,4 @@ QT_END_NAMESPACE
#endif // QT_NO_SYSTEMTRAYICON
#include "moc_qsystemtrayicon.cpp"
+#include "moc_qsystemtrayicon_p.cpp"
diff --git a/src/widgets/util/qundogroup.cpp b/src/widgets/util/qundogroup.cpp
index c8623f44fe..ec4fc2788a 100644
--- a/src/widgets/util/qundogroup.cpp
+++ b/src/widgets/util/qundogroup.cpp
@@ -501,4 +501,6 @@ QAction *QUndoGroup::createRedoAction(QObject *parent, const QString &prefix) co
QT_END_NAMESPACE
+#include "moc_qundogroup.cpp"
+
#endif // QT_NO_UNDOGROUP
diff --git a/src/widgets/util/qundostack.cpp b/src/widgets/util/qundostack.cpp
index 6f733f99d5..7f6a56e0ec 100644
--- a/src/widgets/util/qundostack.cpp
+++ b/src/widgets/util/qundostack.cpp
@@ -1174,4 +1174,7 @@ bool QUndoStack::isActive() const
QT_END_NAMESPACE
+#include "moc_qundostack.cpp"
+#include "moc_qundostack_p.cpp"
+
#endif // QT_NO_UNDOSTACK
diff --git a/src/widgets/util/qundoview.cpp b/src/widgets/util/qundoview.cpp
index 9a89c42a3e..93c1778ea2 100644
--- a/src/widgets/util/qundoview.cpp
+++ b/src/widgets/util/qundoview.cpp
@@ -472,5 +472,6 @@ QIcon QUndoView::cleanIcon() const
QT_END_NAMESPACE
#include "qundoview.moc"
+#include "moc_qundoview.cpp"
#endif // QT_NO_UNDOVIEW
diff --git a/src/widgets/widgets/qabstractbutton.cpp b/src/widgets/widgets/qabstractbutton.cpp
index 9133664d77..44123d4dda 100644
--- a/src/widgets/widgets/qabstractbutton.cpp
+++ b/src/widgets/widgets/qabstractbutton.cpp
@@ -37,7 +37,9 @@
**
****************************************************************************/
-#include "qabstractbutton.h"
+#include "private/qabstractbutton_p.h"
+
+#include "private/qbuttongroup_p.h"
#include "qabstractitemview.h"
#include "qbuttongroup.h"
#include "qabstractbutton_p.h"
@@ -177,137 +179,6 @@ QAbstractButtonPrivate::QAbstractButtonPrivate(QSizePolicy::ControlType type)
controlType(type)
{}
-#ifndef QT_NO_BUTTONGROUP
-
-class QButtonGroupPrivate: public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QButtonGroup)
-
-public:
- QButtonGroupPrivate():exclusive(true){}
- QList<QAbstractButton *> buttonList;
- QPointer<QAbstractButton> checkedButton;
- void detectCheckedButton();
- void notifyChecked(QAbstractButton *button);
- bool exclusive;
- QHash<QAbstractButton*, int> mapping;
-};
-
-QButtonGroup::QButtonGroup(QObject *parent)
- : QObject(*new QButtonGroupPrivate, parent)
-{
-}
-
-QButtonGroup::~QButtonGroup()
-{
- Q_D(QButtonGroup);
- for (int i = 0; i < d->buttonList.count(); ++i)
- d->buttonList.at(i)->d_func()->group = 0;
-}
-
-
-bool QButtonGroup::exclusive() const
-{
- Q_D(const QButtonGroup);
- return d->exclusive;
-}
-
-void QButtonGroup::setExclusive(bool exclusive)
-{
- Q_D(QButtonGroup);
- d->exclusive = exclusive;
-}
-
-
-void QButtonGroup::addButton(QAbstractButton *button, int id)
-{
- Q_D(QButtonGroup);
- if (QButtonGroup *previous = button->d_func()->group)
- previous->removeButton(button);
- button->d_func()->group = this;
- d->buttonList.append(button);
- if (id == -1) {
- const QHash<QAbstractButton*, int>::const_iterator it
- = std::min_element(d->mapping.cbegin(), d->mapping.cend());
- if (it == d->mapping.cend())
- d->mapping[button] = -2;
- else
- d->mapping[button] = *it - 1;
- } else {
- d->mapping[button] = id;
- }
-
- if (d->exclusive && button->isChecked())
- button->d_func()->notifyChecked();
-}
-
-void QButtonGroup::removeButton(QAbstractButton *button)
-{
- Q_D(QButtonGroup);
- if (d->checkedButton == button) {
- d->detectCheckedButton();
- }
- if (button->d_func()->group == this) {
- button->d_func()->group = 0;
- d->buttonList.removeAll(button);
- d->mapping.remove(button);
- }
-}
-
-QList<QAbstractButton*> QButtonGroup::buttons() const
-{
- Q_D(const QButtonGroup);
- return d->buttonList;
-}
-
-QAbstractButton *QButtonGroup::checkedButton() const
-{
- Q_D(const QButtonGroup);
- return d->checkedButton;
-}
-
-QAbstractButton *QButtonGroup::button(int id) const
-{
- Q_D(const QButtonGroup);
- return d->mapping.key(id);
-}
-
-void QButtonGroup::setId(QAbstractButton *button, int id)
-{
- Q_D(QButtonGroup);
- if (button && id != -1)
- d->mapping[button] = id;
-}
-
-int QButtonGroup::id(QAbstractButton *button) const
-{
- Q_D(const QButtonGroup);
- return d->mapping.value(button, -1);
-}
-
-int QButtonGroup::checkedId() const
-{
- Q_D(const QButtonGroup);
- return d->mapping.value(d->checkedButton, -1);
-}
-
-// detect a checked button other than the current one
-void QButtonGroupPrivate::detectCheckedButton()
-{
- QAbstractButton *previous = checkedButton;
- checkedButton = 0;
- if (exclusive)
- return;
- for (int i = 0; i < buttonList.count(); i++) {
- if (buttonList.at(i) != previous && buttonList.at(i)->isChecked()) {
- checkedButton = buttonList.at(i);
- return;
- }
- }
-}
-
-#endif // QT_NO_BUTTONGROUP
-
QList<QAbstractButton *>QAbstractButtonPrivate::queryButtonList() const
{
#ifndef QT_NO_BUTTONGROUP
@@ -1419,3 +1290,5 @@ void QAbstractButton::setIconSize(const QSize &size)
QT_END_NAMESPACE
+
+#include "moc_qabstractbutton.cpp"
diff --git a/src/widgets/widgets/qabstractbutton_p.h b/src/widgets/widgets/qabstractbutton_p.h
index 416a9c4c83..f65a0527fc 100644
--- a/src/widgets/widgets/qabstractbutton_p.h
+++ b/src/widgets/widgets/qabstractbutton_p.h
@@ -51,6 +51,8 @@
// We mean it.
//
+#include "qabstractbutton.h"
+
#include "QtCore/qbasictimer.h"
#include "private/qwidget_p.h"
diff --git a/src/widgets/widgets/qabstractslider.cpp b/src/widgets/widgets/qabstractslider.cpp
index 13e7a6e5cf..8cd35495e9 100644
--- a/src/widgets/widgets/qabstractslider.cpp
+++ b/src/widgets/widgets/qabstractslider.cpp
@@ -962,3 +962,5 @@ void QAbstractSliderPrivate::itemviewChangeSingleStep(int step)
}
QT_END_NAMESPACE
+
+#include "moc_qabstractslider.cpp"
diff --git a/src/widgets/widgets/qbuttongroup.cpp b/src/widgets/widgets/qbuttongroup.cpp
index 7cc260a6f0..ef73fd1b67 100644
--- a/src/widgets/widgets/qbuttongroup.cpp
+++ b/src/widgets/widgets/qbuttongroup.cpp
@@ -37,7 +37,28 @@
**
****************************************************************************/
+#include "private/qbuttongroup_p.h"
+#ifndef QT_NO_BUTTONGROUP
+
+#include "private/qabstractbutton_p.h"
+
+QT_BEGIN_NAMESPACE
+
+// detect a checked button other than the current one
+void QButtonGroupPrivate::detectCheckedButton()
+{
+ QAbstractButton *previous = checkedButton;
+ checkedButton = 0;
+ if (exclusive)
+ return;
+ for (int i = 0; i < buttonList.count(); i++) {
+ if (buttonList.at(i) != previous && buttonList.at(i)->isChecked()) {
+ checkedButton = buttonList.at(i);
+ return;
+ }
+ }
+}
/*!
\class QButtonGroup
@@ -84,18 +105,24 @@
*/
/*!
- \fn QButtonGroup::QButtonGroup(QObject *parent)
-
Constructs a new, empty button group with the given \a parent.
\sa addButton(), setExclusive()
*/
+QButtonGroup::QButtonGroup(QObject *parent)
+ : QObject(*new QButtonGroupPrivate, parent)
+{
+}
/*!
- \fn QButtonGroup::~QButtonGroup()
-
Destroys the button group.
*/
+QButtonGroup::~QButtonGroup()
+{
+ Q_D(QButtonGroup);
+ for (int i = 0; i < d->buttonList.count(); ++i)
+ d->buttonList.at(i)->d_func()->group = 0;
+}
/*!
\property QButtonGroup::exclusive
@@ -111,6 +138,19 @@
By default, this property is \c true.
*/
+bool QButtonGroup::exclusive() const
+{
+ Q_D(const QButtonGroup);
+ return d->exclusive;
+}
+
+void QButtonGroup::setExclusive(bool exclusive)
+{
+ Q_D(QButtonGroup);
+ d->exclusive = exclusive;
+}
+
+
/*!
\fn void QButtonGroup::buttonClicked(QAbstractButton *button)
@@ -193,8 +233,6 @@
/*!
- \fn void QButtonGroup::addButton(QAbstractButton *button, int id = -1);
-
Adds the given \a button to the button group. If \a id is -1,
an id will be assigned to the button.
Automatically assigned ids are guaranteed to be negative,
@@ -203,42 +241,82 @@
\sa removeButton(), buttons()
*/
+void QButtonGroup::addButton(QAbstractButton *button, int id)
+{
+ Q_D(QButtonGroup);
+ if (QButtonGroup *previous = button->d_func()->group)
+ previous->removeButton(button);
+ button->d_func()->group = this;
+ d->buttonList.append(button);
+ if (id == -1) {
+ const QHash<QAbstractButton*, int>::const_iterator it
+ = std::min_element(d->mapping.cbegin(), d->mapping.cend());
+ if (it == d->mapping.cend())
+ d->mapping[button] = -2;
+ else
+ d->mapping[button] = *it - 1;
+ } else {
+ d->mapping[button] = id;
+ }
+
+ if (d->exclusive && button->isChecked())
+ button->d_func()->notifyChecked();
+}
/*!
- \fn void QButtonGroup::removeButton(QAbstractButton *button);
-
Removes the given \a button from the button group.
\sa addButton(), buttons()
*/
+void QButtonGroup::removeButton(QAbstractButton *button)
+{
+ Q_D(QButtonGroup);
+ if (d->checkedButton == button) {
+ d->detectCheckedButton();
+ }
+ if (button->d_func()->group == this) {
+ button->d_func()->group = 0;
+ d->buttonList.removeAll(button);
+ d->mapping.remove(button);
+ }
+}
/*!
- \fn QList<QAbstractButton*> QButtonGroup::buttons() const
-
Returns the button group's list of buttons. This may be empty.
\sa addButton(), removeButton()
*/
+QList<QAbstractButton*> QButtonGroup::buttons() const
+{
+ Q_D(const QButtonGroup);
+ return d->buttonList;
+}
/*!
- \fn QAbstractButton *QButtonGroup::checkedButton() const;
-
Returns the button group's checked button, or 0 if no buttons are
checked.
\sa buttonClicked()
*/
+QAbstractButton *QButtonGroup::checkedButton() const
+{
+ Q_D(const QButtonGroup);
+ return d->checkedButton;
+}
/*!
- \fn QAbstractButton *QButtonGroup::button(int id) const;
\since 4.1
Returns the button with the specified \a id, or 0 if no such button
exists.
*/
+QAbstractButton *QButtonGroup::button(int id) const
+{
+ Q_D(const QButtonGroup);
+ return d->mapping.key(id);
+}
/*!
- \fn void QButtonGroup::setId(QAbstractButton *button, int id)
\since 4.1
Sets the \a id for the specified \a button. Note that \a id cannot
@@ -246,9 +324,14 @@
\sa id()
*/
+void QButtonGroup::setId(QAbstractButton *button, int id)
+{
+ Q_D(QButtonGroup);
+ if (button && id != -1)
+ d->mapping[button] = id;
+}
/*!
- \fn int QButtonGroup::id(QAbstractButton *button) const;
\since 4.1
Returns the id for the specified \a button, or -1 if no such button
@@ -257,13 +340,27 @@
\sa setId()
*/
+int QButtonGroup::id(QAbstractButton *button) const
+{
+ Q_D(const QButtonGroup);
+ return d->mapping.value(button, -1);
+}
/*!
- \fn int QButtonGroup::checkedId() const;
\since 4.1
Returns the id of the checkedButton(), or -1 if no button is checked.
\sa setId()
*/
+int QButtonGroup::checkedId() const
+{
+ Q_D(const QButtonGroup);
+ return d->mapping.value(d->checkedButton, -1);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qbuttongroup.cpp"
+#endif // QT_NO_BUTTONGROUP
diff --git a/src/widgets/widgets/qbuttongroup_p.h b/src/widgets/widgets/qbuttongroup_p.h
new file mode 100644
index 0000000000..01c0367876
--- /dev/null
+++ b/src/widgets/widgets/qbuttongroup_p.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWidgets module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBUTTONGROUP_P_H
+#define QBUTTONGROUP_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtWidgets/qbuttongroup.h>
+
+#ifndef QT_NO_BUTTONGROUP
+
+#include <QtCore/private/qobject_p.h>
+
+#include <QtCore/qlist.h>
+#include <QtCore/qpointer.h>
+#include <QtCore/qhash.h>
+
+QT_BEGIN_NAMESPACE
+
+class QButtonGroupPrivate: public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QButtonGroup)
+
+public:
+ QButtonGroupPrivate() : exclusive(true) {}
+
+ QList<QAbstractButton *> buttonList;
+ QPointer<QAbstractButton> checkedButton;
+ void detectCheckedButton();
+ void notifyChecked(QAbstractButton *button);
+
+ bool exclusive;
+ QHash<QAbstractButton*, int> mapping;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_BUTTONGROUP
+
+#endif // QBUTTONGROUP_P_H
diff --git a/src/widgets/widgets/qcheckbox.cpp b/src/widgets/widgets/qcheckbox.cpp
index ad2d019c4a..19369d6cb1 100644
--- a/src/widgets/widgets/qcheckbox.cpp
+++ b/src/widgets/widgets/qcheckbox.cpp
@@ -390,3 +390,5 @@ bool QCheckBox::event(QEvent *e)
QT_END_NAMESPACE
+
+#include "moc_qcheckbox.cpp"
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index 1cf7591302..08c8117e0b 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -3440,5 +3440,6 @@ void QComboBox::setModelColumn(int visibleColumn)
QT_END_NAMESPACE
#include "moc_qcombobox.cpp"
+#include "moc_qcombobox_p.cpp"
#endif // QT_NO_COMBOBOX
diff --git a/src/widgets/widgets/qcommandlinkbutton.cpp b/src/widgets/widgets/qcommandlinkbutton.cpp
index 4d43c999bf..2ec8b1c41a 100644
--- a/src/widgets/widgets/qcommandlinkbutton.cpp
+++ b/src/widgets/widgets/qcommandlinkbutton.cpp
@@ -413,3 +413,4 @@ QString QCommandLinkButton::description() const
QT_END_NAMESPACE
+#include "moc_qcommandlinkbutton.cpp"
diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp
index c3f9198598..f72dc088da 100644
--- a/src/widgets/widgets/qdatetimeedit.cpp
+++ b/src/widgets/widgets/qdatetimeedit.cpp
@@ -2692,5 +2692,6 @@ void QCalendarPopup::hideEvent(QHideEvent *)
QT_END_NAMESPACE
#include "moc_qdatetimeedit.cpp"
+#include "moc_qdatetimeedit_p.cpp"
#endif // QT_NO_DATETIMEEDIT
diff --git a/src/widgets/widgets/qdial.cpp b/src/widgets/widgets/qdial.cpp
index 40c7e98726..cee39e2ae3 100644
--- a/src/widgets/widgets/qdial.cpp
+++ b/src/widgets/widgets/qdial.cpp
@@ -487,4 +487,6 @@ bool QDial::event(QEvent *e)
QT_END_NAMESPACE
+#include "moc_qdial.cpp"
+
#endif // QT_NO_DIAL
diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp
index 03faca157f..293a04ef88 100644
--- a/src/widgets/widgets/qdockwidget.cpp
+++ b/src/widgets/widgets/qdockwidget.cpp
@@ -1682,5 +1682,6 @@ QT_END_NAMESPACE
#include "qdockwidget.moc"
#include "moc_qdockwidget.cpp"
+#include "moc_qdockwidget_p.cpp"
#endif // QT_NO_DOCKWIDGET
diff --git a/src/widgets/widgets/qfocusframe.cpp b/src/widgets/widgets/qfocusframe.cpp
index 6704631afc..8b8f4db86e 100644
--- a/src/widgets/widgets/qfocusframe.cpp
+++ b/src/widgets/widgets/qfocusframe.cpp
@@ -339,3 +339,5 @@ bool QFocusFrame::event(QEvent *e)
}
QT_END_NAMESPACE
+
+#include "moc_qfocusframe.cpp"
diff --git a/src/widgets/widgets/qframe.cpp b/src/widgets/widgets/qframe.cpp
index 96a2e76713..1661c5c881 100644
--- a/src/widgets/widgets/qframe.cpp
+++ b/src/widgets/widgets/qframe.cpp
@@ -555,3 +555,5 @@ bool QFrame::event(QEvent *e)
}
QT_END_NAMESPACE
+
+#include "moc_qframe.cpp"
diff --git a/src/widgets/widgets/qkeysequenceedit.cpp b/src/widgets/widgets/qkeysequenceedit.cpp
index a663c4f853..f8a3be366e 100644
--- a/src/widgets/widgets/qkeysequenceedit.cpp
+++ b/src/widgets/widgets/qkeysequenceedit.cpp
@@ -324,3 +324,5 @@ void QKeySequenceEdit::timerEvent(QTimerEvent *e)
#endif // QT_NO_KEYSEQUENCEEDIT
QT_END_NAMESPACE
+
+#include "moc_qkeysequenceedit.cpp"
diff --git a/src/widgets/widgets/qlcdnumber.cpp b/src/widgets/widgets/qlcdnumber.cpp
index cc1fc20379..543a7aee11 100644
--- a/src/widgets/widgets/qlcdnumber.cpp
+++ b/src/widgets/widgets/qlcdnumber.cpp
@@ -1222,4 +1222,6 @@ bool QLCDNumber::event(QEvent *e)
QT_END_NAMESPACE
+#include "moc_qlcdnumber.cpp"
+
#endif // QT_NO_LCDNUMBER
diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp
index b646e82209..b852b8991c 100644
--- a/src/widgets/widgets/qlineedit_p.cpp
+++ b/src/widgets/widgets/qlineedit_p.cpp
@@ -553,4 +553,6 @@ int QLineEditPrivate::effectiveRightTextMargin() const
QT_END_NAMESPACE
+#include "moc_qlineedit_p.cpp"
+
#endif
diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp
index 4ee22dc235..f86244172d 100644
--- a/src/widgets/widgets/qmainwindow.cpp
+++ b/src/widgets/widgets/qmainwindow.cpp
@@ -1746,4 +1746,6 @@ QMenu *QMainWindow::createPopupMenu()
QT_END_NAMESPACE
+#include "moc_qmainwindow.cpp"
+
#endif // QT_NO_MAINWINDOW
diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp
index 99c32e9acc..6c05887705 100644
--- a/src/widgets/widgets/qmainwindowlayout.cpp
+++ b/src/widgets/widgets/qmainwindowlayout.cpp
@@ -2604,4 +2604,6 @@ void QMainWindowLayout::timerEvent(QTimerEvent *e)
QT_END_NAMESPACE
+#include "moc_qmainwindowlayout_p.cpp"
+
#endif // QT_NO_MAINWINDOW
diff --git a/src/widgets/widgets/qprogressbar.cpp b/src/widgets/widgets/qprogressbar.cpp
index 2897929a14..1ba0d78622 100644
--- a/src/widgets/widgets/qprogressbar.cpp
+++ b/src/widgets/widgets/qprogressbar.cpp
@@ -629,4 +629,6 @@ QString QProgressBar::format() const
QT_END_NAMESPACE
+#include "moc_qprogressbar.cpp"
+
#endif // QT_NO_PROGRESSBAR
diff --git a/src/widgets/widgets/qradiobutton.cpp b/src/widgets/widgets/qradiobutton.cpp
index 125182f79f..55a584078a 100644
--- a/src/widgets/widgets/qradiobutton.cpp
+++ b/src/widgets/widgets/qradiobutton.cpp
@@ -269,3 +269,5 @@ bool QRadioButton::event(QEvent *e)
QT_END_NAMESPACE
+
+#include "moc_qradiobutton.cpp"
diff --git a/src/widgets/widgets/qrubberband.cpp b/src/widgets/widgets/qrubberband.cpp
index 048817d07b..13aa66dec7 100644
--- a/src/widgets/widgets/qrubberband.cpp
+++ b/src/widgets/widgets/qrubberband.cpp
@@ -333,4 +333,6 @@ bool QRubberBand::event(QEvent *e)
QT_END_NAMESPACE
+#include "moc_qrubberband.cpp"
+
#endif // QT_NO_RUBBERBAND
diff --git a/src/widgets/widgets/qscrollarea.cpp b/src/widgets/widgets/qscrollarea.cpp
index bd07040509..0868dcbd69 100644
--- a/src/widgets/widgets/qscrollarea.cpp
+++ b/src/widgets/widgets/qscrollarea.cpp
@@ -538,4 +538,6 @@ Qt::Alignment QScrollArea::alignment() const
QT_END_NAMESPACE
+#include "moc_qscrollarea.cpp"
+
#endif // QT_NO_SCROLLAREA
diff --git a/src/widgets/widgets/qscrollbar.cpp b/src/widgets/widgets/qscrollbar.cpp
index 7399601c2e..7dd41f6a0c 100644
--- a/src/widgets/widgets/qscrollbar.cpp
+++ b/src/widgets/widgets/qscrollbar.cpp
@@ -744,4 +744,6 @@ Q_WIDGETS_EXPORT QStyleOptionSlider qt_qscrollbarStyleOption(QScrollBar *scrollb
QT_END_NAMESPACE
+#include "moc_qscrollbar.cpp"
+
#endif // QT_NO_SCROLLBAR
diff --git a/src/widgets/widgets/qslider.cpp b/src/widgets/widgets/qslider.cpp
index bf27b19940..7b675fccbd 100644
--- a/src/widgets/widgets/qslider.cpp
+++ b/src/widgets/widgets/qslider.cpp
@@ -559,3 +559,5 @@ Q_WIDGETS_EXPORT QStyleOptionSlider qt_qsliderStyleOption(QSlider *slider)
#endif
QT_END_NAMESPACE
+
+#include "moc_qslider.cpp"
diff --git a/src/widgets/widgets/qspinbox.cpp b/src/widgets/widgets/qspinbox.cpp
index 68b405cc5e..a5c096c3a8 100644
--- a/src/widgets/widgets/qspinbox.cpp
+++ b/src/widgets/widgets/qspinbox.cpp
@@ -1328,4 +1328,6 @@ bool QSpinBox::event(QEvent *event)
QT_END_NAMESPACE
+#include "moc_qspinbox.cpp"
+
#endif // QT_NO_SPINBOX
diff --git a/src/widgets/widgets/qsplashscreen.cpp b/src/widgets/widgets/qsplashscreen.cpp
index b379e01b0a..4ad2b83582 100644
--- a/src/widgets/widgets/qsplashscreen.cpp
+++ b/src/widgets/widgets/qsplashscreen.cpp
@@ -358,4 +358,6 @@ bool QSplashScreen::event(QEvent *e)
QT_END_NAMESPACE
+#include "moc_qsplashscreen.cpp"
+
#endif //QT_NO_SPLASHSCREEN
diff --git a/src/widgets/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp
index 9ebd232bef..e3ca6b0a79 100644
--- a/src/widgets/widgets/qsplitter.cpp
+++ b/src/widgets/widgets/qsplitter.cpp
@@ -1739,4 +1739,6 @@ QTextStream& operator>>(QTextStream& ts, QSplitter& splitter)
QT_END_NAMESPACE
+#include "moc_qsplitter.cpp"
+
#endif // QT_NO_SPLITTER
diff --git a/src/widgets/widgets/qstackedwidget.cpp b/src/widgets/widgets/qstackedwidget.cpp
index 097f98fd71..38ce182fbf 100644
--- a/src/widgets/widgets/qstackedwidget.cpp
+++ b/src/widgets/widgets/qstackedwidget.cpp
@@ -293,4 +293,6 @@ bool QStackedWidget::event(QEvent *e)
QT_END_NAMESPACE
+#include "moc_qstackedwidget.cpp"
+
#endif // QT_NO_STACKEDWIDGET
diff --git a/src/widgets/widgets/qstatusbar.cpp b/src/widgets/widgets/qstatusbar.cpp
index 2e1cd29839..7de1d92acf 100644
--- a/src/widgets/widgets/qstatusbar.cpp
+++ b/src/widgets/widgets/qstatusbar.cpp
@@ -789,4 +789,6 @@ bool QStatusBar::event(QEvent *e)
QT_END_NAMESPACE
+#include "moc_qstatusbar.cpp"
+
#endif
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp
index ba3fc2fcd7..f56830c14b 100644
--- a/src/widgets/widgets/qtabbar.cpp
+++ b/src/widgets/widgets/qtabbar.cpp
@@ -2583,4 +2583,4 @@ QT_END_NAMESPACE
#endif // QT_NO_TABBAR
-
+#include "moc_qtabbar_p.cpp"
diff --git a/src/widgets/widgets/qtoolbarextension.cpp b/src/widgets/widgets/qtoolbarextension.cpp
index 71061c8102..267e220b8f 100644
--- a/src/widgets/widgets/qtoolbarextension.cpp
+++ b/src/widgets/widgets/qtoolbarextension.cpp
@@ -87,4 +87,6 @@ QSize QToolBarExtension::sizeHint() const
QT_END_NAMESPACE
+#include "moc_qtoolbarextension_p.cpp"
+
#endif // QT_NO_TOOLBUTTON
diff --git a/src/widgets/widgets/qtoolbarextension_p.h b/src/widgets/widgets/qtoolbarextension_p.h
index e8725d77b8..ea159ce986 100644
--- a/src/widgets/widgets/qtoolbarextension_p.h
+++ b/src/widgets/widgets/qtoolbarextension_p.h
@@ -60,7 +60,6 @@ QT_BEGIN_NAMESPACE
class Q_AUTOTEST_EXPORT QToolBarExtension : public QToolButton
{
Q_OBJECT
- Qt::Orientation orientation;
public:
explicit QToolBarExtension(QWidget *parent);
diff --git a/src/widgets/widgets/qtoolbarlayout.cpp b/src/widgets/widgets/qtoolbarlayout.cpp
index 2d7ab68dde..79174bdbff 100644
--- a/src/widgets/widgets/qtoolbarlayout.cpp
+++ b/src/widgets/widgets/qtoolbarlayout.cpp
@@ -748,4 +748,6 @@ QToolBarItem *QToolBarLayout::createItem(QAction *action)
QT_END_NAMESPACE
+#include "moc_qtoolbarlayout_p.cpp"
+
#endif // QT_NO_TOOLBAR
diff --git a/src/widgets/widgets/qtoolbarseparator.cpp b/src/widgets/widgets/qtoolbarseparator.cpp
index 57997556a5..c99a8bcc4c 100644
--- a/src/widgets/widgets/qtoolbarseparator.cpp
+++ b/src/widgets/widgets/qtoolbarseparator.cpp
@@ -86,4 +86,6 @@ void QToolBarSeparator::paintEvent(QPaintEvent *)
QT_END_NAMESPACE
+#include "moc_qtoolbarseparator_p.cpp"
+
#endif // QT_NO_TOOLBAR
diff --git a/src/widgets/widgets/qwidgetanimator.cpp b/src/widgets/widgets/qwidgetanimator.cpp
index edf0b32ba0..d46d65546c 100644
--- a/src/widgets/widgets/qwidgetanimator.cpp
+++ b/src/widgets/widgets/qwidgetanimator.cpp
@@ -120,3 +120,5 @@ bool QWidgetAnimator::animating() const
}
QT_END_NAMESPACE
+
+#include "moc_qwidgetanimator_p.cpp"
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
index f9674668ec..a77794df8a 100644
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -1924,4 +1924,6 @@ bool QWidgetLineControl::isRedoAvailable() const
QT_END_NAMESPACE
+#include "moc_qwidgetlinecontrol_p.cpp"
+
#endif
diff --git a/src/widgets/widgets/qwidgetresizehandler.cpp b/src/widgets/widgets/qwidgetresizehandler.cpp
index 11bfc38b0d..2a7b1eeecc 100644
--- a/src/widgets/widgets/qwidgetresizehandler.cpp
+++ b/src/widgets/widgets/qwidgetresizehandler.cpp
@@ -541,4 +541,6 @@ void QWidgetResizeHandler::doMove()
QT_END_NAMESPACE
+#include "moc_qwidgetresizehandler_p.cpp"
+
#endif //QT_NO_RESIZEHANDLER
diff --git a/src/widgets/widgets/widgets.pri b/src/widgets/widgets/widgets.pri
index c31a7f7682..784055ed62 100644
--- a/src/widgets/widgets/widgets.pri
+++ b/src/widgets/widgets/widgets.pri
@@ -2,6 +2,7 @@
HEADERS += \
widgets/qbuttongroup.h \
+ widgets/qbuttongroup_p.h \
widgets/qabstractbutton.h \
widgets/qabstractbutton_p.h \
widgets/qabstractslider.h \
@@ -84,6 +85,7 @@ HEADERS += \
widgets/qplaintextedit_p.h
SOURCES += \
+ widgets/qbuttongroup.cpp \
widgets/qabstractbutton.cpp \
widgets/qabstractslider.cpp \
widgets/qabstractspinbox.cpp \
diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt
index 5248f75a84..1abbef0d68 100644
--- a/tests/auto/cmake/CMakeLists.txt
+++ b/tests/auto/cmake/CMakeLists.txt
@@ -68,6 +68,24 @@ expect_fail(test_wrap_cpp_options)
expect_pass(test_platform_defs_include)
expect_pass(test_qtmainwin_library)
+if (HAVE_NINJA)
+ make_directory("${CMAKE_CURRENT_SOURCE_DIR}/test_QFINDTESTDATA/build")
+ add_test(test_QFINDTESTDATA ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMAKE_CURRENT_SOURCE_DIR}/test_QFINDTESTDATA"
+ # Build in a subdir of the source dir.
+ # This causes Ninja to use relative paths.
+ "${CMAKE_CURRENT_SOURCE_DIR}/test_QFINDTESTDATA/build"
+ --build-generator Ninja
+ --build-options "-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}"
+ )
+ add_test(NAME run_test_QFINDTESTDATA COMMAND sh -c "cd \"${CMAKE_SOURCE_DIR}/test_QFINDTESTDATA/build/tests\" && ./test_QFINDTESTDATA -v2")
+
+ set_property(TEST run_test_QFINDTESTDATA
+ PROPERTY DEPENDS test_QFINDTESTDATA
+ )
+endif()
+
if (NOT NO_DBUS)
expect_pass(test_dbus_module)
endif()
diff --git a/tests/auto/cmake/test_QFINDTESTDATA/CMakeLists.txt b/tests/auto/cmake/test_QFINDTESTDATA/CMakeLists.txt
new file mode 100644
index 0000000000..e56c3c5eb9
--- /dev/null
+++ b/tests/auto/cmake/test_QFINDTESTDATA/CMakeLists.txt
@@ -0,0 +1,11 @@
+
+cmake_minimum_required(VERSION 2.8.11)
+
+project(test_QFINDTESTDATA)
+
+find_package(Qt5Test REQUIRED)
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_subdirectory(tests)
diff --git a/tests/auto/cmake/test_QFINDTESTDATA/tests/CMakeLists.txt b/tests/auto/cmake/test_QFINDTESTDATA/tests/CMakeLists.txt
new file mode 100644
index 0000000000..dfe321982a
--- /dev/null
+++ b/tests/auto/cmake/test_QFINDTESTDATA/tests/CMakeLists.txt
@@ -0,0 +1,4 @@
+
+add_executable(test_QFINDTESTDATA WIN32 main.cpp)
+
+target_link_libraries(test_QFINDTESTDATA Qt5::Test)
diff --git a/tests/auto/cmake/test_QFINDTESTDATA/tests/main.cpp b/tests/auto/cmake/test_QFINDTESTDATA/tests/main.cpp
new file mode 100644
index 0000000000..0a5b6acd32
--- /dev/null
+++ b/tests/auto/cmake/test_QFINDTESTDATA/tests/main.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Stephen Kelly <steveire@gmail,com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QCoreApplication>
+#include <QtTest/QTest>
+
+class TestClass : public QObject
+{
+ Q_OBJECT
+public:
+ TestClass(QObject* parent = 0) {}
+
+private slots:
+ void doTest();
+};
+
+void TestClass::doTest()
+{
+ QFile f(QFINDTESTDATA("testdata.txt"));
+ QVERIFY(f.open(QFile::ReadOnly));
+ QCOMPARE(f.readAll().trimmed(), QByteArrayLiteral("This is a test."));
+}
+
+QTEST_MAIN(TestClass)
+#include "main.moc"
diff --git a/tests/auto/cmake/test_QFINDTESTDATA/tests/testdata.txt b/tests/auto/cmake/test_QFINDTESTDATA/tests/testdata.txt
new file mode 100644
index 0000000000..484ba93ef5
--- /dev/null
+++ b/tests/auto/cmake/test_QFINDTESTDATA/tests/testdata.txt
@@ -0,0 +1 @@
+This is a test.
diff --git a/tests/auto/corelib/io/qtextstream/test/test.pro b/tests/auto/corelib/io/qtextstream/test/test.pro
index 93fb6d232f..50335524d3 100644
--- a/tests/auto/corelib/io/qtextstream/test/test.pro
+++ b/tests/auto/corelib/io/qtextstream/test/test.pro
@@ -19,3 +19,7 @@ TESTDATA += \
../qtextstream.qrc \
../tst_qtextstream.cpp \
../resources
+
+builtin_testdata {
+ DEFINES += BUILTIN_TESTDATA
+}
diff --git a/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp b/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp
index 2852420557..104873b85e 100644
--- a/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp
+++ b/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp
@@ -60,6 +60,7 @@ public:
public slots:
void initTestCase();
void cleanup();
+ void cleanupTestCase();
private slots:
void getSetCheck();
@@ -236,6 +237,9 @@ private:
QTemporaryDir tempDir;
QString testFileName;
+#ifdef BUILTIN_TESTDATA
+ QSharedPointer<QTemporaryDir> m_dataDir;
+#endif
const QString m_rfc3261FilePath;
const QString m_shiftJisFilePath;
};
@@ -262,9 +266,14 @@ void tst_QTextStream::initTestCase()
testFileName = tempDir.path() + "/testfile";
+#ifdef BUILTIN_TESTDATA
+ m_dataDir = QEXTRACTTESTDATA("/");
+ QVERIFY2(QDir::setCurrent(m_dataDir->path()), qPrintable("Could not chdir to " + m_dataDir->path()));
+#else
// chdir into the testdata dir and refer to our helper apps with relative paths
QString testdata_dir = QFileInfo(QFINDTESTDATA("stdinProcess")).absolutePath();
QVERIFY2(QDir::setCurrent(testdata_dir), qPrintable("Could not chdir to " + testdata_dir));
+#endif
}
// Testing get/set functions
@@ -387,6 +396,13 @@ void tst_QTextStream::cleanup()
QCoreApplication::instance()->processEvents();
}
+void tst_QTextStream::cleanupTestCase()
+{
+#ifdef BUILTIN_TESTDATA
+ QDir::setCurrent(QCoreApplication::applicationDirPath());
+#endif
+}
+
// ------------------------------------------------------------------------------
void tst_QTextStream::construction()
{
@@ -3044,12 +3060,10 @@ void tst_QTextStream::int_write_with_locale()
void tst_QTextStream::textModeOnEmptyRead()
{
- const QString filename("textmodetest.txt");
- QFile::remove(filename); // Remove file if exists
-
+ const QString filename(tempDir.path() + QLatin1String("/textmodetest.txt"));
QFile file(filename);
- QVERIFY(file.open(QIODevice::ReadWrite | QIODevice::Text));
+ QVERIFY2(file.open(QIODevice::ReadWrite | QIODevice::Text), qPrintable(file.errorString()));
QTextStream stream(&file);
QVERIFY(file.isTextModeEnabled());
QString emptyLine = stream.readLine(); // Text mode flag cleared here
diff --git a/tests/auto/corelib/plugin/plugin.pro b/tests/auto/corelib/plugin/plugin.pro
index e6b748e4f4..777e920995 100644
--- a/tests/auto/corelib/plugin/plugin.pro
+++ b/tests/auto/corelib/plugin/plugin.pro
@@ -8,3 +8,9 @@ load(qfeatures)
qpluginloader \
qplugin \
qlibrary
+
+contains(CONFIG, static) {
+ message(Disabling tests requiring shared build of Qt)
+ SUBDIRS -= qfactoryloader \
+ qpluginloader
+}
diff --git a/tests/auto/corelib/tools/qrect/tst_qrect.cpp b/tests/auto/corelib/tools/qrect/tst_qrect.cpp
index 9b35cdec30..d3c6412b0d 100644
--- a/tests/auto/corelib/tools/qrect/tst_qrect.cpp
+++ b/tests/auto/corelib/tools/qrect/tst_qrect.cpp
@@ -2347,7 +2347,7 @@ void tst_QRect::center_data()
QTest::newRow( "SmallestQRect" ) << getQRectCase( SmallestQRect ) << QPoint(1,1);
QTest::newRow( "MiddleQRect" ) << getQRectCase( MiddleQRect ) << QPoint(0,0);
QTest::newRow( "LargestQRect" ) << getQRectCase( LargestQRect ) << QPoint(INT_MAX/2,INT_MAX/2);
- QTest::newRow( "SmallestCoordQRect" ) << getQRectCase( SmallestCoordQRect ) << QPoint(0,0);
+ QTest::newRow( "SmallestCoordQRect" ) << getQRectCase( SmallestCoordQRect ) << QPoint(INT_MIN, INT_MIN);
QTest::newRow( "LargestCoordQRect" ) << getQRectCase( LargestCoordQRect ) << QPoint(0,0);
QTest::newRow( "RandomQRect" ) << getQRectCase( RandomQRect ) << QPoint(105,207);
QTest::newRow( "NegativeSizeQRect" ) << getQRectCase( NegativeSizeQRect ) << QPoint(-4,-4);
@@ -3169,8 +3169,7 @@ void tst_QRect::newMoveTopLeft_data()
}
{
- QTest::newRow("LargestCoordQRect_NullQPoint") << getQRectCase(LargestCoordQRect) << getQPointCase(NullQPoint)
- << QRect(QPoint(0,0), QPoint(INT_MAX+(0-INT_MIN),INT_MAX+(0-INT_MIN)));
+ // QTest::newRow("LargestCoordQRect_NullQPoint") -- Not tested as it would cause an overflow
QTest::newRow("LargestCoordQRect_SmallestCoordQPoint") << getQRectCase(LargestCoordQRect) << getQPointCase(SmallestCoordQPoint)
<< QRect(QPoint(INT_MIN,INT_MIN), QPoint(INT_MAX,INT_MAX));
// QTest::newRow("LargestCoordQRect_MiddleNegCoordQPoint") -- Not tested as it would cause an overflow
diff --git a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp
index 1879543581..077a6a20f1 100644
--- a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp
+++ b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp
@@ -893,7 +893,7 @@ void tst_QTimeZone::macTest()
void tst_QTimeZone::winTest()
{
-#if defined(QT_BUILD_INTERNAL) && defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(QT_BUILD_INTERNAL) && defined(Q_OS_WIN)
// Known datetimes
qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
diff --git a/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp b/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp
index b889bcc6a9..8a153a4599 100644
--- a/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp
+++ b/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp
@@ -902,7 +902,8 @@ void tst_QXmlStream::testFalsePrematureError() const
// Regression test for crash due to using empty QStack.
void tst_QXmlStream::writerHangs() const
{
- QFile file("test.xml");
+ QTemporaryDir dir(QDir::tempPath() + QLatin1String("/tst_qxmlstream.XXXXXX"));
+ QFile file(dir.path() + "/test.xml");
QVERIFY(file.open(QIODevice::WriteOnly));
diff --git a/tests/auto/gui/text/qstatictext/qstatictext.pro b/tests/auto/gui/text/qstatictext/qstatictext.pro
index 002cead51d..0f4906ce4d 100644
--- a/tests/auto/gui/text/qstatictext/qstatictext.pro
+++ b/tests/auto/gui/text/qstatictext/qstatictext.pro
@@ -1,5 +1,7 @@
CONFIG += testcase
TARGET = tst_qstatictext
QT += testlib
-QT += core-private gui-private
+
SOURCES += tst_qstatictext.cpp
+
+contains(QT_CONFIG, private_tests): QT += core-private gui-private
diff --git a/tests/auto/gui/text/qstatictext/tst_qstatictext.cpp b/tests/auto/gui/text/qstatictext/tst_qstatictext.cpp
index 096b820004..ec30cc8b67 100644
--- a/tests/auto/gui/text/qstatictext/tst_qstatictext.cpp
+++ b/tests/auto/gui/text/qstatictext/tst_qstatictext.cpp
@@ -34,7 +34,9 @@
#include <qstatictext.h>
#include <qpaintengine.h>
+#ifdef QT_BUILD_INTERNAL
#include <private/qstatictext_p.h>
+#endif
// #define DEBUG_SAVE_IMAGE
@@ -89,8 +91,10 @@ private slots:
void unprintableCharacter_qtbug12614();
+#ifdef QT_BUILD_INTERNAL
void underlinedColor_qtbug20159();
void textDocumentColor();
+#endif
private:
bool supportsTransformations() const;
@@ -811,6 +815,7 @@ void tst_QStaticText::unprintableCharacter_qtbug12614()
QVERIFY(staticText.size().isValid()); // Force layout. Should not crash.
}
+#ifdef QT_BUILD_INTERNAL
void tst_QStaticText::underlinedColor_qtbug20159()
{
QString multiScriptText;
@@ -847,6 +852,7 @@ void tst_QStaticText::textDocumentColor()
QCOMPARE(d->items[1].color, QColor(Qt::red));
}
+#endif
QTEST_MAIN(tst_QStaticText)
#include "tst_qstatictext.moc"
diff --git a/tests/auto/gui/text/text.pro b/tests/auto/gui/text/text.pro
index 6c0def4d63..dc67794a98 100644
--- a/tests/auto/gui/text/text.pro
+++ b/tests/auto/gui/text/text.pro
@@ -30,6 +30,5 @@ win32:SUBDIRS -= qtextpiecetable
!contains(QT_CONFIG, private_tests): SUBDIRS -= \
qfontcache \
qcssparser \
- qstatictext \
qtextlayout \
qtextpiecetable \
diff --git a/tests/auto/network/socket/qlocalsocket/BLACKLIST b/tests/auto/network/socket/qlocalsocket/BLACKLIST
deleted file mode 100644
index 11ddef30a5..0000000000
--- a/tests/auto/network/socket/qlocalsocket/BLACKLIST
+++ /dev/null
@@ -1,2 +0,0 @@
-[processConnection:1 client]
-windows
diff --git a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp
index ef47b45e9e..123fbfeb2a 100644
--- a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp
+++ b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp
@@ -517,6 +517,7 @@ void tst_QLocalSocket::sendData()
// test creating a connection
socket.connectToServer(name);
bool timedOut = true;
+ int expectedReadyReadSignals = 0;
QCOMPARE(server.waitForNewConnection(3000, &timedOut), canListen);
@@ -540,15 +541,17 @@ void tst_QLocalSocket::sendData()
out << testLine << endl;
bool wrote = serverSocket->waitForBytesWritten(3000);
- if (!socket.canReadLine())
+ if (!socket.canReadLine()) {
+ expectedReadyReadSignals = 1;
QVERIFY(socket.waitForReadyRead());
+ }
QVERIFY(socket.bytesAvailable() >= 0);
QCOMPARE(socket.bytesToWrite(), (qint64)0);
QCOMPARE(socket.flush(), false);
QCOMPARE(socket.isValid(), canListen);
QCOMPARE(socket.readBufferSize(), (qint64)0);
- QCOMPARE(spyReadyRead.count(), 1);
+ QCOMPARE(spyReadyRead.count(), expectedReadyReadSignals);
QVERIFY(testLine.startsWith(in.readLine()));
@@ -563,7 +566,7 @@ void tst_QLocalSocket::sendData()
QCOMPARE(spyDisconnected.count(), canListen ? 1 : 0);
QCOMPARE(spyError.count(), canListen ? 0 : 1);
QCOMPARE(spyStateChanged.count(), canListen ? 4 : 2);
- QCOMPARE(spyReadyRead.count(), canListen ? 1 : 0);
+ QCOMPARE(spyReadyRead.count(), canListen ? expectedReadyReadSignals : 0);
server.close();
diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
index 64e123309d..be3a86f4de 100644
--- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
+++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
@@ -1748,24 +1748,6 @@ void tst_QSqlQuery::synonyms()
QCOMPARE( rec.field( 2 ).name().toLower(), QString( "t_varchar" ) );
}
-// This class is used to test protected QSqlResult methods
-class ResultHelper: public QSqlResult
-{
-
-public:
- ResultHelper(): QSqlResult( 0 ) {} // don't call, it's only for stupid compilers
-
- bool execBatch( bool bindArray = false )
- {
- return QSqlResult::execBatch( bindArray );
- }
-
- QString boundValueName( int pos ) const
- {
- return QSqlResult::boundValueName( pos );
- }
-};
-
// It doesn't make sense to split this into several tests
void tst_QSqlQuery::prepare_bind_exec()
{
@@ -1890,81 +1872,81 @@ void tst_QSqlQuery::prepare_bind_exec()
q.bindValue( 0, 0 );
q.bindValue( 1, values[ 0 ] );
QCOMPARE( q.boundValues().size(), 2 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 0 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[0] );
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 0);
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[0]);
QVERIFY_SQL( q, exec() );
QCOMPARE( q.boundValues().size(), 2 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 0 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[0] );
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 0);
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[0]);
q.addBindValue( 1 );
q.addBindValue( values[ 1 ] );
QCOMPARE( q.boundValues().size(), 2 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 1 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[1] );
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 1);
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[1]);
QVERIFY_SQL( q, exec() );
QCOMPARE( q.boundValues().size(), 2 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 1 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[1] );
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 1);
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[1]);
q.addBindValue( 2 );
q.addBindValue( values[ 2 ] );
QCOMPARE( q.boundValues().size(), 2 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 2 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[2] );
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 2);
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[2]);
QVERIFY_SQL( q, exec() );
QCOMPARE( q.boundValues().size(), 2 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 2 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[2] );
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 2);
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[2]);
q.addBindValue( 3 );
q.addBindValue( values[ 3 ] );
QCOMPARE( q.boundValues().size(), 2 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 3 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[3] );
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 3);
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[3]);
QVERIFY_SQL( q, exec() );
QCOMPARE( q.boundValues().size(), 2 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 3 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[3] );
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 3);
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[3]);
q.addBindValue( 4 );
q.addBindValue( values[ 4 ] );
QCOMPARE( q.boundValues().size(), 2 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 4 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[4] );
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 4);
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[4]);
QVERIFY_SQL( q, exec() );
QCOMPARE( q.boundValues().size(), 2 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 4 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[4] );
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 4);
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[4]);
q.bindValue( 1, values[ 5 ] );
q.bindValue( 0, 5 );
QCOMPARE( q.boundValues().size(), 2 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 5 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[5] );
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 5);
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[5]);
QVERIFY_SQL( q, exec() );
QCOMPARE( q.boundValues().size(), 2 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 5 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[5] );
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 5);
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[5]);
q.bindValue( 0, 6 );
q.bindValue( 1, QString() );
QCOMPARE( q.boundValues().size(), 2 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 6 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), QString() );
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 6);
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), QString());
QVERIFY_SQL( q, exec() );
QCOMPARE( q.boundValues().size(), 2 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 6 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), QString() );
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 6);
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), QString());
if ( db.driver()->hasFeature( QSqlDriver::Unicode ) ) {
q.bindValue( 0, 7 );
q.bindValue( 1, utf8str );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 7 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), utf8str );
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 7);
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), utf8str);
QVERIFY_SQL( q, exec() );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 7 );
- QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), utf8str );
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 7);
+ QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), utf8str);
}
QVERIFY_SQL( q, exec( "SELECT * FROM " + qtest_prepare + " order by id" ) );
diff --git a/tests/auto/widgets/widgets/qdockwidget/BLACKLIST b/tests/auto/widgets/widgets/qdockwidget/BLACKLIST
deleted file mode 100644
index 60adfb9f4b..0000000000
--- a/tests/auto/widgets/widgets/qdockwidget/BLACKLIST
+++ /dev/null
@@ -1,2 +0,0 @@
-[restoreDockWidget]
-ubuntu-14.04
diff --git a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp
index 947c251590..550cca8145 100644
--- a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp
+++ b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp
@@ -274,36 +274,30 @@ void tst_QTabBar::sizeHints()
{
QTabBar tabBar;
tabBar.setFont(QFont("Arial", 10));
- tabBar.addTab("tab 01");
- tabBar.addTab("tab 02");
- tabBar.addTab("tab 03");
- tabBar.addTab("tab 04");
- tabBar.addTab("tab 05");
- tabBar.addTab("tab 06");
- tabBar.addTab("This is tab7");
- tabBar.addTab("This is tab8");
- tabBar.addTab("This is tab9 with a very long title");
// No eliding and no scrolling -> tabbar becomes very wide
tabBar.setUsesScrollButtons(false);
tabBar.setElideMode(Qt::ElideNone);
-// qDebug() << tabBar.minimumSizeHint() << tabBar.sizeHint();
-#ifdef Q_OS_MAC
- QEXPECT_FAIL("", "QTBUG-27230", Abort);
-#endif
+ tabBar.addTab("tab 01");
+
+ // Fetch the minimum size hint width and make sure that we create enough
+ // tabs.
+ int minimumSizeHintWidth = tabBar.minimumSizeHint().width();
+ for (int i = 0; i <= 700 / minimumSizeHintWidth; ++i)
+ tabBar.addTab(QString("tab 0%1").arg(i+2));
+
+ //qDebug() << tabBar.minimumSizeHint() << tabBar.sizeHint();
QVERIFY(tabBar.minimumSizeHint().width() > 700);
QVERIFY(tabBar.sizeHint().width() > 700);
// Scrolling enabled -> no reason to become very wide
tabBar.setUsesScrollButtons(true);
- // qDebug() << tabBar.minimumSizeHint() << tabBar.sizeHint();
QVERIFY(tabBar.minimumSizeHint().width() < 200);
QVERIFY(tabBar.sizeHint().width() > 700); // unchanged
// Eliding enabled -> no reason to become very wide
tabBar.setUsesScrollButtons(false);
tabBar.setElideMode(Qt::ElideRight);
-// qDebug() << tabBar.minimumSizeHint() << tabBar.sizeHint();
// The sizeHint is very much dependent on the screen DPI value
// so we can not really predict it.
@@ -312,7 +306,7 @@ void tst_QTabBar::sizeHints()
QVERIFY(tabBarMinSizeHintWidth < tabBarSizeHintWidth);
QVERIFY(tabBarSizeHintWidth > 700); // unchanged
- tabBar.addTab("This is tab10 with a very long title");
+ tabBar.addTab("This is tab with a very long title");
QVERIFY(tabBar.minimumSizeHint().width() > tabBarMinSizeHintWidth);
QVERIFY(tabBar.sizeHint().width() > tabBarSizeHintWidth);
}
diff --git a/tests/manual/foreignwindows/foreignwindows.pro b/tests/manual/foreignwindows/foreignwindows.pro
new file mode 100644
index 0000000000..6a370a6813
--- /dev/null
+++ b/tests/manual/foreignwindows/foreignwindows.pro
@@ -0,0 +1,6 @@
+TEMPLATE = app
+QT += widgets
+CONFIG += console c++11
+CONFIG -= app_bundle
+SOURCES += main.cpp
+include(../diaglib/diaglib.pri)
diff --git a/tests/manual/foreignwindows/main.cpp b/tests/manual/foreignwindows/main.cpp
new file mode 100644
index 0000000000..6c722a3f6f
--- /dev/null
+++ b/tests/manual/foreignwindows/main.cpp
@@ -0,0 +1,329 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets/QAction>
+#include <QtWidgets/QApplication>
+#include <QtWidgets/QDesktopWidget>
+#include <QtWidgets/QMainWindow>
+#include <QtWidgets/QMenu>
+#include <QtWidgets/QMenuBar>
+#include <QtWidgets/QToolBar>
+
+#include <QtGui/QScreen>
+#include <QtGui/QWindow>
+
+#include <QtCore/QCommandLineOption>
+#include <QtCore/QCommandLineParser>
+#include <QtCore/QDebug>
+#include <QtCore/QSharedPointer>
+#include <QtCore/QStringList>
+#include <QtCore/QTextStream>
+#include <QtCore/QTimer>
+
+#ifdef Q_OS_WIN
+# include <QtCore/qt_windows.h>
+#endif
+
+#include <eventfilter.h> // diaglib
+#include <nativewindowdump.h>
+#include <qwidgetdump.h>
+#include <qwindowdump.h>
+
+#include <iostream>
+#include <algorithm>
+
+QT_USE_NAMESPACE
+
+typedef QSharedPointer<QWidget> WidgetPtr;
+typedef QList<WidgetPtr> WidgetPtrList;
+typedef QList<WId> WIdList;
+
+// Create some pre-defined Windows controls by class name
+static WId createInternalWindow(const QString &name)
+{
+ WId result = 0;
+#ifdef Q_OS_WIN
+ if (name == QLatin1String("BUTTON") || name == QLatin1String("COMBOBOX")
+ || name == QLatin1String("EDIT") || name.startsWith(QLatin1String("RICHEDIT"))) {
+ const HWND hwnd =
+ CreateWindowEx(0, reinterpret_cast<const wchar_t *>(name.utf16()),
+ L"NativeCtrl", WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+ 0, 0, GetModuleHandle(NULL), NULL);
+ if (hwnd) {
+ SetWindowText(hwnd, L"Demo");
+ result = WId(hwnd);
+ } else {
+ qErrnoWarning("Cannot create window \"%s\"", qPrintable(name));
+ }
+ }
+#else // Q_OS_WIN
+ Q_UNUSED(name)
+#endif
+ return result;
+}
+
+// Embed a foreign window using createWindowContainer() providing
+// menu actions to dump information.
+class EmbeddingWindow : public QMainWindow
+{
+ Q_OBJECT
+public:
+ explicit EmbeddingWindow(QWindow *window);
+
+public slots:
+ void releaseForeignWindow();
+
+private:
+ QWindow *m_window;
+ QAction *m_releaseAction;
+};
+
+EmbeddingWindow::EmbeddingWindow(QWindow *window) : m_window(window)
+{
+ const QString title = QLatin1String("Qt ") + QLatin1String(QT_VERSION_STR)
+ + QLatin1String(" 0x") + QString::number(window->winId(), 16);
+ setWindowTitle(title);
+ setObjectName("MainWindow");
+ QWidget *container = QWidget::createWindowContainer(window, Q_NULLPTR, Qt::Widget);
+ container->setObjectName("Container");
+ setCentralWidget(container);
+
+ QMenu *fileMenu = menuBar()->addMenu("File");
+ fileMenu->setObjectName("FileMenu");
+ QToolBar *toolbar = new QToolBar;
+ addToolBar(Qt::TopToolBarArea, toolbar);
+
+ // Manipulation
+ QAction *action = fileMenu->addAction("Visible");
+ action->setCheckable(true);
+ action->setChecked(true);
+ connect(action, &QAction::toggled, m_window, &QWindow::setVisible);
+ toolbar->addAction(action);
+
+ m_releaseAction = fileMenu->addAction("Release", this, &EmbeddingWindow::releaseForeignWindow);
+ toolbar->addAction(m_releaseAction);
+
+ fileMenu->addSeparator(); // Diaglib actions
+ action = fileMenu->addAction("Dump Widgets",
+ this, [] () { QtDiag::dumpAllWidgets(); });
+ toolbar->addAction(action);
+ action = fileMenu->addAction("Dump Windows",
+ this, [] () { QtDiag::dumpAllWindows(); });
+ toolbar->addAction(action);
+ action = fileMenu->addAction("Dump Native Windows",
+ this, [this] () { QtDiag::dumpNativeWindows(winId()); });
+ toolbar->addAction(action);
+
+ fileMenu->addSeparator();
+ action = fileMenu->addAction("Quit", qApp, &QCoreApplication::quit);
+ toolbar->addAction(action);
+ action->setShortcut(Qt::CTRL + Qt::Key_Q);
+}
+
+void EmbeddingWindow::releaseForeignWindow()
+{
+ if (m_window) {
+ m_window->setParent(Q_NULLPTR);
+ m_window = Q_NULLPTR;
+ m_releaseAction->setEnabled(false);
+ }
+}
+
+// Dump information about foreign windows.
+class WindowDumper : public QObject {
+ Q_OBJECT
+public:
+ explicit WindowDumper(const QWindowList &watchedWindows)
+ : m_watchedWindows(watchedWindows) {}
+
+public slots:
+ void dump() const;
+
+private:
+ const QWindowList m_watchedWindows;
+};
+
+void WindowDumper::dump() const
+{
+ static int n = 0;
+ QString s;
+ QDebug debug(&s);
+ debug.nospace();
+ debug.setVerbosity(3);
+ debug << '#' << n++;
+ if (m_watchedWindows.size() > 1)
+ debug << '\n';
+ foreach (const QWindow *w, m_watchedWindows) {
+ const QPoint globalPos = w->mapToGlobal(QPoint());
+ debug << " " << w << " pos=" << globalPos.x() << ',' << globalPos.y() << '\n';
+ }
+
+ std::cout << qPrintable(s);
+}
+
+static QString description(const QString &appName)
+{
+ QString result;
+ QTextStream(&result)
+ << "\nDumps information about foreign windows passed on the command line or\n"
+ "tests embedding foreign windows into Qt.\n\nUse cases:\n\n"
+ << appName << " -a Dump a list of all native window ids.\n"
+ << appName << " <winid> Dump information on the window.\n"
+ << appName << " -c <winid> Dump information on the window continuously.\n"
+ << appName << " -e <winid> Embed window into a Qt widget.\n"
+ << "\nOn Windows, class names of well known controls (EDIT, BUTTON...) can be\n"
+ "passed as <winid> along with -e, which will create the control.\n";
+ return result;
+}
+
+struct EventFilterOption
+{
+ const char *name;
+ const char *description;
+ QtDiag::EventFilter::EventCategories categories;
+};
+
+EventFilterOption eventFilterOptions[] = {
+{"mouse-events", "Dump mouse events.", QtDiag::EventFilter::MouseEvents},
+{"keyboard-events", "Dump keyboard events.", QtDiag::EventFilter::KeyEvents},
+{"state-events", "Dump state/focus change events.", QtDiag::EventFilter::StateChangeEvents | QtDiag::EventFilter::FocusEvents}
+};
+
+static inline bool isOptionSet(int argc, char *argv[], const char *option)
+{
+ return (argv + argc) !=
+ std::find_if(argv + 1, argv + argc,
+ [option] (const char *arg) { return !qstrcmp(arg, option); });
+}
+
+int main(int argc, char *argv[])
+{
+ // Check for no scaling before QApplication is instantiated.
+ if (isOptionSet(argc, argv, "-s"))
+ QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);
+ QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
+ QGuiApplication::setApplicationDisplayName("Foreign window tester");
+
+ QApplication app(argc, argv);
+
+ QCommandLineParser parser;
+ parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
+ parser.setApplicationDescription(description(QCoreApplication::applicationName()));
+ parser.addHelpOption();
+ parser.addVersionOption();
+ QCommandLineOption noScalingDummy(QStringLiteral("s"),
+ QStringLiteral("Disable High DPI scaling."));
+ parser.addOption(noScalingDummy);
+ QCommandLineOption outputAllOption(QStringList() << QStringLiteral("a") << QStringLiteral("all"),
+ QStringLiteral("Output all native window ids (requires diaglib)."));
+ parser.addOption(outputAllOption);
+ QCommandLineOption continuousOption(QStringList() << QStringLiteral("c") << QStringLiteral("continuous"),
+ QStringLiteral("Output continuously."));
+ parser.addOption(continuousOption);
+ QCommandLineOption embedOption(QStringList() << QStringLiteral("e") << QStringLiteral("embed"),
+ QStringLiteral("Embed a foreign window into a Qt widget."));
+ parser.addOption(embedOption);
+ const int eventFilterOptionCount = int(sizeof(eventFilterOptions) / sizeof(eventFilterOptions[0]));
+ for (int i = 0; i < eventFilterOptionCount; ++i) {
+ parser.addOption(QCommandLineOption(QLatin1String(eventFilterOptions[i].name),
+ QLatin1String(eventFilterOptions[i].description)));
+ }
+ parser.addPositionalArgument(QStringLiteral("[windows]"), QStringLiteral("Window IDs."));
+
+ parser.process(QCoreApplication::arguments());
+
+ if (parser.isSet(outputAllOption)) {
+ QtDiag::dumpNativeWindows();
+ return 0;
+ }
+
+ QWindowList windows;
+ foreach (const QString &argument, parser.positionalArguments()) {
+ bool ok = true;
+ WId wid = createInternalWindow(argument);
+ if (!wid)
+ wid = argument.toULongLong(&ok, 0);
+ if (!wid || !ok) {
+ std::cerr << "Invalid window id: \"" << qPrintable(argument) << "\"\n";
+ return -1;
+ }
+ QWindow *foreignWindow = QWindow::fromWinId(wid);
+ foreignWindow->setObjectName("ForeignWindow" + QString::number(wid, 16));
+ windows.append(foreignWindow);
+ }
+
+ if (windows.isEmpty())
+ parser.showHelp(0);
+
+ int exitCode = 0;
+
+ if (parser.isSet(embedOption)) {
+ QtDiag::EventFilter::EventCategories eventCategories = 0;
+ for (int i = 0; i < eventFilterOptionCount; ++i) {
+ if (parser.isSet(QLatin1String(eventFilterOptions[i].name)))
+ eventCategories |= eventFilterOptions[i].categories;
+ }
+ if (eventCategories)
+ app.installEventFilter(new QtDiag::EventFilter(eventCategories, &app));
+
+ const QRect availableGeometry = QApplication::desktop()->availableGeometry(0);
+ QPoint pos = availableGeometry.topLeft() + QPoint(availableGeometry.width(), availableGeometry.height()) / 3;
+
+ WidgetPtrList mainWindows;
+ foreach (QWindow *window, windows) {
+ WidgetPtr mainWindow(new EmbeddingWindow(window));
+ mainWindow->move(pos);
+ mainWindow->resize(availableGeometry.size() / 4);
+ mainWindow->show();
+ pos += QPoint(40, 40);
+ mainWindows.append(mainWindow);
+ }
+ exitCode = app.exec();
+
+ } else if (parser.isSet(continuousOption)) {
+ WindowDumper dumper(windows);
+ dumper.dump();
+ QTimer *timer = new QTimer(&dumper);
+ QObject::connect(timer, &QTimer::timeout, &dumper, &WindowDumper::dump);
+ timer->start(1000);
+ exitCode = app.exec();
+
+ } else {
+ WindowDumper(windows).dump();
+ }
+
+ return exitCode;
+}
+
+#include "main.moc"
diff --git a/tests/manual/highdpi/dragwidget.cpp b/tests/manual/highdpi/dragwidget.cpp
index b5ad6fa63b..fc1ea72963 100644
--- a/tests/manual/highdpi/dragwidget.cpp
+++ b/tests/manual/highdpi/dragwidget.cpp
@@ -163,7 +163,11 @@ void DragWidget::mousePressEvent(QMouseEvent *event)
mimeData->setData("application/x-hotspot",
QByteArray::number(hotSpot.x()) + ' ' + QByteArray::number(hotSpot.y()));
- QPixmap pixmap(child->size());
+ const qreal dpr = devicePixelRatioF() > 1 && !(QGuiApplication::keyboardModifiers() & Qt::ShiftModifier)
+ ? devicePixelRatioF() : 1;
+
+ QPixmap pixmap(child->size() * dpr);
+ pixmap.setDevicePixelRatio(dpr);
child->render(&pixmap);
QDrag *drag = new QDrag(this);
diff --git a/tests/manual/highdpi/main.cpp b/tests/manual/highdpi/main.cpp
index dcfabb213c..bd6af75b16 100644
--- a/tests/manual/highdpi/main.cpp
+++ b/tests/manual/highdpi/main.cpp
@@ -375,16 +375,22 @@ Labels::Labels()
class MainWindow : public QMainWindow
{
+ Q_OBJECT
public:
MainWindow();
QMenu *addNewMenu(const QString &title, int itemCount = 5);
+private slots:
+ void maskActionToggled(bool t);
+
+private:
QIcon qtIcon;
QIcon qtIcon1x;
QIcon qtIcon2x;
QToolBar *fileToolBar;
int menuCount;
+ QAction *m_maskAction;
};
MainWindow::MainWindow()
@@ -403,7 +409,12 @@ MainWindow::MainWindow()
addNewMenu("&Edit");
addNewMenu("&Build");
addNewMenu("&Debug", 4);
- addNewMenu("&Transmogrify", 7);
+ QMenu *menu = addNewMenu("&Transmogrify", 7);
+ menu->addSeparator();
+ m_maskAction = menu->addAction("Mask");
+ m_maskAction->setCheckable(true);
+ connect(m_maskAction, &QAction::toggled, this, &MainWindow::maskActionToggled);
+ fileToolBar->addAction(m_maskAction);
addNewMenu("T&ools");
addNewMenu("&Help", 2);
}
@@ -426,6 +437,16 @@ QMenu *MainWindow::addNewMenu(const QString &title, int itemCount)
return menu;
}
+void MainWindow::maskActionToggled(bool t)
+{
+ if (t) {
+ QVector<QPoint> upperLeftTriangle;
+ upperLeftTriangle << QPoint(0, 0) << QPoint(width(), 0) << QPoint(0, height());
+ setMask(QRegion(QPolygon(upperLeftTriangle)));
+ } else {
+ clearMask();
+ }
+}
class StandardIcons : public QWidget
{
diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro
index cffe76b2b4..8777cc6e11 100644
--- a/tests/manual/manual.pro
+++ b/tests/manual/manual.pro
@@ -2,6 +2,7 @@ TEMPLATE=subdirs
SUBDIRS = bearerex \
filetest \
+foreignwindows \
gestures \
inputmethodhints \
keypadnavigation \
@@ -62,4 +63,5 @@ win32 {
}
lessThan(QT_MAJOR_VERSION, 5): SUBDIRS -= bearerex lance qnetworkaccessmanager/qget qmimedatabase qnetworkreply \
-qpainfo qscreen socketengine xembed-raster xembed-widgets windowtransparency
+qpainfo qscreen socketengine xembed-raster xembed-widgets windowtransparency \
+foreignwindows