summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config.tests/arch/arch.cpp2
-rwxr-xr-xconfigure4
-rw-r--r--doc/global/externalsites/qtcreator.qdoc8
-rw-r--r--doc/global/template/style/online.css3
-rw-r--r--mkspecs/features/qml_plugin.prf2
-rw-r--r--mkspecs/features/qt_functions.prf18
-rw-r--r--mkspecs/macx-ios-clang/xcodebuild.mk4
-rw-r--r--qmake/generators/makefiledeps.cpp11
-rw-r--r--src/3rdparty/libpng.pri1
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp41
-rw-r--r--src/corelib/tools/qsimd_p.h6
-rw-r--r--src/gui/doc/snippets/qfileopenevent/Info.plist59
-rw-r--r--src/gui/doc/snippets/qfileopenevent/main.cpp73
-rw-r--r--src/gui/image/qimage_conversions.cpp34
-rw-r--r--src/gui/image/qimage_neon.cpp30
-rw-r--r--src/gui/image/qjpeghandler.cpp3
-rw-r--r--src/gui/image/qpnghandler.cpp5
-rw-r--r--src/gui/kernel/qevent.cpp15
-rw-r--r--src/gui/painting/painting.pri2
-rw-r--r--src/gui/painting/qdrawhelper.cpp4
-rw-r--r--src/gui/painting/qdrawhelper_neon.cpp4
-rw-r--r--src/gui/painting/qrgb.h4
-rw-r--r--src/gui/text/qtextengine.cpp13
-rw-r--r--src/gui/text/qtextengine_p.h2
-rw-r--r--src/gui/text/qtextlayout.cpp40
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp10
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h1
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm6
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro3
-rw-r--r--src/plugins/platforms/ios/qiosintegration.mm10
-rw-r--r--src/plugins/platforms/ios/quiview.mm29
-rw-r--r--src/plugins/platforms/mirclient/qmirclientplugin.cpp5
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.cpp168
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.h18
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.cpp111
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.h10
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp12
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.h4
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp3
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp6
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp3
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp14
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h2
-rw-r--r--src/testlib/qsignalspy.h7
-rw-r--r--src/widgets/kernel/qopenglwidget.cpp3
-rw-r--r--src/widgets/kernel/qwidget.cpp13
-rw-r--r--src/widgets/kernel/qwidget_p.h3
-rw-r--r--src/widgets/kernel/qwidgetbackingstore.cpp13
-rw-r--r--src/widgets/util/qsystemtrayicon.cpp6
-rw-r--r--src/widgets/util/qsystemtrayicon_x11.cpp3
-rw-r--r--tests/auto/corelib/io/qprocess/tst_qprocess.cpp52
-rw-r--r--tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp8
-rw-r--r--tests/auto/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp152
-rw-r--r--tests/auto/gui/image/qimagereader/tst_qimagereader.cpp31
-rw-r--r--tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp8
-rw-r--r--tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp14
-rw-r--r--tests/auto/tools/qmake/testdata/.gitignore5
-rw-r--r--tests/manual/qcursor/qcursor.pro2
-rw-r--r--tests/manual/qcursor/qcursorhighdpi/main.cpp321
-rw-r--r--tests/manual/qcursor/qcursorhighdpi/qcursorhighdpi.pro6
60 files changed, 1085 insertions, 365 deletions
diff --git a/config.tests/arch/arch.cpp b/config.tests/arch/arch.cpp
index 7e481d4cf5..c4f23f7bcd 100644
--- a/config.tests/arch/arch.cpp
+++ b/config.tests/arch/arch.cpp
@@ -237,7 +237,7 @@ const char msg2[] = "==Qt=magic=Qt== Sub-architecture:"
#endif
// -- ARM --
-#ifdef __ARM_NEON__
+#if defined(__ARM_NEON) || defined(__ARM_NEON__)
" neon"
#endif
#ifdef __IWMMXT__
diff --git a/configure b/configure
index 5873112a16..b65519cce9 100755
--- a/configure
+++ b/configure
@@ -455,7 +455,7 @@ DeviceVar()
eq="="
;;
*)
- echo >&2 "BUG: wrong command to QMakeVar: $1"
+ echo >&2 "BUG: wrong command to DeviceVar: $1"
;;
esac
@@ -7203,7 +7203,7 @@ if [ -n "$DISABLED_FEATURES" ]; then
fi
echo "QT_QCONFIG_PATH = ${CFG_QCONFIG_PATH#$relpath/src/corelib/global/}"
-cat >>"$QTMODULE.tmp" <<EOF
+cat <<EOF
host_build {
QT_CPU_FEATURES.$CFG_HOST_ARCH = $CFG_HOST_CPUFEATURES
} else {
diff --git a/doc/global/externalsites/qtcreator.qdoc b/doc/global/externalsites/qtcreator.qdoc
index 95200622f3..b8cd9dec00 100644
--- a/doc/global/externalsites/qtcreator.qdoc
+++ b/doc/global/externalsites/qtcreator.qdoc
@@ -106,6 +106,10 @@
\title Qt Creator: Creating a Qt Quick Application
*/
/*!
+ \externalpage http://doc.qt.io/qtcreator/qtquick-iso-icon-browser.html
+ \title Qt Creator: Browsing ISO 7000 Icons
+*/
+/*!
\externalpage http://doc.qt.io/qtcreator/quick-export-to-qml.html
\title Qt Creator: Exporting Designs from Graphics Software
*/
@@ -210,6 +214,10 @@
\title Qt Creator: Editing MIME Types
*/
/*!
+ \externalpage http://doc.qt.io/qtcreator/creator-modeling.html
+ \title Qt Creator: Modeling
+*/
+/*!
\externalpage http://doc.qt.io/qtcreator/creator-qml-debugging-example.html
\title Qt Creator: Debugging a Qt Quick Example Application
*/
diff --git a/doc/global/template/style/online.css b/doc/global/template/style/online.css
index cfd0da0f4b..a98382e083 100644
--- a/doc/global/template/style/online.css
+++ b/doc/global/template/style/online.css
@@ -1261,6 +1261,9 @@ table td,table th {
table.alignedsummary,table.propsummary {
width:initial
}
+table.valuelist td.tblval {
+ font-size:0.75em
+}
div.main_index .row {
border-bottom:1px solid #eee
}
diff --git a/mkspecs/features/qml_plugin.prf b/mkspecs/features/qml_plugin.prf
index a639ac2969..1bc05caefe 100644
--- a/mkspecs/features/qml_plugin.prf
+++ b/mkspecs/features/qml_plugin.prf
@@ -19,6 +19,8 @@ if(win32|mac):!macx-xcode {
contains(QT_CONFIG, build_all):CONFIG += build_all
}
+CONFIG += relative_qt_rpath # Qt's QML plugins should be relocatable
+
!no_cxx_module:isEmpty(CXX_MODULE) {
CXX_MODULE = $$TARGET
TARGET = declarative_$${TARGET}
diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf
index 403b847ac1..00f4bdf93e 100644
--- a/mkspecs/features/qt_functions.prf
+++ b/mkspecs/features/qt_functions.prf
@@ -120,15 +120,9 @@ defineTest(qtAddTargetEnv) {
deps = $$replace($$2, -private$, _private)
deps = $$resolve_depends(deps, "QT.", ".depends" ".run_depends")
!isEmpty(deps) {
- ptypes =
- for(dep, deps) {
- isEmpty(3): \
- deppath += $$shell_path($$eval(QT.$${dep}.libs))
- else: \
- deppath += $$system_path($$eval(QT.$${dep}.libs))
- ptypes += $$eval(QT.$${dep}.plugin_types)
- }
+ libs = libs
equals(QMAKE_HOST.os, Windows) {
+ libs = bins
deppath.name = PATH
} else:contains(QMAKE_HOST.os, Linux|FreeBSD|OpenBSD|NetBSD|DragonFly|SunOS|HP-UX|QNX|GNU) {
deppath.name = LD_LIBRARY_PATH
@@ -144,6 +138,14 @@ defineTest(qtAddTargetEnv) {
} else {
error("Operating system not supported.")
}
+ ptypes =
+ for(dep, deps) {
+ isEmpty(3): \
+ deppath += $$shell_path($$eval(QT.$${dep}.$$libs))
+ else: \
+ deppath += $$system_path($$eval(QT.$${dep}.$$libs))
+ ptypes += $$eval(QT.$${dep}.plugin_types)
+ }
deppath.value = $$unique(deppath)
deppath.CONFIG = prepend
diff --git a/mkspecs/macx-ios-clang/xcodebuild.mk b/mkspecs/macx-ios-clang/xcodebuild.mk
index afe331240b..1bd18430df 100644
--- a/mkspecs/macx-ios-clang/xcodebuild.mk
+++ b/mkspecs/macx-ios-clang/xcodebuild.mk
@@ -40,6 +40,10 @@ $(EXPORT_SUBTARGETS): % : %-build
%-install: ACTION = install
%-install: xcodebuild-% ;
+# iOS Simulator doesn't support archiving
+%-iphonesimulator-install: ACTION = build
+iphonesimulator-install: ACTION = build
+
# Limit check to a single configuration
%-iphoneos-check: check-iphoneos ;
%-iphonesimulator-check: check-iphonesimulator ;
diff --git a/qmake/generators/makefiledeps.cpp b/qmake/generators/makefiledeps.cpp
index f4479750c8..0f11745f4c 100644
--- a/qmake/generators/makefiledeps.cpp
+++ b/qmake/generators/makefiledeps.cpp
@@ -596,14 +596,11 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
continue;
}
x++;
-
- int inc_len;
- for (inc_len = 0;
- buffer[x + inc_len] != term && !qmake_endOfLine(buffer[x + inc_len]);
- ++inc_len) {} // skip until end of include name
- buffer[x + inc_len] = '\0';
inc = buffer + x;
- x += inc_len;
+ for (;
+ buffer[x] != term && !qmake_endOfLine(buffer[x]);
+ ++x) {} // skip until end of include name
+ buffer[x] = '\0';
} else if (buffer[x] == '\'' || buffer[x] == '"') {
const char term = buffer[x++];
while(x < buffer_len) {
diff --git a/src/3rdparty/libpng.pri b/src/3rdparty/libpng.pri
index f8516bd5db..a5fe32f867 100644
--- a/src/3rdparty/libpng.pri
+++ b/src/3rdparty/libpng.pri
@@ -1,4 +1,3 @@
-DEFINES *= QT_USE_BUNDLED_LIBPNG
DEFINES += PNG_ARM_NEON_OPT=0
INCLUDEPATH += $$PWD/libpng
SOURCES += $$PWD/libpng/png.c \
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 361bc0172d..5fe0ea3559 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -590,7 +590,7 @@ void QCoreApplicationPrivate::initLocale()
\section1 The Event Loop and Event Handling
- The event loop is started with a call to exec(). Long running
+ The event loop is started with a call to exec(). Long-running
operations can call processEvents() to keep the application
responsive.
@@ -672,7 +672,7 @@ QCoreApplication::QCoreApplication(QCoreApplicationPrivate &p)
#ifndef QT_NO_QOBJECT
/*!
- Flushes the platform specific event queues.
+ Flushes the platform-specific event queues.
If you are doing graphical changes inside a loop that does not
return to the event loop on asynchronous window systems like X11
@@ -690,9 +690,9 @@ void QCoreApplication::flush()
#endif
/*!
- Constructs a Qt kernel application. Kernel applications are
- applications without a graphical user interface. These type of
- applications are used at the console or as server processes.
+ Constructs a Qt core application. Core applications are applications without
+ a graphical user interface. Such applications are used at the console or as
+ server processes.
The \a argc and \a argv arguments are processed by the application,
and made available in a more convenient form by the arguments()
@@ -1174,7 +1174,7 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)
milliseconds or until there are no more events to process,
whichever is shorter.
- You can call this function occasionally when you program is busy
+ You can call this function occasionally when your program is busy
doing a long operation (e.g. copying a file).
Calling this function processes events only for the calling thread.
@@ -1201,9 +1201,9 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int m
*****************************************************************************/
/*!
- Enters the main event loop and waits until exit() is called.
- Returns the value that was set to exit() (which is 0 if exit() is
- called via quit()).
+ Enters the main event loop and waits until exit() is called. Returns
+ the value that was passed to exit() (which is 0 if exit() is called via
+ quit()).
It is necessary to call this function to start event handling. The
main event loop receives events from the window system and
@@ -1459,7 +1459,8 @@ bool QCoreApplication::compressEvent(QEvent *event, QObject *receiver, QPostEven
If \a receiver is null, the events of \a event_type are sent for all
objects. If \a event_type is 0, all the events are sent for \a receiver.
- \note This method must be called from the same thread as its QObject parameter, \a receiver.
+ \note This method must be called from the thread in which its QObject
+ parameter, \a receiver, lives.
\sa flush(), postEvent()
*/
@@ -1805,7 +1806,7 @@ void QCoreApplication::quit()
This signal is emitted when the application is about to quit the
main event loop, e.g. when the event loop level drops to zero.
This may happen either after a call to quit() from inside the
- application or when the users shuts down the entire desktop session.
+ application or when the user shuts down the entire desktop session.
The signal is particularly useful if your application has to do some
last-second cleanup. Note that no user interaction is possible in
@@ -2035,8 +2036,8 @@ void QCoreApplicationPrivate::setApplicationFilePath(const QString &path)
directory, and you run the \c{regexp} example, this function will
return "C:/Qt/examples/tools/regexp".
- On OS X and iOS this will point to the directory actually containing the
- executable, which may be inside of an application bundle (if the
+ On OS X and iOS this will point to the directory actually containing
+ the executable, which may be inside an application bundle (if the
application is bundled).
\warning On Linux, this function will try to get the path from the
@@ -2604,11 +2605,11 @@ void QCoreApplication::removeLibraryPath(const QString &path)
The event filter \a filterObj receives events via its \l {QAbstractNativeEventFilter::}{nativeEventFilter()}
function, which is called for all native events received in the main thread.
- The QAbstractNativeEventFilter::nativeEventFilter() function should return true if the event should
- be filtered, (i.e. stopped). It should return false to allow
- normal Qt processing to continue: the native event can then be translated
- into a QEvent and handled by the standard Qt \l{QEvent} {event} filtering,
- e.g. QObject::installEventFilter().
+ The QAbstractNativeEventFilter::nativeEventFilter() function should
+ return true if the event should be filtered, i.e. stopped. It should
+ return false to allow normal Qt processing to continue: the native
+ event can then be translated into a QEvent and handled by the standard
+ Qt \l{QEvent} {event} filtering, e.g. QObject::installEventFilter().
If multiple event filters are installed, the filter that was
installed last is activated first.
@@ -2616,7 +2617,7 @@ void QCoreApplication::removeLibraryPath(const QString &path)
\note The filter function set here receives native messages,
i.e. MSG or XCB event structs.
- \note Native event filters will be disabled when the application the
+ \note Native event filters will be disabled in the application when the
Qt::AA_PluginApplication attribute is set.
For maximum portability, you should always try to use QEvent
@@ -2805,7 +2806,7 @@ void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatc
\snippet code/src_corelib_kernel_qcoreapplication.cpp 7
The \a context parameter is normally the class name, but it can
- be any string.
+ be any text.
\sa Q_OBJECT, QObject::tr(), QObject::trUtf8()
*/
diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h
index 96f5419af6..96b9d376b7 100644
--- a/src/corelib/tools/qsimd_p.h
+++ b/src/corelib/tools/qsimd_p.h
@@ -251,9 +251,13 @@
// NEON intrinsics
// note: as of GCC 4.9, does not support function targets for ARM
-#if defined __ARM_NEON__
+#if defined(__ARM_NEON) || defined(__ARM_NEON__)
#include <arm_neon.h>
#define QT_FUNCTION_TARGET_STRING_ARM_NEON "neon"
+#ifndef __ARM_NEON__
+// __ARM_NEON__ is not defined on AArch64, but we need it in our NEON detection.
+#define __ARM_NEON__
+#endif
#endif
#undef QT_COMPILER_SUPPORTS_SIMD_ALWAYS
diff --git a/src/gui/doc/snippets/qfileopenevent/Info.plist b/src/gui/doc/snippets/qfileopenevent/Info.plist
new file mode 100644
index 0000000000..6b8039bc7d
--- /dev/null
+++ b/src/gui/doc/snippets/qfileopenevent/Info.plist
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Samuel Gaist <samuel.gaist@edeltech.ch>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [Custom Info.plist]
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>png</string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ </dict>
+ </array>
+</dict>
+</plist>
+//! [Custom Info.plist] \ No newline at end of file
diff --git a/src/gui/doc/snippets/qfileopenevent/main.cpp b/src/gui/doc/snippets/qfileopenevent/main.cpp
new file mode 100644
index 0000000000..3fd1757bd7
--- /dev/null
+++ b/src/gui/doc/snippets/qfileopenevent/main.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Samuel Gaist <samuel.gaist@edeltech.ch>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [QApplication subclass]
+#include <QApplication>
+#include <QFileOpenEvent>
+#include <QtDebug>
+
+class MyApplication : public QApplication
+{
+public:
+ MyApplication(int &argc, char **argv)
+ : QApplication(argc, argv)
+ {
+ }
+
+ bool event(QEvent *event)
+ {
+ if (event->type() == QEvent::FileOpen) {
+ QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(event);
+ qDebug() << "Open file" << openEvent->file();
+ }
+
+ return QApplication::event(event);
+ }
+};
+//! [QApplication subclass]
+
+int main(int argc, char *argv[])
+{
+ MyApplication app(argc, argv);
+ QPushButton closeButton("Quit");
+ QObject::connect(&closeButton, &QPushButton::clicked, &app, &QApplication::quit);
+ closeButton.show();
+ return app.exec();
+}
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp
index 02f32aa34b..7d1fb23b15 100644
--- a/src/gui/image/qimage_conversions.cpp
+++ b/src/gui/image/qimage_conversions.cpp
@@ -375,7 +375,32 @@ static void convert_RGB888_to_RGB(QImageData *dest, const QImageData *src, Qt::I
}
}
+#ifdef __SSE2__
extern bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags);
+#else
+static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data,Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_ARGB32 || data->format == QImage::Format_RGBA8888);
+
+ const int pad = (data->bytes_per_line >> 2) - data->width;
+ QRgb *rgb_data = (QRgb *) data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ const QRgb *end = rgb_data + data->width;
+ while (rgb_data < end) {
+ *rgb_data = qPremultiply(*rgb_data);
+ ++rgb_data;
+ }
+ rgb_data += pad;
+ }
+
+ if (data->format == QImage::Format_ARGB32)
+ data->format = QImage::Format_ARGB32_Premultiplied;
+ else
+ data->format = QImage::Format_RGBA8888_Premultiplied;
+ return true;
+}
+#endif
static void convert_ARGB_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
@@ -2592,7 +2617,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
#ifdef __SSE2__
convert_ARGB_to_ARGB_PM_inplace_sse2,
#else
- 0,
+ convert_ARGB_to_ARGB_PM_inplace,
#endif
0,
0,
@@ -2705,12 +2730,13 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
mask_alpha_converter_rgbx_inplace,
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN && __SSE2__
0,
+#ifdef __SSE2__
convert_ARGB_to_ARGB_PM_inplace_sse2,
+#elif Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ convert_ARGB_to_ARGB_PM_inplace,
#else
0,
- 0,
#endif
0, 0, 0, 0, 0, 0
}, // Format_RGBA8888
@@ -2921,7 +2947,7 @@ void qInitImageConversions()
}
#endif
-#if defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64)
+#if defined(__ARM_NEON__)
extern void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
qimage_converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_neon;
qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_neon;
diff --git a/src/gui/image/qimage_neon.cpp b/src/gui/image/qimage_neon.cpp
index b51c43aa9d..5853510ee1 100644
--- a/src/gui/image/qimage_neon.cpp
+++ b/src/gui/image/qimage_neon.cpp
@@ -35,7 +35,7 @@
#include <private/qimage_p.h>
#include <private/qsimd_p.h>
-#if defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64)
+#if defined(__ARM_NEON__)
QT_BEGIN_NAMESPACE
@@ -55,6 +55,7 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, cons
if ((len - offsetToAlignOn8Bytes) >= 8) {
const quint32 *const simdEnd = end - 7;
+#if !defined(Q_PROCESSOR_ARM_64)
register uint8x8_t fullVector asm ("d3") = vdup_n_u8(0xff);
do {
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
@@ -76,6 +77,31 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, cons
);
#endif
} while (dst < simdEnd);
+#else
+ register uint8x8_t fullVector asm ("v3") = vdup_n_u8(0xff);
+ do {
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+ asm volatile (
+ "ld3 { v4.8b, v5.8b, v6.8b }, [%[SRC]], #24 \n\t"
+ "st4 { v3.8b, v4.8b, v5.8b, v6.8b }, [%[DST]], #32 \n\t"
+ : [DST]"+r" (dst), [SRC]"+r" (src)
+ : "w"(fullVector)
+ : "memory", "v4", "v5", "v6"
+ );
+#else
+ asm volatile (
+ "ld3 { v0.8b, v1.8b, v2.8b }, [%[SRC]], #24 \n\t"
+ "mov v4.8b, v2.8b\n\t"
+ "mov v2.8b, v0.8b\n\t"
+ "mov v0.8b, v4.8b\n\t"
+ "st4 { v0.8b, v1.8b, v2.8b, v3.8b }, [%[DST]], #32 \n\t"
+ : [DST]"+r" (dst), [SRC]"+r" (src)
+ : "w"(fullVector)
+ : "memory", "v0", "v1", "v2", "v4"
+ );
+#endif
+ } while (dst < simdEnd);
+#endif
}
while (dst != end) {
@@ -103,4 +129,4 @@ void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::I
QT_END_NAMESPACE
-#endif // defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64)
+#endif // defined(__ARM_NEON__)
diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp
index 7e9483e6f7..68709b708d 100644
--- a/src/gui/image/qjpeghandler.cpp
+++ b/src/gui/image/qjpeghandler.cpp
@@ -978,9 +978,8 @@ extern "C" void qt_convert_rgb888_to_rgb32_mips_dspr2_asm(quint32 *dst, const uc
QJpegHandler::QJpegHandler()
: d(new QJpegHandlerPrivate(this))
{
-#if defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64)
+#if defined(__ARM_NEON__)
// from qimage_neon.cpp
-
if (qCpuHasFeature(NEON))
d->rgb888ToRgb32ConverterPtr = qt_convert_rgb888_to_rgb32_neon;
#endif
diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp
index 776a61d8fe..e9944e1750 100644
--- a/src/gui/image/qpnghandler.cpp
+++ b/src/gui/image/qpnghandler.cpp
@@ -43,13 +43,8 @@
#include <qvariant.h>
#include <qvector.h>
-#ifdef QT_USE_BUNDLED_LIBPNG
-#include <../../3rdparty/libpng/png.h>
-#include <../../3rdparty/libpng/pngconf.h>
-#else
#include <png.h>
#include <pngconf.h>
-#endif
#if PNG_LIBPNG_VER >= 10400 && PNG_LIBPNG_VER <= 10502 \
&& defined(PNG_PEDANTIC_WARNINGS_SUPPORTED)
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 233b9ef3f7..bd1b4d6393 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -3418,6 +3418,21 @@ QShowEvent::~QShowEvent()
It may be safely ignored.
\note This class is currently supported for OS X only.
+
+ \section1 OS X Example
+
+ In order to trigger the event on OS X, the application must be configured
+ to let the OS know what kind of file(s) it should react on.
+
+ For example, the following \c Info.plist file declares that the application
+ can act as a viewer for files with a PNG extension:
+
+ \snippet qfileopenevent/Info.plist Custom Info.plist
+
+ The following implementation of a QApplication subclass prints the path to
+ the file that was, for example, dropped on the Dock icon of the application.
+
+ \snippet qfileopenevent/main.cpp QApplication subclass
*/
/*!
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 2e2532a25f..fd9ae0aaca 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -101,7 +101,7 @@ SSE4_1_SOURCES += painting/qdrawhelper_sse4.cpp \
painting/qimagescale_sse4.cpp
AVX2_SOURCES += painting/qdrawhelper_avx2.cpp
-!ios {
+!ios:!contains(QT_ARCH, "arm64") {
CONFIG += no_clang_integrated_as
NEON_SOURCES += painting/qdrawhelper_neon.cpp
NEON_HEADERS += painting/qdrawhelper_neon_p.h
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 52843fa113..988bee9b27 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -6309,7 +6309,7 @@ void qt_memfill16(quint16 *dest, quint16 color, int count)
qt_memfill_template<quint16>(dest, color, count);
}
#endif
-#if !defined(__SSE2__) && !defined(__ARM_NEON__)
+#if !defined(__SSE2__) && (!defined(__ARM_NEON__) || defined(Q_PROCESSOR_ARM_64))
# ifdef QT_COMPILER_SUPPORTS_MIPS_DSP
extern "C" void qt_memfill32_asm_mips_dsp(quint32 *, quint32, int);
# endif
@@ -6425,7 +6425,7 @@ void qInitDrawhelperAsm()
#endif // SSE2
-#if defined(__ARM_NEON__) && !defined(Q_OS_IOS)
+#if defined(__ARM_NEON__) && !defined(Q_OS_IOS) && !defined(Q_PROCESSOR_ARM_64)
qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp
index 08e564f017..bf4758afd2 100644
--- a/src/gui/painting/qdrawhelper_neon.cpp
+++ b/src/gui/painting/qdrawhelper_neon.cpp
@@ -31,15 +31,13 @@
**
****************************************************************************/
-#include <private/qdrawhelper_p.h>
+#include <private/qdrawhelper_neon_p.h>
#include <private/qblendfunctions_p.h>
#include <private/qmath_p.h>
#ifdef __ARM_NEON__
-#include <private/qdrawhelper_neon_p.h>
#include <private/qpaintengine_raster_p.h>
-#include <arm_neon.h>
QT_BEGIN_NAMESPACE
diff --git a/src/gui/painting/qrgb.h b/src/gui/painting/qrgb.h
index f7f2185bef..ca9fc03d14 100644
--- a/src/gui/painting/qrgb.h
+++ b/src/gui/painting/qrgb.h
@@ -58,10 +58,10 @@ inline Q_DECL_CONSTEXPR int qAlpha(QRgb rgb) // get alpha part of
{ return rgb >> 24; }
inline Q_DECL_CONSTEXPR QRgb qRgb(int r, int g, int b)// set RGB value
-{ return (0xffu << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); }
+{ return (0xffu << 24) | ((r & 0xffu) << 16) | ((g & 0xffu) << 8) | (b & 0xffu); }
inline Q_DECL_CONSTEXPR QRgb qRgba(int r, int g, int b, int a)// set RGBA value
-{ return ((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); }
+{ return ((a & 0xffu) << 24) | ((r & 0xffu) << 16) | ((g & 0xffu) << 8) | (b & 0xffu); }
inline Q_DECL_CONSTEXPR int qGray(int r, int g, int b)// convert R,G,B to gray 0..255
{ return (r*11+g*16+b*5)/32; }
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 68747ad6ad..746a51318e 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -918,10 +918,11 @@ void QTextEngine::shapeLine(const QScriptLine &line)
{
QFixed x;
bool first = true;
- const int end = findItem(line.from + line.length - 1);
int item = findItem(line.from);
if (item == -1)
return;
+
+ const int end = findItem(line.from + line.length - 1, item);
for ( ; item <= end; ++item) {
QScriptItem &si = layoutData->items[item];
if (si.analysis.flags == QScriptAnalysis::Tab) {
@@ -1747,13 +1748,13 @@ bool QTextEngine::isRightToLeft() const
}
-int QTextEngine::findItem(int strPos) const
+int QTextEngine::findItem(int strPos, int firstItem) const
{
itemize();
- if (strPos < 0 || strPos >= layoutData->string.size())
+ if (strPos < 0 || strPos >= layoutData->string.size() || firstItem < 0)
return -1;
- int left = 1;
+ int left = firstItem + 1;
int right = layoutData->items.size()-1;
while(left <= right) {
int middle = ((right-left)/2)+left;
@@ -2172,7 +2173,7 @@ void QTextEngine::justify(const QScriptLine &line)
return;
int firstItem = findItem(line.from);
- int lastItem = findItem(line.from + line_length - 1);
+ int lastItem = findItem(line.from + line_length - 1, firstItem);
int nItems = (firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0;
QVarLengthArray<QJustificationPoint> justificationPoints;
@@ -3529,7 +3530,7 @@ QTextLineItemIterator::QTextLineItemIterator(QTextEngine *_eng, int _lineNum, co
lineNum(_lineNum),
lineEnd(line.from + line.length),
firstItem(eng->findItem(line.from)),
- lastItem(eng->findItem(lineEnd - 1)),
+ lastItem(eng->findItem(lineEnd - 1, firstItem)),
nItems((firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0),
logicalItem(-1),
item(-1),
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index dbe8e1ee2b..39c228fd52 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -512,7 +512,7 @@ public:
void freeMemory();
- int findItem(int strPos) const;
+ int findItem(int strPos, int firstItem = 0) const;
inline QTextFormatCollection *formatCollection() const {
if (block.docHandle())
return block.docHandle()->formatCollection();
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index 9f046af47c..65650504ac 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -2624,26 +2624,24 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR
*/
qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
{
- if (!eng->layoutData)
- eng->itemize();
-
const QScriptLine &line = eng->lines[index];
bool lastLine = index >= eng->lines.size() - 1;
- QFixed x = line.x;
- x += eng->alignLine(line) - eng->leadingSpaceWidth(line);
+ QFixed x = line.x + eng->alignLine(line) - eng->leadingSpaceWidth(line);
- if (!index && !eng->layoutData->items.size()) {
- *cursorPos = 0;
+ if (!eng->layoutData)
+ eng->itemize();
+ if (!eng->layoutData->items.size()) {
+ *cursorPos = line.from;
return x.toReal();
}
int lineEnd = line.from + line.length + line.trailingSpaces;
- int pos = qBound(0, *cursorPos, lineEnd);
+ int pos = qBound(line.from, *cursorPos, lineEnd);
int itm;
const QCharAttributes *attributes = eng->attributes();
if (!attributes) {
- *cursorPos = 0;
+ *cursorPos = line.from;
return x.toReal();
}
while (pos < lineEnd && !attributes[pos].graphemeBoundary)
@@ -2655,7 +2653,7 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
else
itm = eng->findItem(pos);
if (itm < 0) {
- *cursorPos = 0;
+ *cursorPos = line.from;
return x.toReal();
}
eng->shapeLine(line);
@@ -2663,18 +2661,14 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
const QScriptItem *si = &eng->layoutData->items[itm];
if (!si->num_glyphs)
eng->shape(itm);
- pos -= si->position;
+
+ const int l = eng->length(itm);
+ pos = qBound(0, pos - si->position, l);
QGlyphLayout glyphs = eng->shapedGlyphs(si);
unsigned short *logClusters = eng->logClusters(si);
Q_ASSERT(logClusters);
- int l = eng->length(itm);
- if (pos > l)
- pos = l;
- if (pos < 0)
- pos = 0;
-
int glyph_pos = pos == l ? si->num_glyphs : logClusters[pos];
if (edge == Trailing && glyph_pos < si->num_glyphs) {
// trailing edge is leading edge of next cluster
@@ -2683,13 +2677,13 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
glyph_pos++;
}
- bool reverse = eng->layoutData->items[itm].analysis.bidiLevel % 2;
+ bool reverse = si->analysis.bidiLevel % 2;
// add the items left of the cursor
int firstItem = eng->findItem(line.from);
- int lastItem = eng->findItem(lineEnd - 1);
+ int lastItem = eng->findItem(lineEnd - 1, itm);
int nItems = (firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0;
QVarLengthArray<int> visualOrder(nItems);
@@ -2710,13 +2704,15 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
x += si.width;
continue;
}
+
+ const int itemLength = eng->length(item);
int start = qMax(line.from, si.position);
- int end = qMin(lineEnd, si.position + eng->length(item));
+ int end = qMin(lineEnd, si.position + itemLength);
logClusters = eng->logClusters(&si);
int gs = logClusters[start-si.position];
- int ge = (end == si.position + eng->length(item)) ? si.num_glyphs-1 : logClusters[end-si.position-1];
+ int ge = (end == si.position + itemLength) ? si.num_glyphs-1 : logClusters[end-si.position-1];
QGlyphLayout glyphs = eng->shapedGlyphs(&si);
@@ -2788,7 +2784,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
return line.from;
int firstItem = eng->findItem(line.from);
- int lastItem = eng->findItem(line.from + line_length - 1);
+ int lastItem = eng->findItem(line.from + line_length - 1, firstItem);
int nItems = (firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0;
if (!nItems)
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
index 2a39fc1bbd..02217a7179 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -717,15 +717,19 @@ QStringList QFontconfigDatabase::fallbacksForFamily(const QString &family, QFont
FcPatternDestroy(pattern);
if (fontSet) {
+ QSet<QString> duplicates;
+ duplicates.reserve(fontSet->nfont + 1);
+ duplicates.insert(family.toCaseFolded());
for (int i = 0; i < fontSet->nfont; i++) {
FcChar8 *value = 0;
if (FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
continue;
// capitalize(value);
- QString familyName = QString::fromUtf8((const char *)value);
- if (!fallbackFamilies.contains(familyName,Qt::CaseInsensitive) &&
- familyName.compare(family, Qt::CaseInsensitive)) {
+ const QString familyName = QString::fromUtf8((const char *)value);
+ const QString familyNameCF = familyName.toCaseFolded();
+ if (!duplicates.contains(familyNameCF)) {
fallbackFamilies << familyName;
+ duplicates.insert(familyNameCF);
}
}
FcFontSetDestroy(fontSet);
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index e754855e7f..a3541829c6 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -99,6 +99,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
- (void)textInputContextKeyboardSelectionDidChangeNotification : (NSNotification *) textInputContextKeyboardSelectionDidChangeNotification;
- (void)viewDidHide;
- (void)viewDidUnhide;
+- (void)removeFromSuperview;
- (BOOL)isFlipped;
- (BOOL)acceptsFirstResponder;
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index f414193bdb..3faa292ae0 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -498,6 +498,12 @@ QT_WARNING_POP
m_platformWindow->exposeWindow();
}
+- (void)removeFromSuperview
+{
+ QMacAutoReleasePool pool;
+ [super removeFromSuperview];
+}
+
- (void) flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset
{
m_backingStore = backingStore;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro
index 98797e2106..2026b6a6c6 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro
@@ -12,6 +12,9 @@ CONFIG += egl
LIBS += -lbcm_host
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
+# Avoid X11 header collision
+DEFINES += MESA_EGL_NO_X11_HEADERS
+
SOURCES += $$PWD/qeglfsbrcmmain.cpp \
$$PWD/qeglfsbrcmintegration.cpp
diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm
index eaff0daf19..0e3da8dce8 100644
--- a/src/plugins/platforms/ios/qiosintegration.mm
+++ b/src/plugins/platforms/ios/qiosintegration.mm
@@ -89,10 +89,11 @@ QIOSIntegration::QIOSIntegration()
// Set current directory to app bundle folder
QDir::setCurrent(QString::fromUtf8([[[NSBundle mainBundle] bundlePath] UTF8String]));
+ UIScreen *mainScreen = [UIScreen mainScreen];
NSMutableArray *screens = [[[UIScreen screens] mutableCopy] autorelease];
- if (![screens containsObject:[UIScreen mainScreen]]) {
+ if (![screens containsObject:mainScreen]) {
// Fallback for iOS 7.1 (QTBUG-42345)
- [screens insertObject:[UIScreen mainScreen] atIndex:0];
+ [screens insertObject:mainScreen atIndex:0];
}
for (UIScreen *screen in screens)
@@ -103,7 +104,10 @@ QIOSIntegration::QIOSIntegration()
m_touchDevice = new QTouchDevice;
m_touchDevice->setType(QTouchDevice::TouchScreen);
- m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition);
+ QTouchDevice::Capabilities touchCapabilities = QTouchDevice::Position | QTouchDevice::NormalizedPosition;
+ if (mainScreen.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)
+ touchCapabilities |= QTouchDevice::Pressure;
+ m_touchDevice->setCapabilities(touchCapabilities);
QWindowSystemInterface::registerTouchDevice(m_touchDevice);
QMacInternalPasteboardMime::initializeMimeTypes();
}
diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm
index c6ef843b9f..53b3d30327 100644
--- a/src/plugins/platforms/ios/quiview.mm
+++ b/src/plugins/platforms/ios/quiview.mm
@@ -280,6 +280,19 @@
// -------------------------------------------------------------------------
+- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
+{
+ [super traitCollectionDidChange: previousTraitCollection];
+
+ QTouchDevice *touchDevice = QIOSIntegration::instance()->touchDevice();
+ QTouchDevice::Capabilities touchCapabilities = touchDevice->capabilities();
+ if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)
+ touchCapabilities |= QTouchDevice::Pressure;
+ else
+ touchCapabilities &= ~QTouchDevice::Pressure;
+ touchDevice->setCapabilities(touchCapabilities);
+}
+
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
if (m_qioswindow->window()->flags() & Qt::WindowTransparentForInput)
@@ -289,6 +302,8 @@
- (void)updateTouchList:(NSSet *)touches withState:(Qt::TouchPointState)state
{
+ bool supportsPressure = QIOSIntegration::instance()->touchDevice()->capabilities() & QTouchDevice::Pressure;
+
foreach (UITouch *uiTouch, m_activeTouches.keys()) {
QWindowSystemInterface::TouchPoint &touchPoint = m_activeTouches[uiTouch];
if (![touches containsObject:uiTouch]) {
@@ -309,9 +324,17 @@
touchPoint.normalPosition = QPointF(globalScreenPosition.x() / screenSize.width(),
globalScreenPosition.y() / screenSize.height());
- // We don't claim that our touch device supports QTouchDevice::Pressure,
- // but fill in a meaningfull value in case clients use it anyways.
- touchPoint.pressure = (state == Qt::TouchPointReleased) ? 0.0 : 1.0;
+ if (supportsPressure) {
+ // Note: iOS will deliver touchesBegan with a touch force of 0, which
+ // we will reflect/propagate as a 0 pressure, but there is no clear
+ // alternative, as we don't want to wait for a touchedMoved before
+ // sending a touch press event to Qt, just to have a valid pressure.
+ touchPoint.pressure = uiTouch.force / uiTouch.maximumPossibleForce;
+ } else {
+ // We don't claim that our touch device supports QTouchDevice::Pressure,
+ // but fill in a meaningfull value in case clients use it anyways.
+ touchPoint.pressure = (state == Qt::TouchPointReleased) ? 0.0 : 1.0;
+ }
}
}
}
diff --git a/src/plugins/platforms/mirclient/qmirclientplugin.cpp b/src/plugins/platforms/mirclient/qmirclientplugin.cpp
index 43d913f8d2..203a1cbfd8 100644
--- a/src/plugins/platforms/mirclient/qmirclientplugin.cpp
+++ b/src/plugins/platforms/mirclient/qmirclientplugin.cpp
@@ -49,11 +49,6 @@ QPlatformIntegration* QMirClientIntegrationPlugin::create(const QString &system,
const QStringList &)
{
if (system.toLower() == "mirclient") {
-#ifdef PLATFORM_API_TOUCH
- setenv("UBUNTU_PLATFORM_API_BACKEND", "touch_mirclient", 1);
-#else
- setenv("UBUNTU_PLATFORM_API_BACKEND", "desktop_mirclient", 1);
-#endif
return new QMirClientClientIntegration;
} else {
return 0;
diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp
index 800b79347c..c769eb04a4 100644
--- a/src/plugins/platforms/windows/qwindowscursor.cpp
+++ b/src/plugins/platforms/windows/qwindowscursor.cpp
@@ -43,15 +43,17 @@
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
#include <QtGui/private/qguiapplication_p.h> // getPixmapCursor()
+#include <QtGui/private/qhighdpiscaling_p.h>
#include <QtCore/QDebug>
#include <QtCore/QScopedArrayPointer>
-static void initResources()
+static bool initResources()
{
#if !defined (Q_OS_WINCE) && !defined (QT_NO_IMAGEFORMAT_PNG)
Q_INIT_RESOURCE(cursors);
#endif
+ return true;
}
QT_BEGIN_NAMESPACE
@@ -92,9 +94,14 @@ QWindowsPixmapCursorCacheKey::QWindowsPixmapCursorCacheKey(const QCursor &c)
\sa QWindowsWindowCursor
*/
-HCURSOR QWindowsCursor::createPixmapCursor(const QPixmap &pixmap, const QPoint &hotSpot)
+HCURSOR QWindowsCursor::createPixmapCursor(QPixmap pixmap, const QPoint &hotSpot, qreal scaleFactor)
{
HCURSOR cur = 0;
+ scaleFactor /= pixmap.devicePixelRatioF();
+ if (!qFuzzyCompare(scaleFactor, 1)) {
+ pixmap = pixmap.scaled((scaleFactor * QSizeF(pixmap.size())).toSize(),
+ Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ }
QBitmap mask = pixmap.mask();
if (mask.isNull()) {
mask = QBitmap(pixmap.size());
@@ -202,17 +209,43 @@ static HCURSOR createBitmapCursor(const QImage &bbits, const QImage &mbits,
}
// Create a cursor from image and mask of the format QImage::Format_Mono.
-static HCURSOR createBitmapCursor(const QCursor &cursor)
+static HCURSOR createBitmapCursor(const QCursor &cursor, qreal scaleFactor = 1)
{
Q_ASSERT(cursor.shape() == Qt::BitmapCursor && cursor.bitmap());
- const QImage bbits = cursor.bitmap()->toImage().convertToFormat(QImage::Format_Mono);
- const QImage mbits = cursor.mask()->toImage().convertToFormat(QImage::Format_Mono);
+ QImage bbits = cursor.bitmap()->toImage();
+ QImage mbits = cursor.mask()->toImage();
+ scaleFactor /= bbits.devicePixelRatioF();
+ if (!qFuzzyCompare(scaleFactor, 1)) {
+ const QSize scaledSize = (QSizeF(bbits.size()) * scaleFactor).toSize();
+ bbits = bbits.scaled(scaledSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ mbits = mbits.scaled(scaledSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ }
+ bbits = bbits.convertToFormat(QImage::Format_Mono);
+ mbits = mbits.convertToFormat(QImage::Format_Mono);
const bool invb = bbits.colorCount() > 1 && qGray(bbits.color(0)) < qGray(bbits.color(1));
const bool invm = mbits.colorCount() > 1 && qGray(mbits.color(0)) < qGray(mbits.color(1));
return createBitmapCursor(bbits, mbits, cursor.hotSpot(), invb, invm);
}
-static inline QSize systemCursorSize() { return QSize(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR)); }
+static QSize systemCursorSize(const QPlatformScreen *screen = Q_NULLPTR)
+{
+ const QSize primaryScreenCursorSize(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR));
+ if (screen) {
+ // Correct the size if the DPI value of the screen differs from
+ // that of the primary screen.
+ if (const QScreen *primaryQScreen = QGuiApplication::primaryScreen()) {
+ const QPlatformScreen *primaryScreen = primaryQScreen->handle();
+ if (screen != primaryScreen) {
+ const qreal logicalDpi = screen->logicalDpi().first;
+ const qreal primaryScreenLogicalDpi = primaryScreen->logicalDpi().first;
+ if (!qFuzzyCompare(logicalDpi, primaryScreenLogicalDpi))
+ return (QSizeF(primaryScreenCursorSize) * logicalDpi / primaryScreenLogicalDpi).toSize();
+ }
+ }
+ }
+ return primaryScreenCursorSize;
+}
+
static inline QSize standardCursorSize() { return QSize(32, 32); }
#if defined (Q_OS_WINCE) || defined (QT_NO_IMAGEFORMAT_PNG)
@@ -242,7 +275,8 @@ static QWindowsCursor::PixmapCursor createPixmapCursorFromData(const QSize &syst
return QWindowsCursor::PixmapCursor(rawImage, hotSpot);
}
-QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape)
+QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape,
+ const QPlatformScreen *screen)
{
// Non-standard Windows cursors are created from bitmaps
static const uchar vsplit_bits[] = {
@@ -410,13 +444,13 @@ QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursor
switch (cursorShape) {
case Qt::SplitVCursor:
- return createPixmapCursorFromData(systemCursorSize(), standardCursorSize(), 32, vsplit_bits, vsplitm_bits);
+ return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 32, vsplit_bits, vsplitm_bits);
case Qt::SplitHCursor:
- return createPixmapCursorFromData(systemCursorSize(), standardCursorSize(), 32, hsplit_bits, hsplitm_bits);
+ return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 32, hsplit_bits, hsplitm_bits);
case Qt::OpenHandCursor:
- return createPixmapCursorFromData(systemCursorSize(), standardCursorSize(), 16, openhand_bits, openhandm_bits);
+ return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 16, openhand_bits, openhandm_bits);
case Qt::ClosedHandCursor:
- return createPixmapCursorFromData(systemCursorSize(), standardCursorSize(), 16, closedhand_bits, closedhandm_bits);
+ return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 16, closedhand_bits, closedhandm_bits);
case Qt::DragCopyCursor:
return QWindowsCursor::PixmapCursor(QPixmap(copyDragCursorXpmC), QPoint(0, 0));
case Qt::DragMoveCursor:
@@ -436,7 +470,7 @@ struct QWindowsCustomPngCursor {
int hotSpotY;
};
-QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape)
+QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape, const QPlatformScreen *screen)
{
static const QWindowsCustomPngCursor pngCursors[] = {
{ Qt::SplitVCursor, 32, "splitvcursor_32.png", 11, 11 },
@@ -462,14 +496,14 @@ QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursor
{ Qt::DragLinkCursor, 64, "draglinkcursor_64.png", 0, 0 }
};
- const int cursorSize = GetSystemMetrics(SM_CXCURSOR);
+ const QSize cursorSize = systemCursorSize(screen);
const QWindowsCustomPngCursor *sEnd = pngCursors + sizeof(pngCursors) / sizeof(pngCursors[0]);
const QWindowsCustomPngCursor *bestFit = 0;
int sizeDelta = INT_MAX;
for (const QWindowsCustomPngCursor *s = pngCursors; s < sEnd; ++s) {
if (s->shape != cursorShape)
continue;
- const int currentSizeDelta = qMax(s->size, cursorSize) - qMin(s->size, cursorSize);
+ const int currentSizeDelta = qMax(s->size, cursorSize.width()) - qMin(s->size, cursorSize.width());
if (currentSizeDelta < sizeDelta) {
bestFit = s;
if (currentSizeDelta == 0)
@@ -492,7 +526,7 @@ struct QWindowsStandardCursorMapping {
LPCWSTR resource;
};
-HCURSOR QWindowsCursor::createCursorFromShape(Qt::CursorShape cursorShape)
+HCURSOR QWindowsCursor::createCursorFromShape(Qt::CursorShape cursorShape, const QPlatformScreen *screen)
{
Q_ASSERT(cursorShape != Qt::BitmapCursor);
@@ -515,7 +549,7 @@ HCURSOR QWindowsCursor::createCursorFromShape(Qt::CursorShape cursorShape)
switch (cursorShape) {
case Qt::BlankCursor: {
- QImage blank = QImage(systemCursorSize(), QImage::Format_Mono);
+ QImage blank = QImage(systemCursorSize(screen), QImage::Format_Mono);
blank.fill(0); // ignore color table
return createBitmapCursor(blank, blank);
}
@@ -526,7 +560,7 @@ HCURSOR QWindowsCursor::createCursorFromShape(Qt::CursorShape cursorShape)
case Qt::DragCopyCursor:
case Qt::DragMoveCursor:
case Qt::DragLinkCursor:
- return QWindowsCursor::createPixmapCursor(customCursor(cursorShape));
+ return QWindowsCursor::createPixmapCursor(customCursor(cursorShape, screen));
default:
break;
}
@@ -555,7 +589,7 @@ CursorHandlePtr QWindowsCursor::standardWindowCursor(Qt::CursorShape shape)
{
StandardCursorCache::Iterator it = m_standardCursorCache.find(shape);
if (it == m_standardCursorCache.end()) {
- if (const HCURSOR hc = QWindowsCursor::createCursorFromShape(shape))
+ if (const HCURSOR hc = QWindowsCursor::createCursorFromShape(shape, m_screen))
it = m_standardCursorCache.insert(shape, CursorHandlePtr(new CursorHandle(hc)));
}
return it != m_standardCursorCache.end() ? it.value() : CursorHandlePtr(new CursorHandle);
@@ -582,17 +616,21 @@ CursorHandlePtr QWindowsCursor::pixmapWindowCursor(const QCursor &c)
++it;
}
}
+ const qreal scaleFactor = QHighDpiScaling::factor(m_screen);
const QPixmap pixmap = c.pixmap();
const HCURSOR hc = pixmap.isNull()
- ? createBitmapCursor(c) : QWindowsCursor::createPixmapCursor(pixmap, c.hotSpot());
+ ? createBitmapCursor(c, scaleFactor)
+ : QWindowsCursor::createPixmapCursor(pixmap, c.hotSpot(), scaleFactor);
it = m_pixmapCursorCache.insert(cacheKey, CursorHandlePtr(new CursorHandle(hc)));
}
return it.value();
}
-QWindowsCursor::QWindowsCursor()
+QWindowsCursor::QWindowsCursor(const QPlatformScreen *screen)
+ : m_screen(screen)
{
- initResources();
+ static const bool dummy = initResources();
+ Q_UNUSED(dummy)
}
/*!
@@ -654,6 +692,94 @@ void QWindowsCursor::setPos(const QPoint &pos)
SetCursorPos(pos.x() , pos.y());
}
+QPixmap QWindowsCursor::dragDefaultCursor(Qt::DropAction action) const
+{
+ switch (action) {
+ case Qt::CopyAction:
+ if (m_copyDragCursor.isNull())
+ m_copyDragCursor = QWindowsCursor::customCursor(Qt::DragCopyCursor, m_screen).pixmap;
+ return m_copyDragCursor;
+ case Qt::TargetMoveAction:
+ case Qt::MoveAction:
+ if (m_moveDragCursor.isNull())
+ m_moveDragCursor = QWindowsCursor::customCursor(Qt::DragMoveCursor, m_screen).pixmap;
+ return m_moveDragCursor;
+ case Qt::LinkAction:
+ if (m_linkDragCursor.isNull())
+ m_linkDragCursor = QWindowsCursor::customCursor(Qt::DragLinkCursor, m_screen).pixmap;
+ return m_linkDragCursor;
+ default:
+ break;
+ }
+
+ static const char * const ignoreDragCursorXpmC[] = {
+ "24 30 3 1",
+ ". c None",
+ "a c #000000",
+ "X c #FFFFFF",
+ "aa......................",
+ "aXa.....................",
+ "aXXa....................",
+ "aXXXa...................",
+ "aXXXXa..................",
+ "aXXXXXa.................",
+ "aXXXXXXa................",
+ "aXXXXXXXa...............",
+ "aXXXXXXXXa..............",
+ "aXXXXXXXXXa.............",
+ "aXXXXXXaaaa.............",
+ "aXXXaXXa................",
+ "aXXaaXXa................",
+ "aXa..aXXa...............",
+ "aa...aXXa...............",
+ "a.....aXXa..............",
+ "......aXXa.....XXXX.....",
+ ".......aXXa..XXaaaaXX...",
+ ".......aXXa.XaaaaaaaaX..",
+ "........aa.XaaaXXXXaaaX.",
+ "...........XaaaaX..XaaX.",
+ "..........XaaXaaaX..XaaX",
+ "..........XaaXXaaaX.XaaX",
+ "..........XaaX.XaaaXXaaX",
+ "..........XaaX..XaaaXaaX",
+ "...........XaaX..XaaaaX.",
+ "...........XaaaXXXXaaaX.",
+ "............XaaaaaaaaX..",
+ ".............XXaaaaXX...",
+ "...............XXXX....."};
+
+ if (m_ignoreDragCursor.isNull()) {
+#if !defined (Q_OS_WINCE)
+ HCURSOR cursor = LoadCursor(NULL, IDC_NO);
+ ICONINFO iconInfo = {0, 0, 0, 0, 0};
+ GetIconInfo(cursor, &iconInfo);
+ BITMAP bmColor = {0, 0, 0, 0, 0, 0, 0};
+
+ if (iconInfo.hbmColor
+ && GetObject(iconInfo.hbmColor, sizeof(BITMAP), &bmColor)
+ && bmColor.bmWidth == bmColor.bmWidthBytes / 4) {
+ const int colorBitsLength = bmColor.bmHeight * bmColor.bmWidthBytes;
+ uchar *colorBits = new uchar[colorBitsLength];
+ GetBitmapBits(iconInfo.hbmColor, colorBitsLength, colorBits);
+ const QImage colorImage(colorBits, bmColor.bmWidth, bmColor.bmHeight,
+ bmColor.bmWidthBytes, QImage::Format_ARGB32);
+
+ m_ignoreDragCursor = QPixmap::fromImage(colorImage);
+ delete [] colorBits;
+ } else {
+ m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC);
+ }
+
+ DeleteObject(iconInfo.hbmMask);
+ DeleteObject(iconInfo.hbmColor);
+ DestroyCursor(cursor);
+#else // !Q_OS_WINCE
+ m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC);
+#endif // !Q_OS_WINCE
+ }
+ return m_ignoreDragCursor;
+}
+
/*!
\class QWindowsWindowCursor
\brief Per-Window cursor. Contains a QCursor and manages its associated system
diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h
index ac9e87d1fb..e93f779f94 100644
--- a/src/plugins/platforms/windows/qwindowscursor.h
+++ b/src/plugins/platforms/windows/qwindowscursor.h
@@ -96,29 +96,37 @@ public:
QPoint hotSpot;
};
- QWindowsCursor();
+ explicit QWindowsCursor(const QPlatformScreen *screen);
void changeCursor(QCursor * widgetCursor, QWindow * widget) Q_DECL_OVERRIDE;
QPoint pos() const Q_DECL_OVERRIDE;
void setPos(const QPoint &pos) Q_DECL_OVERRIDE;
- static HCURSOR createPixmapCursor(const QPixmap &pixmap, const QPoint &hotSpot);
- static HCURSOR createPixmapCursor(const PixmapCursor &pc) { return createPixmapCursor(pc.pixmap, pc.hotSpot); }
- static PixmapCursor customCursor(Qt::CursorShape cursorShape);
+ static HCURSOR createPixmapCursor(QPixmap pixmap, const QPoint &hotSpot, qreal scaleFactor = 1);
+ static HCURSOR createPixmapCursor(const PixmapCursor &pc, qreal scaleFactor = 1) { return createPixmapCursor(pc.pixmap, pc.hotSpot, scaleFactor); }
+ static PixmapCursor customCursor(Qt::CursorShape cursorShape, const QPlatformScreen *screen = Q_NULLPTR);
- static HCURSOR createCursorFromShape(Qt::CursorShape cursorShape);
+ static HCURSOR createCursorFromShape(Qt::CursorShape cursorShape, const QPlatformScreen *screen = Q_NULLPTR);
static QPoint mousePosition();
static CursorState cursorState();
CursorHandlePtr standardWindowCursor(Qt::CursorShape s = Qt::ArrowCursor);
CursorHandlePtr pixmapWindowCursor(const QCursor &c);
+ QPixmap dragDefaultCursor(Qt::DropAction action) const;
+
private:
typedef QHash<Qt::CursorShape, CursorHandlePtr> StandardCursorCache;
typedef QHash<QWindowsPixmapCursorCacheKey, CursorHandlePtr> PixmapCursorCache;
+ const QPlatformScreen *const m_screen;
StandardCursorCache m_standardCursorCache;
PixmapCursorCache m_pixmapCursorCache;
+
+ mutable QPixmap m_copyDragCursor;
+ mutable QPixmap m_moveDragCursor;
+ mutable QPixmap m_linkDragCursor;
+ mutable QPixmap m_ignoreDragCursor;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp
index 5435c4820a..c68f05b5bb 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.cpp
+++ b/src/plugins/platforms/windows/qwindowsdrag.cpp
@@ -269,13 +269,6 @@ QDebug operator<<(QDebug d, const QWindowsOleDropSource::CursorEntry &e)
}
#endif // !QT_NO_DEBUG_STREAM
-static qreal dragScaleFactor()
-{
- const QWindowsScreenManager &screenManager = QWindowsContext::instance()->screenManager();
- const QWindowsScreen *screen = screenManager.screenAtDp(QWindowsCursor::mousePosition());
- return screen ? QHighDpiScaling::factor(screen) : qreal(1);
-}
-
/*!
\brief Blend custom pixmap with cursors.
*/
@@ -286,7 +279,17 @@ void QWindowsOleDropSource::createCursors()
const QPixmap pixmap = drag->pixmap();
const bool hasPixmap = !pixmap.isNull();
- const qreal scaleFactor = dragScaleFactor();
+ // Find screen for drag. Could be obtained from QDrag::source(), but that might be a QWidget.
+
+ qreal scaleFactor = 1;
+ QPlatformCursor *platformCursor = Q_NULLPTR;
+ if (const QPlatformScreen *platformScreen = QWindowsContext::instance()->screenManager().screenAtDp(QWindowsCursor::mousePosition())) {
+ scaleFactor = QHighDpiScaling::factor(platformScreen);
+ platformCursor = platformScreen->cursor();
+ }
+ if (!platformCursor && QGuiApplication::primaryScreen())
+ platformCursor = QGuiApplication::primaryScreen()->handle()->cursor();
+
const bool scalePixmap = hasPixmap
&& m_mode != TouchDrag // Touch drag: pixmap is shown in a separate QWindow, which will be scaled.
&& (scaleFactor != 1 && scaleFactor != qRound(pixmap.devicePixelRatio()));
@@ -304,8 +307,8 @@ void QWindowsOleDropSource::createCursors()
for (int cnum = 0; cnum < actionCount; ++cnum) {
const Qt::DropAction action = actions[cnum];
QPixmap cursorPixmap = drag->dragCursor(action);
- if (cursorPixmap.isNull())
- cursorPixmap = m_drag->defaultCursor(action);
+ if (cursorPixmap.isNull() && platformCursor)
+ cursorPixmap = static_cast<QWindowsCursor *>(platformCursor)->dragDefaultCursor(action);
const qint64 cacheKey = cursorPixmap.cacheKey();
const auto it = m_cursors.find(action);
if (it != m_cursors.end() && it.value().cacheKey == cacheKey)
@@ -704,94 +707,6 @@ IDropTargetHelper* QWindowsDrag::dropHelper() {
return m_cachedDropTargetHelper;
}
-QPixmap QWindowsDrag::defaultCursor(Qt::DropAction action) const
-{
- switch (action) {
- case Qt::CopyAction:
- if (m_copyDragCursor.isNull())
- m_copyDragCursor = QWindowsCursor::customCursor(Qt::DragCopyCursor).pixmap;
- return m_copyDragCursor;
- case Qt::TargetMoveAction:
- case Qt::MoveAction:
- if (m_moveDragCursor.isNull())
- m_moveDragCursor = QWindowsCursor::customCursor(Qt::DragMoveCursor).pixmap;
- return m_moveDragCursor;
- case Qt::LinkAction:
- if (m_linkDragCursor.isNull())
- m_linkDragCursor = QWindowsCursor::customCursor(Qt::DragLinkCursor).pixmap;
- return m_linkDragCursor;
- default:
- break;
- }
-
- static const char * const ignoreDragCursorXpmC[] = {
- "24 30 3 1",
- ". c None",
- "a c #000000",
- "X c #FFFFFF",
- "aa......................",
- "aXa.....................",
- "aXXa....................",
- "aXXXa...................",
- "aXXXXa..................",
- "aXXXXXa.................",
- "aXXXXXXa................",
- "aXXXXXXXa...............",
- "aXXXXXXXXa..............",
- "aXXXXXXXXXa.............",
- "aXXXXXXaaaa.............",
- "aXXXaXXa................",
- "aXXaaXXa................",
- "aXa..aXXa...............",
- "aa...aXXa...............",
- "a.....aXXa..............",
- "......aXXa.....XXXX.....",
- ".......aXXa..XXaaaaXX...",
- ".......aXXa.XaaaaaaaaX..",
- "........aa.XaaaXXXXaaaX.",
- "...........XaaaaX..XaaX.",
- "..........XaaXaaaX..XaaX",
- "..........XaaXXaaaX.XaaX",
- "..........XaaX.XaaaXXaaX",
- "..........XaaX..XaaaXaaX",
- "...........XaaX..XaaaaX.",
- "...........XaaaXXXXaaaX.",
- "............XaaaaaaaaX..",
- ".............XXaaaaXX...",
- "...............XXXX....."};
-
- if (m_ignoreDragCursor.isNull()) {
-#if !defined (Q_OS_WINCE)
- HCURSOR cursor = LoadCursor(NULL, IDC_NO);
- ICONINFO iconInfo = {0, 0, 0, 0, 0};
- GetIconInfo(cursor, &iconInfo);
- BITMAP bmColor = {0, 0, 0, 0, 0, 0, 0};
-
- if (iconInfo.hbmColor
- && GetObject(iconInfo.hbmColor, sizeof(BITMAP), &bmColor)
- && bmColor.bmWidth == bmColor.bmWidthBytes / 4) {
- const int colorBitsLength = bmColor.bmHeight * bmColor.bmWidthBytes;
- uchar *colorBits = new uchar[colorBitsLength];
- GetBitmapBits(iconInfo.hbmColor, colorBitsLength, colorBits);
- const QImage colorImage(colorBits, bmColor.bmWidth, bmColor.bmHeight,
- bmColor.bmWidthBytes, QImage::Format_ARGB32);
-
- m_ignoreDragCursor = QPixmap::fromImage(colorImage);
- delete [] colorBits;
- } else {
- m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC);
- }
-
- DeleteObject(iconInfo.hbmMask);
- DeleteObject(iconInfo.hbmColor);
- DestroyCursor(cursor);
-#else // !Q_OS_WINCE
- m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC);
-#endif // !Q_OS_WINCE
- }
- return m_ignoreDragCursor;
-}
-
Qt::DropAction QWindowsDrag::drag(QDrag *drag)
{
// TODO: Accessibility handling?
diff --git a/src/plugins/platforms/windows/qwindowsdrag.h b/src/plugins/platforms/windows/qwindowsdrag.h
index b031faa884..ebe949a6af 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.h
+++ b/src/plugins/platforms/windows/qwindowsdrag.h
@@ -42,6 +42,9 @@
struct IDropTargetHelper;
QT_BEGIN_NAMESPACE
+
+class QPlatformScreen;
+
class QWindowsDropMimeData : public QWindowsInternalMimeData {
public:
QWindowsDropMimeData() {}
@@ -97,8 +100,6 @@ public:
IDropTargetHelper* dropHelper();
- QPixmap defaultCursor(Qt::DropAction action) const;
-
private:
static bool m_canceled;
@@ -106,11 +107,6 @@ private:
IDataObject *m_dropDataObject;
IDropTargetHelper* m_cachedDropTargetHelper;
-
- mutable QPixmap m_copyDragCursor;
- mutable QPixmap m_moveDragCursor;
- mutable QPixmap m_linkDragCursor;
- mutable QPixmap m_ignoreDragCursor;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index de4ef79b81..e69665e4a9 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -195,16 +195,6 @@ static QDebug operator<<(QDebug dbg, const QWindowsScreenData &d)
}
#endif // !QT_NO_DEBUG_STREAM
-// Return the cursor to be shared by all screens (virtual desktop).
-static inline QSharedPointer<QPlatformCursor> sharedCursor()
-{
-#ifndef QT_NO_CURSOR
- if (const QScreen *primaryScreen = QGuiApplication::primaryScreen())
- return static_cast<const QWindowsScreen *>(primaryScreen->handle())->cursorPtr();
-#endif
- return QSharedPointer<QPlatformCursor>(new QWindowsCursor);
-}
-
/*!
\class QWindowsScreen
\brief Windows screen.
@@ -216,7 +206,7 @@ static inline QSharedPointer<QPlatformCursor> sharedCursor()
QWindowsScreen::QWindowsScreen(const QWindowsScreenData &data) :
m_data(data)
#ifndef QT_NO_CURSOR
- ,m_cursor(sharedCursor())
+ , m_cursor(new QWindowsCursor(this))
#endif
{
}
diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h
index bc8fbf553b..879cda047e 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.h
+++ b/src/plugins/platforms/windows/qwindowsscreen.h
@@ -42,7 +42,7 @@
#include <QtCore/QList>
#include <QtCore/QVector>
#include <QtCore/QPair>
-#include <QtCore/QSharedPointer>
+#include <QtCore/QScopedPointer>
#include <qpa/qplatformscreen.h>
QT_BEGIN_NAMESPACE
@@ -74,7 +74,7 @@ class QWindowsScreen : public QPlatformScreen
{
public:
#ifndef QT_NO_CURSOR
- typedef QSharedPointer<QPlatformCursor> CursorPtr;
+ typedef QScopedPointer<QPlatformCursor> CursorPtr;
#endif
explicit QWindowsScreen(const QWindowsScreenData &data);
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index 158917184c..a642443386 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -507,6 +507,8 @@ QWinRTScreen::QWinRTScreen()
hr = d->displayInformation->get_NativeOrientation(&displayOrientation);
Q_ASSERT_SUCCEEDED(hr);
d->nativeOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation)));
+ // Set initial pixel density
+ onDpiChanged(Q_NULLPTR, Q_NULLPTR);
d->orientation = d->nativeOrientation;
ComPtr<IApplicationViewStatics2> applicationViewStatics;
@@ -753,7 +755,6 @@ void QWinRTScreen::initialize()
Q_ASSERT_SUCCEEDED(hr);
hr = d->displayInformation->add_DpiChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onDpiChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_DpiChanged]);
Q_ASSERT_SUCCEEDED(hr);
- onDpiChanged(Q_NULLPTR, Q_NULLPTR);
onOrientationChanged(Q_NULLPTR, Q_NULLPTR);
onVisibilityChanged(nullptr, nullptr);
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 901764bbf8..50d49ca798 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -1086,8 +1086,12 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
case XCB_FOCUS_OUT:
HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_out_event_t, event, handleFocusOutEvent);
case XCB_KEY_PRESS:
- m_keyboard->updateXKBStateFromCore(((xcb_key_press_event_t *)event)->state);
+ {
+ xcb_key_press_event_t *kp = (xcb_key_press_event_t *)event;
+ m_keyboard->updateXKBStateFromCore(kp->state);
+ setTime(kp->time);
HANDLE_KEYBOARD_EVENT(xcb_key_press_event_t, handleKeyPressEvent);
+ }
case XCB_KEY_RELEASE:
m_keyboard->updateXKBStateFromCore(((xcb_key_release_event_t *)event)->state);
HANDLE_KEYBOARD_EVENT(xcb_key_release_event_t, handleKeyReleaseEvent);
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 55bae05523..db7d837e01 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -556,7 +556,8 @@ void QXcbScreen::updateRefreshRate(xcb_randr_mode_t mode)
for (; modesIter.rem; xcb_randr_mode_info_next(&modesIter)) {
xcb_randr_mode_info_t *modeInfo = modesIter.data;
if (modeInfo->id == mode) {
- m_refreshRate = modeInfo->dot_clock / (modeInfo->htotal * modeInfo->vtotal);
+ const uint32_t dotCount = modeInfo->htotal * modeInfo->vtotal;
+ m_refreshRate = (dotCount != 0) ? modeInfo->dot_clock / dotCount : 0;
m_mode = mode;
break;
}
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 5d052a7ca1..4bd4639833 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -314,8 +314,6 @@ void QXcbWindow::create()
destroy();
- m_deferredExpose = false;
- m_configureNotifyPending = true;
m_windowState = Qt::WindowNoState;
Qt::WindowType type = window()->type();
@@ -2032,12 +2030,8 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
if (newScreen != currentScreen)
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen());
- m_configureNotifyPending = false;
-
- if (m_deferredExpose) {
- m_deferredExpose = false;
+ if (m_mapped)
QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
- }
if (m_usingSyncProtocol && m_syncState == SyncReceived)
m_syncState = SyncAndConfigureReceived;
@@ -2104,10 +2098,8 @@ void QXcbWindow::handleMapNotifyEvent(const xcb_map_notify_event_t *event)
m_mapped = true;
if (m_deferredActivation)
requestActivateWindow();
- if (m_configureNotifyPending)
- m_deferredExpose = true;
- else
- QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
+
+ QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
}
}
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index 1a8e031779..c42c98c205 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -232,8 +232,6 @@ protected:
bool m_transparent;
bool m_usingSyncProtocol;
bool m_deferredActivation;
- bool m_deferredExpose;
- bool m_configureNotifyPending;
bool m_embedded;
bool m_alertState;
xcb_window_t m_netWmUserTimeWindow;
diff --git a/src/testlib/qsignalspy.h b/src/testlib/qsignalspy.h
index 1751220059..e9744d0b07 100644
--- a/src/testlib/qsignalspy.h
+++ b/src/testlib/qsignalspy.h
@@ -175,8 +175,11 @@ private:
tp = QMetaType::UnknownType;
}
if (tp == QMetaType::UnknownType) {
- qWarning("Don't know how to handle '%s', use qRegisterMetaType to register it.",
- member.parameterNames().at(i).constData());
+ qWarning("QSignalSpy: Unable to handle parameter '%s' of type '%s' of method '%s',"
+ " use qRegisterMetaType to register it.",
+ member.parameterNames().at(i).constData(),
+ member.parameterTypes().at(i).constData(),
+ member.name().constData());
}
args << tp;
}
diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp
index 1522b065a7..7051f970ff 100644
--- a/src/widgets/kernel/qopenglwidget.cpp
+++ b/src/widgets/kernel/qopenglwidget.cpp
@@ -1172,8 +1172,7 @@ void QOpenGLWidget::resizeEvent(QResizeEvent *e)
d->recreateFbo();
resizeGL(width(), height());
- d->invokeUserPaint();
- d->resolveSamples();
+ d->sendPaintEvent(QRect(QPoint(0, 0), size()));
}
/*!
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index e8169d0bd1..308403175a 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -271,6 +271,9 @@ QWidgetPrivate::QWidgetPrivate(int version)
#ifndef QT_NO_IM
, inheritsInputMethodHints(0)
#endif
+#ifndef QT_NO_OPENGL
+ , renderToTextureReallyDirty(1)
+#endif
#if defined(Q_OS_WIN)
, noPaintOnScreen(0)
#endif
@@ -5560,7 +5563,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
<< "geometry ==" << QRect(q->mapTo(q->window(), QPoint(0, 0)), q->size());
#endif
- bool grabbed = false;
+ bool skipPaintEvent = false;
#ifndef QT_NO_OPENGL
if (renderToTexture) {
// This widget renders into a texture which is composed later. We just need to
@@ -5574,14 +5577,18 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
} else {
// We are not drawing to a backingstore: fall back to QImage
p.drawImage(q->rect(), grabFramebuffer());
- grabbed = true;
+ skipPaintEvent = true;
}
endBackingStorePainting();
}
+ if (renderToTextureReallyDirty)
+ renderToTextureReallyDirty = 0;
+ else
+ skipPaintEvent = true;
}
#endif // QT_NO_OPENGL
- if (!grabbed) {
+ if (!skipPaintEvent) {
//actually send the paint event
sendPaintEvent(toBePainted);
}
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index a78cf099ac..7eb8d048b3 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -743,6 +743,9 @@ public:
#ifndef QT_NO_IM
uint inheritsInputMethodHints : 1;
#endif
+#ifndef QT_NO_OPENGL
+ uint renderToTextureReallyDirty : 1;
+#endif
// *************************** Platform specific ************************************
#if defined(Q_OS_WIN)
diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp
index 90311b0f0a..a108dcf03b 100644
--- a/src/widgets/kernel/qwidgetbackingstore.cpp
+++ b/src/widgets/kernel/qwidgetbackingstore.cpp
@@ -1000,6 +1000,16 @@ void QPlatformTextureListWatcher::onLockStatusChanged(bool locked)
if (!isLocked())
m_backingStore->sync();
}
+
+#else
+
+static QPlatformTextureList *widgetTexturesFor(QWidget *tlw, QWidget *widget)
+{
+ Q_UNUSED(tlw);
+ Q_UNUSED(widget);
+ return Q_NULLPTR;
+}
+
#endif // QT_NO_OPENGL
static inline bool discardSyncRequest(QWidget *tlw, QTLWExtra *tlwExtra)
@@ -1220,6 +1230,9 @@ void QWidgetBackingStore::doSync()
QWidget *w = static_cast<QWidget *>(tl->source(i));
if (dirtyRenderToTextureWidgets.contains(w)) {
const QRect rect = tl->geometry(i); // mapped to the tlw already
+ // Set a flag to indicate that the paint event for this
+ // render-to-texture widget must not to be optimized away.
+ w->d_func()->renderToTextureReallyDirty = 1;
dirty += rect;
toClean += rect;
}
diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp
index 20f5c95ae9..47bc88cb43 100644
--- a/src/widgets/util/qsystemtrayicon.cpp
+++ b/src/widgets/util/qsystemtrayicon.cpp
@@ -284,12 +284,6 @@ bool QSystemTrayIcon::isVisible() const
*/
bool QSystemTrayIcon::event(QEvent *e)
{
-#if defined(Q_DEAD_CODE_FROM_QT4_X11)
- if (e->type() == QEvent::ToolTip) {
- Q_D(QSystemTrayIcon);
- return d->sys->deliverToolTipEvent(e);
- }
-#endif
return QObject::event(e);
}
diff --git a/src/widgets/util/qsystemtrayicon_x11.cpp b/src/widgets/util/qsystemtrayicon_x11.cpp
index e50b0bd12c..13d58acebd 100644
--- a/src/widgets/util/qsystemtrayicon_x11.cpp
+++ b/src/widgets/util/qsystemtrayicon_x11.cpp
@@ -196,6 +196,9 @@ void QSystemTrayIconSys::mouseDoubleClickEvent(QMouseEvent *ev)
bool QSystemTrayIconSys::event(QEvent *e)
{
switch (e->type()) {
+ case QEvent::ToolTip:
+ QApplication::sendEvent(q, e);
+ break;
#ifndef QT_NO_WHEELEVENT
case QEvent::Wheel:
return QApplication::sendEvent(q, e);
diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
index 83da28767f..1c639c94a8 100644
--- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
+++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
@@ -38,6 +38,7 @@
#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QThread>
+#include <QtCore/QTemporaryDir>
#include <QtCore/QRegExp>
#include <QtCore/QDebug>
#include <QtCore/QMetaType>
@@ -54,14 +55,6 @@ Q_DECLARE_METATYPE(QProcess::ExitStatus);
Q_DECLARE_METATYPE(QProcess::ProcessState);
#endif
-#define QPROCESS_VERIFY(Process, Fn) \
-{ \
-const bool ret = Process.Fn; \
-if (ret == false) \
- qWarning("QProcess error: %d: %s", Process.error(), qPrintable(Process.errorString())); \
-QVERIFY(ret); \
-}
-
typedef void (QProcess::*QProcessFinishedSignal1)(int);
typedef void (QProcess::*QProcessFinishedSignal2)(int, QProcess::ExitStatus);
typedef void (QProcess::*QProcessErrorSignal)(QProcess::ProcessError);
@@ -180,6 +173,7 @@ protected slots:
private:
qint64 bytesAvailable;
+ QTemporaryDir m_temporaryDir;
#endif //QT_NO_PROCESS
};
@@ -188,6 +182,7 @@ void tst_QProcess::initTestCase()
#ifdef QT_NO_PROCESS
QSKIP("This test requires QProcess support");
#else
+ QVERIFY2(m_temporaryDir.isValid(), qPrintable(m_temporaryDir.errorString()));
// chdir to our testdata path and execute helper apps relative to that.
QString testdata_dir = QFileInfo(QFINDTESTDATA("testProcessNormal")).absolutePath();
QVERIFY2(QDir::setCurrent(testdata_dir), qPrintable("Could not chdir to " + testdata_dir));
@@ -1717,7 +1712,7 @@ void tst_QProcess::failToStartEmptyArgs()
// Reading and writing to a process is not supported on Qt/CE
void tst_QProcess::removeFileWhileProcessIsRunning()
{
- QFile file("removeFile.txt");
+ QFile file(m_temporaryDir.path() + QLatin1String("/removeFile.txt"));
QVERIFY(file.open(QFile::WriteOnly));
QProcess process;
@@ -1948,16 +1943,16 @@ void tst_QProcess::setStandardInputFile()
{
static const char data[] = "A bunch\1of\2data\3\4\5\6\7...";
QProcess process;
- QFile file("data");
+ QFile file(m_temporaryDir.path() + QLatin1String("/data-sif"));
QVERIFY(file.open(QIODevice::WriteOnly));
file.write(data, sizeof data);
file.close();
- process.setStandardInputFile("data");
+ process.setStandardInputFile(file.fileName());
process.start("testProcessEcho/testProcessEcho");
- QPROCESS_VERIFY(process, waitForFinished());
+ QVERIFY(process.waitForFinished());
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
QCOMPARE(process.exitCode(), 0);
QByteArray all = process.readAll();
@@ -1967,7 +1962,7 @@ void tst_QProcess::setStandardInputFile()
QProcess process2;
process2.setStandardInputFile(QProcess::nullDevice());
process2.start("testProcessEcho/testProcessEcho");
- QPROCESS_VERIFY(process2, waitForFinished());
+ QVERIFY(process2.waitForFinished());
all = process2.readAll();
QCOMPARE(all.size(), 0);
}
@@ -2016,7 +2011,7 @@ void tst_QProcess::setStandardOutputFile()
QIODevice::OpenMode mode = append ? QIODevice::Append : QIODevice::Truncate;
// create the destination file with data
- QFile file("data");
+ QFile file(m_temporaryDir.path() + QLatin1String("/data-stdof-") + QLatin1String(QTest::currentDataTag()));
QVERIFY(file.open(QIODevice::WriteOnly));
file.write(data, sizeof data - 1);
file.close();
@@ -2025,13 +2020,13 @@ void tst_QProcess::setStandardOutputFile()
QProcess process;
process.setReadChannelMode(channelMode);
if (channelToTest == QProcess::StandardOutput)
- process.setStandardOutputFile("data", mode);
+ process.setStandardOutputFile(file.fileName(), mode);
else
- process.setStandardErrorFile("data", mode);
+ process.setStandardErrorFile(file.fileName(), mode);
process.start("testProcessEcho2/testProcessEcho2");
process.write(testdata, sizeof testdata);
- QPROCESS_VERIFY(process,waitForFinished());
+ QVERIFY(process.waitForFinished());
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
QCOMPARE(process.exitCode(), 0);
@@ -2062,7 +2057,7 @@ void tst_QProcess::setStandardOutputFileNullDevice()
process.setStandardOutputFile(QProcess::nullDevice());
process.start("testProcessEcho2/testProcessEcho2");
process.write(testdata, sizeof testdata);
- QPROCESS_VERIFY(process,waitForFinished());
+ QVERIFY(process.waitForFinished());
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
QCOMPARE(process.exitCode(), 0);
QCOMPARE(process.bytesAvailable(), Q_INT64_C(0));
@@ -2074,13 +2069,14 @@ void tst_QProcess::setStandardOutputFileAndWaitForBytesWritten()
{
static const char testdata[] = "Test data.";
- QFile file("data");
+ QFile file(m_temporaryDir.path() + QLatin1String("/data-stdofawfbw"));
QProcess process;
process.setStandardOutputFile(file.fileName());
process.start("testProcessEcho2/testProcessEcho2");
+ QVERIFY2(process.waitForStarted(), qPrintable(process.errorString()));
process.write(testdata, sizeof testdata);
process.waitForBytesWritten();
- QPROCESS_VERIFY(process, waitForFinished());
+ QVERIFY(process.waitForFinished());
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
QCOMPARE(process.exitCode(), 0);
@@ -2122,10 +2118,10 @@ void tst_QProcess::setStandardOutputProcess()
if (waitForBytesWritten)
source.waitForBytesWritten();
source.closeWriteChannel();
- QPROCESS_VERIFY(source, waitForFinished());
+ QVERIFY(source.waitForFinished());
QCOMPARE(source.exitStatus(), QProcess::NormalExit);
QCOMPARE(source.exitCode(), 0);
- QPROCESS_VERIFY(sink, waitForFinished());
+ QVERIFY(sink.waitForFinished());
QCOMPARE(sink.exitStatus(), QProcess::NormalExit);
QCOMPARE(sink.exitCode(), 0);
QByteArray all = sink.readAll();
@@ -2151,14 +2147,15 @@ void tst_QProcess::fileWriterProcess()
QTime stopWatch;
stopWatch.start();
- const QString fileName = QLatin1String("fileWriterProcess.txt");
+ const QString fileName = m_temporaryDir.path() + QLatin1String("/fileWriterProcess.txt");
+ const QString binary = QDir::currentPath() + QLatin1String("/fileWriterProcess/fileWriterProcess");
do {
if (QFile::exists(fileName))
QVERIFY(QFile::remove(fileName));
QProcess process;
- process.start("fileWriterProcess/fileWriterProcess",
- QIODevice::ReadWrite | QIODevice::Text);
+ process.setWorkingDirectory(m_temporaryDir.path());
+ process.start(binary, QIODevice::ReadWrite | QIODevice::Text);
process.write(stdinStr);
process.closeWriteChannel();
while (process.bytesToWrite()) {
@@ -2181,8 +2178,9 @@ void tst_QProcess::detachedWorkingDirectoryAndPid()
QTest::qSleep(1000);
#endif
- QFile infoFile(QDir::currentPath() + QLatin1String("/detachedinfo.txt"));
- infoFile.remove();
+ QFile infoFile(m_temporaryDir.path() + QLatin1String("/detachedinfo.txt"));
+ if (infoFile.exists())
+ QVERIFY(infoFile.remove());
QString workingDir = QDir::currentPath() + "/testDetached";
diff --git a/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp b/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp
index 1531e0ac40..20ff670835 100644
--- a/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp
+++ b/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp
@@ -49,6 +49,9 @@ class tst_QItemModel : public QObject
{
Q_OBJECT
+public:
+ tst_QItemModel();
+
public slots:
void init();
void cleanup();
@@ -124,6 +127,11 @@ private:
bool insertRecursively;
};
+tst_QItemModel::tst_QItemModel()
+{
+ qRegisterMetaType<QAbstractItemModel::LayoutChangeHint>();
+}
+
void tst_QItemModel::init()
{
testModels = new ModelsToTest();
diff --git a/tests/auto/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp b/tests/auto/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp
index dea305e3e1..df52aa4949 100644
--- a/tests/auto/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp
+++ b/tests/auto/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp
@@ -33,6 +33,7 @@
#include <QtTest/QtTest>
+#include <qatomic.h>
#include <qcoreapplication.h>
#include <qmutex.h>
#include <qthread.h>
@@ -54,7 +55,25 @@ private slots:
static const int iterations = 4;
static const int ThreadCount = 4;
-class wait_QMutex_Thread_1 : public QThread
+// Terminate thread in destructor for threads instantiated on the stack
+class TerminatingThread : public QThread
+{
+public:
+ explicit TerminatingThread()
+ {
+ setTerminationEnabled(true);
+ }
+
+ ~TerminatingThread()
+ {
+ if (isRunning()) {
+ qWarning() << "forcibly terminating " << objectName();
+ terminate();
+ }
+ }
+};
+
+class wait_QMutex_Thread_1 : public TerminatingThread
{
public:
QMutex mutex;
@@ -72,7 +91,7 @@ public:
}
};
-class wait_QMutex_Thread_2 : public QThread
+class wait_QMutex_Thread_2 : public TerminatingThread
{
public:
QWaitCondition started;
@@ -93,7 +112,7 @@ public:
}
};
-class wait_QReadWriteLock_Thread_1 : public QThread
+class wait_QReadWriteLock_Thread_1 : public TerminatingThread
{
public:
QReadWriteLock readWriteLock;
@@ -111,7 +130,7 @@ public:
}
};
-class wait_QReadWriteLock_Thread_2 : public QThread
+class wait_QReadWriteLock_Thread_2 : public TerminatingThread
{
public:
QWaitCondition started;
@@ -155,7 +174,11 @@ void tst_QWaitCondition::wait_QMutex()
// test multiple threads waiting on separate wait conditions
wait_QMutex_Thread_1 thread[ThreadCount];
+ const QString prefix = QLatin1String(QTest::currentTestFunction()) + QLatin1String("_mutex_")
+ + QString::number(i) + QLatin1Char('_');
+
for (x = 0; x < ThreadCount; ++x) {
+ thread[x].setObjectName(prefix + QString::number(x));
thread[x].mutex.lock();
thread[x].start();
// wait for thread to start
@@ -185,8 +208,12 @@ void tst_QWaitCondition::wait_QMutex()
QWaitCondition cond1, cond2;
wait_QMutex_Thread_2 thread[ThreadCount];
+ const QString prefix = QLatin1String(QTest::currentTestFunction()) + QLatin1String("_mutex_")
+ + QString::number(i) + QLatin1Char('_');
+
mutex.lock();
for (x = 0; x < ThreadCount; ++x) {
+ thread[x].setObjectName(prefix + QString::number(x));
thread[x].mutex = &mutex;
thread[x].cond = (x < ThreadCount / 2) ? &cond1 : &cond2;
thread[x].start();
@@ -289,7 +316,10 @@ void tst_QWaitCondition::wait_QReadWriteLock()
// test multiple threads waiting on separate wait conditions
wait_QReadWriteLock_Thread_1 thread[ThreadCount];
+ const QString prefix = QLatin1String(QTest::currentTestFunction()) + QLatin1String("_lockforread_");
+
for (x = 0; x < ThreadCount; ++x) {
+ thread[x].setObjectName(prefix + QString::number(x));
thread[x].readWriteLock.lockForRead();
thread[x].start();
// wait for thread to start
@@ -319,8 +349,11 @@ void tst_QWaitCondition::wait_QReadWriteLock()
QWaitCondition cond1, cond2;
wait_QReadWriteLock_Thread_2 thread[ThreadCount];
+ const QString prefix = QLatin1String(QTest::currentTestFunction()) + QLatin1String("_lockforwrite_");
+
readWriteLock.lockForWrite();
for (x = 0; x < ThreadCount; ++x) {
+ thread[x].setObjectName(prefix + QString::number(x));
thread[x].readWriteLock = &readWriteLock;
thread[x].cond = (x < ThreadCount / 2) ? &cond1 : &cond2;
thread[x].start();
@@ -346,11 +379,17 @@ void tst_QWaitCondition::wait_QReadWriteLock()
}
}
-class wake_Thread : public QThread
+class WakeThreadBase : public TerminatingThread
{
public:
- static int count;
+ QAtomicInt *count;
+ WakeThreadBase() : count(Q_NULLPTR) {}
+};
+
+class wake_Thread : public WakeThreadBase
+{
+public:
QWaitCondition started;
QWaitCondition dummy;
@@ -366,24 +405,23 @@ public:
void run()
{
+ Q_ASSERT(count);
+ Q_ASSERT(mutex);
+ Q_ASSERT(cond);
mutex->lock();
- ++count;
+ ++*count;
dummy.wakeOne(); // this wakeup should be lost
started.wakeOne();
dummy.wakeAll(); // this one too
cond->wait(mutex);
- --count;
+ --*count;
mutex->unlock();
}
};
-int wake_Thread::count = 0;
-
-class wake_Thread_2 : public QThread
+class wake_Thread_2 : public WakeThreadBase
{
public:
- static int count;
-
QWaitCondition started;
QWaitCondition dummy;
@@ -399,22 +437,27 @@ public:
void run()
{
+ Q_ASSERT(count);
+ Q_ASSERT(readWriteLock);
+ Q_ASSERT(cond);
readWriteLock->lockForWrite();
- ++count;
+ ++*count;
dummy.wakeOne(); // this wakeup should be lost
started.wakeOne();
dummy.wakeAll(); // this one too
cond->wait(readWriteLock);
- --count;
+ --*count;
readWriteLock->unlock();
}
};
-int wake_Thread_2::count = 0;
-
void tst_QWaitCondition::wakeOne()
{
+ static const int firstWaitInterval = 1000;
+ static const int waitInterval = 30;
+
int x;
+ QAtomicInt count;
// wake up threads, one at a time
for (int i = 0; i < iterations; ++i) {
QMutex mutex;
@@ -424,8 +467,13 @@ void tst_QWaitCondition::wakeOne()
wake_Thread thread[ThreadCount];
bool thread_exited[ThreadCount];
+ QString prefix = QLatin1String(QTest::currentTestFunction()) + QLatin1String("_mutex_")
+ + QString::number(i) + QLatin1Char('_');
+
mutex.lock();
for (x = 0; x < ThreadCount; ++x) {
+ thread[x].setObjectName(prefix + QString::number(x));
+ thread[x].count = &count;
thread[x].mutex = &mutex;
thread[x].cond = &cond;
thread_exited[x] = false;
@@ -438,7 +486,7 @@ void tst_QWaitCondition::wakeOne()
}
mutex.unlock();
- QCOMPARE(wake_Thread::count, ThreadCount);
+ QCOMPARE(count.load(), ThreadCount);
// wake up threads one at a time
for (x = 0; x < ThreadCount; ++x) {
@@ -452,24 +500,29 @@ void tst_QWaitCondition::wakeOne()
for (int y = 0; y < ThreadCount; ++y) {
if (thread_exited[y])
continue;
- if (thread[y].wait(exited > 0 ? 10 : 1000)) {
+ if (thread[y].wait(exited > 0 ? waitInterval : firstWaitInterval)) {
thread_exited[y] = true;
++exited;
}
}
QCOMPARE(exited, 1);
- QCOMPARE(wake_Thread::count, ThreadCount - (x + 1));
+ QCOMPARE(count.load(), ThreadCount - (x + 1));
}
- QCOMPARE(wake_Thread::count, 0);
+ QCOMPARE(count.load(), 0);
// QReadWriteLock
QReadWriteLock readWriteLock;
wake_Thread_2 rwthread[ThreadCount];
+ prefix = QLatin1String(QTest::currentTestFunction()) + QLatin1String("_readwritelock_")
+ + QString::number(i) + QLatin1Char('_');
+
readWriteLock.lockForWrite();
for (x = 0; x < ThreadCount; ++x) {
+ rwthread[x].setObjectName(prefix + QString::number(x));
+ rwthread[x].count = &count;
rwthread[x].readWriteLock = &readWriteLock;
rwthread[x].cond = &cond;
thread_exited[x] = false;
@@ -482,7 +535,7 @@ void tst_QWaitCondition::wakeOne()
}
readWriteLock.unlock();
- QCOMPARE(wake_Thread_2::count, ThreadCount);
+ QCOMPARE(count.load(), ThreadCount);
// wake up threads one at a time
for (x = 0; x < ThreadCount; ++x) {
@@ -496,17 +549,17 @@ void tst_QWaitCondition::wakeOne()
for (int y = 0; y < ThreadCount; ++y) {
if (thread_exited[y])
continue;
- if (rwthread[y].wait(exited > 0 ? 10 : 1000)) {
+ if (rwthread[y].wait(exited > 0 ? waitInterval : firstWaitInterval)) {
thread_exited[y] = true;
++exited;
}
}
QCOMPARE(exited, 1);
- QCOMPARE(wake_Thread_2::count, ThreadCount - (x + 1));
+ QCOMPARE(count.load(), ThreadCount - (x + 1));
}
- QCOMPARE(wake_Thread_2::count, 0);
+ QCOMPARE(count.load(), 0);
}
// wake up threads, two at a time
@@ -518,8 +571,13 @@ void tst_QWaitCondition::wakeOne()
wake_Thread thread[ThreadCount];
bool thread_exited[ThreadCount];
+ QString prefix = QLatin1String(QTest::currentTestFunction()) + QLatin1String("_mutex2_")
+ + QString::number(i) + QLatin1Char('_');
+
mutex.lock();
for (x = 0; x < ThreadCount; ++x) {
+ thread[x].setObjectName(prefix + QString::number(x));
+ thread[x].count = &count;
thread[x].mutex = &mutex;
thread[x].cond = &cond;
thread_exited[x] = false;
@@ -532,7 +590,7 @@ void tst_QWaitCondition::wakeOne()
}
mutex.unlock();
- QCOMPARE(wake_Thread::count, ThreadCount);
+ QCOMPARE(count.load(), ThreadCount);
// wake up threads one at a time
for (x = 0; x < ThreadCount; x += 2) {
@@ -548,24 +606,29 @@ void tst_QWaitCondition::wakeOne()
for (int y = 0; y < ThreadCount; ++y) {
if (thread_exited[y])
continue;
- if (thread[y].wait(exited > 0 ? 10 : 1000)) {
+ if (thread[y].wait(exited > 0 ? waitInterval : firstWaitInterval)) {
thread_exited[y] = true;
++exited;
}
}
QCOMPARE(exited, 2);
- QCOMPARE(wake_Thread::count, ThreadCount - (x + 2));
+ QCOMPARE(count.load(), ThreadCount - (x + 2));
}
- QCOMPARE(wake_Thread::count, 0);
+ QCOMPARE(count.load(), 0);
// QReadWriteLock
QReadWriteLock readWriteLock;
wake_Thread_2 rwthread[ThreadCount];
+ prefix = QLatin1String(QTest::currentTestFunction()) + QLatin1String("_readwritelock_")
+ + QString::number(i) + QLatin1Char('_');
+
readWriteLock.lockForWrite();
for (x = 0; x < ThreadCount; ++x) {
+ rwthread[x].setObjectName(prefix + QString::number(x));
+ rwthread[x].count = &count;
rwthread[x].readWriteLock = &readWriteLock;
rwthread[x].cond = &cond;
thread_exited[x] = false;
@@ -578,7 +641,7 @@ void tst_QWaitCondition::wakeOne()
}
readWriteLock.unlock();
- QCOMPARE(wake_Thread_2::count, ThreadCount);
+ QCOMPARE(count.load(), ThreadCount);
// wake up threads one at a time
for (x = 0; x < ThreadCount; x += 2) {
@@ -594,23 +657,24 @@ void tst_QWaitCondition::wakeOne()
for (int y = 0; y < ThreadCount; ++y) {
if (thread_exited[y])
continue;
- if (rwthread[y].wait(exited > 0 ? 10 : 1000)) {
+ if (rwthread[y].wait(exited > 0 ? waitInterval : firstWaitInterval)) {
thread_exited[y] = true;
++exited;
}
}
QCOMPARE(exited, 2);
- QCOMPARE(wake_Thread_2::count, ThreadCount - (x + 2));
+ QCOMPARE(count.load(), ThreadCount - (x + 2));
}
- QCOMPARE(wake_Thread_2::count, 0);
+ QCOMPARE(count.load(), 0);
}
}
void tst_QWaitCondition::wakeAll()
{
int x;
+ QAtomicInt count;
for (int i = 0; i < iterations; ++i) {
QMutex mutex;
QWaitCondition cond;
@@ -618,8 +682,13 @@ void tst_QWaitCondition::wakeAll()
// QMutex
wake_Thread thread[ThreadCount];
+ QString prefix = QLatin1String(QTest::currentTestFunction()) + QLatin1String("_mutex_")
+ + QString::number(i) + QLatin1Char('_');
+
mutex.lock();
for (x = 0; x < ThreadCount; ++x) {
+ thread[x].setObjectName(prefix + QString::number(x));
+ thread[x].count = &count;
thread[x].mutex = &mutex;
thread[x].cond = &cond;
thread[x].start();
@@ -628,7 +697,7 @@ void tst_QWaitCondition::wakeAll()
}
mutex.unlock();
- QCOMPARE(wake_Thread::count, ThreadCount);
+ QCOMPARE(count.load(), ThreadCount);
// wake up all threads at once
mutex.lock();
@@ -643,14 +712,19 @@ void tst_QWaitCondition::wakeAll()
}
QCOMPARE(exited, ThreadCount);
- QCOMPARE(wake_Thread::count, 0);
+ QCOMPARE(count.load(), 0);
// QReadWriteLock
QReadWriteLock readWriteLock;
wake_Thread_2 rwthread[ThreadCount];
+ prefix = QLatin1String(QTest::currentTestFunction()) + QLatin1String("_readwritelock_")
+ + QString::number(i) + QLatin1Char('_');
+
readWriteLock.lockForWrite();
for (x = 0; x < ThreadCount; ++x) {
+ rwthread[x].setObjectName(prefix + QString::number(x));
+ rwthread[x].count = &count;
rwthread[x].readWriteLock = &readWriteLock;
rwthread[x].cond = &cond;
rwthread[x].start();
@@ -659,7 +733,7 @@ void tst_QWaitCondition::wakeAll()
}
readWriteLock.unlock();
- QCOMPARE(wake_Thread_2::count, ThreadCount);
+ QCOMPARE(count.load(), ThreadCount);
// wake up all threads at once
readWriteLock.lockForWrite();
@@ -674,11 +748,11 @@ void tst_QWaitCondition::wakeAll()
}
QCOMPARE(exited, ThreadCount);
- QCOMPARE(wake_Thread_2::count, 0);
+ QCOMPARE(count.load(), 0);
}
}
-class wait_RaceConditionThread : public QThread
+class wait_RaceConditionThread : public TerminatingThread
{
public:
wait_RaceConditionThread(QMutex *mutex, QWaitCondition *startup, QWaitCondition *waitCondition,
@@ -707,7 +781,7 @@ public:
}
};
-class wait_RaceConditionThread_2 : public QThread
+class wait_RaceConditionThread_2 : public TerminatingThread
{
public:
wait_RaceConditionThread_2(QReadWriteLock *readWriteLock,
diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
index 1425ce3c2f..68b92e1851 100644
--- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
+++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
@@ -36,7 +36,6 @@
#include <QBuffer>
#include <QDebug>
-#include <QFile>
#include <QImage>
#include <QImageReader>
#include <QImageWriter>
@@ -46,6 +45,7 @@
#include <QTcpServer>
#include <QTimer>
#include <QTemporaryDir>
+#include <QTemporaryFile>
#include <algorithm>
@@ -53,6 +53,22 @@ typedef QMap<QString, QString> QStringMap;
typedef QList<int> QIntList;
Q_DECLARE_METATYPE(QImage::Format)
+static QByteArray msgFileOpenWriteFailed(const QFile &file)
+{
+ const QString result = QLatin1String("Cannot open \"")
+ + QDir::toNativeSeparators(file.fileName())
+ + QLatin1String("\" for writing: ") + file.errorString();
+ return result.toLocal8Bit();
+}
+
+static QByteArray msgFileOpenReadFailed(const QFile &file)
+{
+ const QString result = QLatin1String("Cannot open \"")
+ + QDir::toNativeSeparators(file.fileName())
+ + QLatin1String("\" for reading: ") + file.errorString();
+ return result.toLocal8Bit();
+}
+
class tst_QImageReader : public QObject
{
Q_OBJECT
@@ -1051,7 +1067,7 @@ void tst_QImageReader::readFromDevice()
const QString imageFileName = prefix + fileName;
QImage expectedImage(imageFileName, format);
QFile file(imageFileName);
- QVERIFY(file.open(QFile::ReadOnly));
+ QVERIFY2(file.open(QFile::ReadOnly), msgFileOpenReadFailed(file).constData());
QByteArray imageData = file.readAll();
QVERIFY(!imageData.isEmpty());
{
@@ -1129,12 +1145,11 @@ void tst_QImageReader::readFromFileAfterJunk()
SKIP_IF_UNSUPPORTED(format);
- QFile::remove("junk");
- QFile junkFile("junk");
- QVERIFY(junkFile.open(QFile::WriteOnly));
+ QTemporaryFile junkFile(m_temporaryDir.path() + QLatin1String("/junkXXXXXX"));
+ QVERIFY2(junkFile.open(), msgFileOpenWriteFailed(junkFile).constData());
QFile imageFile(prefix + fileName);
- QVERIFY(imageFile.open(QFile::ReadOnly));
+ QVERIFY2(imageFile.open(QFile::ReadOnly), msgFileOpenReadFailed(imageFile).constData());
QByteArray imageData = imageFile.readAll();
QVERIFY(!imageData.isNull());
@@ -1155,7 +1170,7 @@ void tst_QImageReader::readFromFileAfterJunk()
}
}
junkFile.close();
- junkFile.open(QFile::ReadOnly);
+ QVERIFY2(junkFile.open(), msgFileOpenReadFailed(junkFile).constData());
for (int i = 0; i < iterations; ++i) {
QByteArray ole = junkFile.read(9);
@@ -1205,7 +1220,7 @@ void tst_QImageReader::devicePosition()
QVERIFY(!expected.isNull());
QFile imageFile(prefix + fileName);
- QVERIFY(imageFile.open(QFile::ReadOnly));
+ QVERIFY2(imageFile.open(QFile::ReadOnly), msgFileOpenReadFailed(imageFile).constData());
QByteArray imageData = imageFile.readAll();
QVERIFY(!imageData.isNull());
int imageDataSize = imageData.size();
diff --git a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp
index 6c22c47f0e..c49c9c9129 100644
--- a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp
+++ b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp
@@ -89,6 +89,7 @@ private slots:
void saveToTemporaryFile();
private:
+ QTemporaryDir m_temporaryDir;
QString prefix;
QString writePrefix;
};
@@ -112,14 +113,11 @@ static void initializePadding(QImage *image)
void tst_QImageWriter::initTestCase()
{
+ QVERIFY(m_temporaryDir.isValid());
prefix = QFINDTESTDATA("images/");
if (prefix.isEmpty())
QFAIL("Can't find images directory!");
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_NO_SDK)
- writePrefix = QDir::homePath();
-#else
- writePrefix = prefix;
-#endif
+ writePrefix = m_temporaryDir.path();
}
// Testing get/set functions
diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
index a84d290661..66aa26ccea 100644
--- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
@@ -202,8 +202,7 @@ protected Q_SLOTS:
void notEnoughData();
private Q_SLOTS:
- void init();
- void cleanup();
+ void cleanup() { cleanupTestData(); }
void initTestCase();
void cleanupTestCase();
@@ -487,6 +486,8 @@ private Q_SLOTS:
// NOTE: This test must be last!
void parentingRepliesToTheApp();
private:
+ void cleanupTestData();
+
QString testDataDir;
bool notEnoughDataForFastSender;
};
@@ -1499,6 +1500,8 @@ void tst_QNetworkReply::initTestCase()
echoProcessDir = QFINDTESTDATA("echo");
QVERIFY2(!echoProcessDir.isEmpty(), qPrintable(
QString::fromLatin1("Couldn't find echo dir starting from %1.").arg(QDir::currentPath())));
+
+ cleanupTestData();
}
void tst_QNetworkReply::cleanupTestCase()
@@ -1514,12 +1517,7 @@ void tst_QNetworkReply::cleanupTestCase()
#endif
}
-void tst_QNetworkReply::init()
-{
- cleanup();
-}
-
-void tst_QNetworkReply::cleanup()
+void tst_QNetworkReply::cleanupTestData()
{
QFile file(testFileName);
QVERIFY(!file.exists() || file.remove());
diff --git a/tests/auto/tools/qmake/testdata/.gitignore b/tests/auto/tools/qmake/testdata/.gitignore
new file mode 100644
index 0000000000..1e997b287b
--- /dev/null
+++ b/tests/auto/tools/qmake/testdata/.gitignore
@@ -0,0 +1,5 @@
+# Created by various tests, even for shadow builds:
+/pro_file_cache/include.pri
+/quotedfilenames/cpp folder/
+/quotedfilenames/quotedfilenames
+/resources/resources
diff --git a/tests/manual/qcursor/qcursor.pro b/tests/manual/qcursor/qcursor.pro
index af082a4b82..0b5c2b1945 100644
--- a/tests/manual/qcursor/qcursor.pro
+++ b/tests/manual/qcursor/qcursor.pro
@@ -1,3 +1,3 @@
TEMPLATE = subdirs
-SUBDIRS = allcursors grab_override
+SUBDIRS = allcursors grab_override qcursorhighdpi
diff --git a/tests/manual/qcursor/qcursorhighdpi/main.cpp b/tests/manual/qcursor/qcursorhighdpi/main.cpp
new file mode 100644
index 0000000000..fc45ae00d1
--- /dev/null
+++ b/tests/manual/qcursor/qcursorhighdpi/main.cpp
@@ -0,0 +1,321 @@
+/****************************************************************************
+**
+** 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 <QAction>
+#include <QApplication>
+#include <QDesktopWidget>
+#include <QGridLayout>
+#include <QLabel>
+#include <QMainWindow>
+#include <QMenu>
+#include <QMenuBar>
+#include <QSharedPointer>
+#include <QToolBar>
+
+#include <QBitmap>
+#include <QCursor>
+#include <QPainter>
+#include <QPixmap>
+
+#include <QDebug>
+#include <QStringList>
+#include <QTextStream>
+
+#if QT_VERSION > 0x050000
+# include <QScreen>
+# include <QWindow>
+# include <private/qhighdpiscaling_p.h>
+# include <qpa/qplatformwindow.h>
+#else
+# define Q_NULLPTR 0
+# define Q_DECL_OVERRIDE
+#endif
+
+#ifdef Q_OS_WIN
+# include <qt_windows.h>
+#endif
+
+#include <algorithm>
+#include <iterator>
+
+// High DPI cursor test for testing cursor sizes in multi-screen setups.
+// It creates one widget per screen with a grid of standard cursors,
+// pixmap / bitmap cursors and pixmap / bitmap cursors with device pixel ratio 2.
+// On the left, there is a ruler with 10 DIP marks.
+// The code is meant to compile with Qt 4 also.
+
+static QString screenInfo(const QWidget *w)
+{
+ QString result;
+ QTextStream str(&result);
+#if QT_VERSION > 0x050000
+ QScreen *screen = Q_NULLPTR;
+ if (const QWindow *window = w->windowHandle())
+ screen = window->screen();
+ if (screen) {
+ str << '"' << screen->name() << "\" " << screen->size().width() << 'x'
+ << screen->size().height() << ", DPR=" << screen->devicePixelRatio()
+ << ", " << screen->logicalDotsPerInchX() << "DPI ";
+ if (QHighDpiScaling::isActive())
+ str << ", factor=" << QHighDpiScaling::factor(screen);
+ else
+ str << ", no scaling";
+ } else {
+ str << "<null>";
+ }
+#else
+ QDesktopWidget *desktop = QApplication::desktop();
+ int screenNumber = desktop->screenNumber(w);
+ str << "Screen #" <<screenNumber << ' ' << desktop->screenGeometry(screenNumber).width()
+ << 'x' << desktop->screenGeometry(screenNumber).height() << " PD: " << w->logicalDpiX() << "DPI";
+#endif
+#ifdef Q_OS_WIN
+ str << ", SM_C_CURSOR: " << GetSystemMetrics(SM_CXCURSOR) << 'x' << GetSystemMetrics(SM_CYCURSOR);
+#endif
+ return result;
+}
+
+// Helpers for painting pixmaps and creating cursors
+static QPixmap paintPixmap(int size, QColor c)
+{
+ QPixmap result(size, size);
+ result.fill(c);
+ QPainter p(&result);
+ p.drawRect(QRect(QPoint(0, 0), result.size() - QSize(1, 1)));
+ p.drawLine(0, 0, size, size);
+ p.drawLine(0, size, size, 0);
+ return result;
+}
+
+static QCursor pixmapCursor(int size)
+{
+ QCursor result(paintPixmap(size, Qt::red), size / 2, size / 2);
+ return result;
+}
+
+static QPair<QBitmap, QBitmap> paintBitmaps(int size)
+{
+ QBitmap bitmap(size, size);
+ bitmap.fill(Qt::color1);
+ QBitmap mask(size, size);
+ mask.fill(Qt::color1);
+ {
+ QPainter mp(&mask);
+ mp.fillRect(QRect(0, 0, size / 2, size / 2), Qt::color0);
+ }
+ return QPair<QBitmap, QBitmap>(bitmap, mask);
+}
+
+static QCursor bitmapCursor(int size)
+{
+ QPair<QBitmap, QBitmap> bitmaps = paintBitmaps(size);
+ return QCursor(bitmaps.first, bitmaps.second, size / 2, size / 2);
+}
+
+#if QT_VERSION > 0x050000
+static QCursor pixmapCursorDevicePixelRatio(int size, int dpr)
+{
+ QPixmap pixmap = paintPixmap(dpr * size, Qt::yellow);
+ pixmap.setDevicePixelRatio(dpr);
+ return QCursor(pixmap, size / 2, size / 2);
+}
+
+static QCursor bitmapCursorDevicePixelRatio(int size, int dpr)
+{
+ QPair<QBitmap, QBitmap> bitmaps = paintBitmaps(dpr * size);
+ bitmaps.first.setDevicePixelRatio(dpr);
+ bitmaps.second.setDevicePixelRatio(dpr);
+ return QCursor(bitmaps.first, bitmaps.second, size / 2, size / 2);
+}
+#endif // Qt 5
+
+// Vertical ruler widget with 10 px marks
+class VerticalRuler : public QWidget {
+public:
+ VerticalRuler(QWidget *parent = Q_NULLPTR);
+
+protected:
+ void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
+};
+
+VerticalRuler::VerticalRuler(QWidget *parent) : QWidget(parent)
+{
+ const int screenWidth = QApplication::desktop()->screenGeometry(this).width();
+ setFixedWidth(screenWidth / 48); // 1920 pixel monitor ->40
+}
+
+void VerticalRuler::paintEvent(QPaintEvent *)
+{
+ const QSize sizeS(size());
+ const QPoint sizeP(sizeS.width(), sizeS.height());
+ const QPoint center = sizeP / 2;
+ QPainter painter(this);
+ painter.fillRect(QRect(QPoint(0, 0), sizeS), Qt::white);
+ painter.drawLine(center.x(), 0, center.x(), sizeP.y());
+ for (int y = 0; y < sizeP.y(); y += 10)
+ painter.drawLine(center.x() - 5, y, center.x() + 5, y);
+}
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+public:
+ explicit MainWindow(QWidget *parent = Q_NULLPTR);
+ void updateScreenInfo() { m_screenInfoLabel->setText(screenInfo(this)); }
+
+public slots:
+ void screenChanged() { updateScreenInfo(); }
+
+private:
+ QLabel *m_screenInfoLabel;
+};
+
+static QLabel *createCursorLabel(const QCursor &cursor, const QString &additionalText = QString())
+{
+ QString labelText;
+ QDebug(&labelText).nospace() << cursor.shape();
+#if QT_VERSION > 0x050000
+ labelText.remove(0, labelText.indexOf('(') + 1);
+ labelText.chop(1);
+#endif // Qt 5
+ if (!additionalText.isEmpty())
+ labelText += ' ' + additionalText;
+ QLabel *result = new QLabel(labelText);
+ result->setFrameShape(QFrame::Box);
+ result->setCursor(cursor);
+ return result;
+}
+
+static void addToGrid(QWidget *w, QGridLayout *gridLayout, int columnCount, int &row, int &col)
+{
+ gridLayout->addWidget(w, row, col);
+ if (col >= columnCount) {
+ col = 0;
+ row++;
+ } else {
+ col++;
+ }
+}
+
+MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent)
+ , m_screenInfoLabel(new QLabel)
+{
+ QString title = "Cursors ";
+#if QT_VERSION > 0x050000
+ title += '(' + QGuiApplication::platformName() + ") ";
+#endif
+ title += QT_VERSION_STR;
+ setWindowTitle(title);
+
+ QMenu *fileMenu = menuBar()->addMenu("File");
+ QAction *quitAction = fileMenu->addAction("Quit");
+ quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
+ connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
+
+ QToolBar *fileToolBar = addToolBar("File");
+ fileToolBar->addAction(quitAction);
+
+ QWidget *cw = new QWidget;
+ QHBoxLayout *hLayout = new QHBoxLayout(cw);
+ hLayout->addWidget(new VerticalRuler(cw));
+ QGridLayout *gridLayout = new QGridLayout;
+ hLayout->addLayout(gridLayout);
+
+ const int columnCount = 5;
+ const int size = 32;
+
+ int row = 0;
+ int col = 0;
+ for (int i = 0; i < Qt::BitmapCursor; ++i)
+ addToGrid(createCursorLabel(QCursor(static_cast<Qt::CursorShape>(i))), gridLayout, columnCount, row, col);
+
+ addToGrid(createCursorLabel(QCursor(pixmapCursor(size)),
+ QLatin1String("Plain PX ") + QString::number(size)),
+ gridLayout, columnCount, row, col);
+
+ addToGrid(createCursorLabel(bitmapCursor(size),
+ QLatin1String("Plain BM ") + QString::number(size)),
+ gridLayout, columnCount, row, col);
+
+#if QT_VERSION > 0x050000
+ addToGrid(createCursorLabel(QCursor(pixmapCursorDevicePixelRatio(size, 2)),
+ "PX with DPR 2 " + QString::number(size)),
+ gridLayout, columnCount, row, col);
+
+ addToGrid(createCursorLabel(QCursor(bitmapCursorDevicePixelRatio(size, 2)),
+ "BM with DPR 2 " + QString::number(size)),
+ gridLayout, columnCount, row, col);
+#endif // Qt 5
+
+ gridLayout->addWidget(m_screenInfoLabel, row + 1, 0, 1, columnCount);
+
+ setCentralWidget(cw);
+}
+
+typedef QSharedPointer<MainWindow> MainWindowPtr;
+typedef QList<MainWindowPtr> MainWindowPtrList;
+
+int main(int argc, char *argv[])
+{
+ QStringList arguments;
+ std::copy(argv + 1, argv + argc, std::back_inserter(arguments));
+
+#if QT_VERSION > 0x050000
+ if (arguments.contains("-s"))
+ QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ else if (arguments.contains("-n"))
+ QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);
+#endif // Qt 5
+
+ QApplication app(argc, argv);
+
+ MainWindowPtrList windows;
+
+ QDesktopWidget *desktopWidget = app.desktop();
+
+ for (int s = desktopWidget->screenCount() - 1; s >= 0; --s) {
+ MainWindowPtr window(new MainWindow(desktopWidget->screen(s)));
+ const QPoint pos = desktopWidget->screenGeometry(s).center() - QPoint(200, 100);
+ window->move(pos);
+ windows.append(window);
+ window->show();
+ window->updateScreenInfo();
+#if QT_VERSION > 0x050000
+ QObject::connect(window->windowHandle(), &QWindow::screenChanged,
+ window.data(), &MainWindow::updateScreenInfo);
+#endif
+ }
+ return app.exec();
+}
+#include "main.moc"
diff --git a/tests/manual/qcursor/qcursorhighdpi/qcursorhighdpi.pro b/tests/manual/qcursor/qcursorhighdpi/qcursorhighdpi.pro
new file mode 100644
index 0000000000..3a8fc25b33
--- /dev/null
+++ b/tests/manual/qcursor/qcursorhighdpi/qcursorhighdpi.pro
@@ -0,0 +1,6 @@
+TEMPLATE = app
+QT = core gui
+greaterThan(QT_MAJOR_VERSION, 4): QT += gui-private core-private widgets
+CONFIG -= app_bundle
+SOURCES += main.cpp
+win32: LIBS += -lUser32