summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfigure8
-rw-r--r--examples/widgets/graphicsview/diagramscene/arrow.cpp32
-rw-r--r--mkspecs/features/file_copies.prf41
-rw-r--r--mkspecs/features/qml_module.prf20
-rw-r--r--mkspecs/features/qt_common.prf4
-rw-r--r--mkspecs/features/spec_pre.prf2
-rw-r--r--qmake/generators/makefiledeps.cpp70
-rw-r--r--qmake/generators/metamakefile.cpp6
-rw-r--r--src/corelib/global/qcompilerdetection.h17
-rw-r--r--src/corelib/itemmodels/qidentityproxymodel.h1
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp2
-rw-r--r--src/corelib/kernel/qmetatype.h2
-rw-r--r--src/corelib/kernel/qobject.cpp6
-rw-r--r--src/corelib/tools/qarraydata.cpp13
-rw-r--r--src/corelib/tools/qlist.h2
-rw-r--r--src/corelib/tools/qstring.cpp14
-rw-r--r--src/corelib/tools/qvarlengtharray.h7
-rw-r--r--src/corelib/tools/qvector.h2
-rw-r--r--src/dbus/dbus_minimal_p.h2
-rw-r--r--src/dbus/qdbusconnection_p.h3
-rw-r--r--src/dbus/qdbusintegrator.cpp41
-rw-r--r--src/dbus/qdbusutil_p.h2
-rw-r--r--src/gui/kernel/qkeysequence.cpp2
-rw-r--r--src/gui/kernel/qkeysequence_p.h3
-rw-r--r--src/gui/painting/qpainter.cpp12
-rw-r--r--src/gui/painting/qpdf.cpp2
-rw-r--r--src/gui/text/qzip.cpp9
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp1
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp40
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm2
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm6
-rw-r--r--src/plugins/platforms/windows/accessible/iaccessible2.cpp19
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.cpp2
-rw-r--r--src/plugins/platforms/winrt/qwinrtfileengine.cpp12
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp67
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp55
-rw-r--r--src/testlib/qtestcase.cpp15
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp2
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.h1
-rw-r--r--src/widgets/styles/qstyle.cpp4
-rw-r--r--src/widgets/widgets/qabstractscrollarea.cpp2
-rw-r--r--src/widgets/widgets/qabstractslider.cpp5
-rw-r--r--src/widgets/widgets/qdatetimeedit_p.h15
-rw-r--r--src/widgets/widgets/qplaintextedit.cpp2
-rw-r--r--src/widgets/widgets/qtextedit.cpp2
-rw-r--r--tests/auto/corelib/tools/qtimezone/BLACKLIST2
-rw-r--r--tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp18
-rw-r--r--tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp21
-rw-r--r--tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h1
-rw-r--r--tests/auto/other/compiler/tst_compiler.cpp90
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp22
-rw-r--r--tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp51
-rw-r--r--tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp1
-rw-r--r--tests/manual/manual.pro1
-rw-r--r--tests/manual/qtabletevent/device_information/tabletwidget.cpp8
-rw-r--r--tests/manual/qtabletevent/device_information/tabletwidget.h1
-rw-r--r--tests/manual/qtbug-52641/main.cpp87
-rw-r--r--tests/manual/qtbug-52641/qtbug-52641.pro5
59 files changed, 662 insertions, 229 deletions
diff --git a/configure b/configure
index b3ddfaa4b6..a58256f089 100755
--- a/configure
+++ b/configure
@@ -692,7 +692,7 @@ CFG_EGLFS_EGLDEVICE=no
CFG_EGLFS_MALI=no
CFG_EGLFS_VIV=no
CFG_EGLFS_VIV_WL=no
-CFG_DIRECTFB=auto
+CFG_DIRECTFB=no
CFG_GBM=auto
CFG_LINUXFB=auto
CFG_INTEGRITYFB=no
@@ -2706,8 +2706,8 @@ Additional options:
-no-gbm ............ Do not compile backends for GBM.
* -gbm ............... Compile backends for GBM.
- -no-directfb ....... Do not compile DirectFB support.
- * -directfb .......... Compile DirectFB support.
+ * -no-directfb ....... Do not compile DirectFB support.
+ -directfb .......... Compile DirectFB support.
-no-linuxfb ........ Do not compile Linux Framebuffer support.
* -linuxfb ........... Compile Linux Framebuffer support.
@@ -3931,7 +3931,7 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ];
setBootstrapVariable QMAKE_CXXFLAGS_RELEASE
EXTRA_CFLAGS="$EXTRA_CFLAGS \$(QMAKE_CFLAGS_RELEASE)"
EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS \$(QMAKE_CXXFLAGS_RELEASE)"
- elif [ "$CFG_DEBUG" = "yes" ]; then
+ else
setBootstrapVariable QMAKE_CFLAGS_DEBUG
setBootstrapVariable QMAKE_CXXFLAGS_DEBUG
EXTRA_CFLAGS="$EXTRA_CFLAGS \$(QMAKE_CFLAGS_DEBUG)"
diff --git a/examples/widgets/graphicsview/diagramscene/arrow.cpp b/examples/widgets/graphicsview/diagramscene/arrow.cpp
index 383c126596..012b9ea2ed 100644
--- a/examples/widgets/graphicsview/diagramscene/arrow.cpp
+++ b/examples/widgets/graphicsview/diagramscene/arrow.cpp
@@ -120,12 +120,12 @@ void Arrow::paint(QPainter *painter, const QStyleOptionGraphicsItem *,
QPointF intersectPoint;
QLineF polyLine;
for (int i = 1; i < endPolygon.count(); ++i) {
- p2 = endPolygon.at(i) + myEndItem->pos();
- polyLine = QLineF(p1, p2);
- QLineF::IntersectType intersectType =
- polyLine.intersect(centerLine, &intersectPoint);
- if (intersectType == QLineF::BoundedIntersection)
- break;
+ p2 = endPolygon.at(i) + myEndItem->pos();
+ polyLine = QLineF(p1, p2);
+ QLineF::IntersectType intersectType =
+ polyLine.intersect(centerLine, &intersectPoint);
+ if (intersectType == QLineF::BoundedIntersection)
+ break;
p1 = p2;
}
@@ -136,18 +136,18 @@ void Arrow::paint(QPainter *painter, const QStyleOptionGraphicsItem *,
if (line().dy() >= 0)
angle = (Pi * 2) - angle;
- QPointF arrowP1 = line().p1() + QPointF(sin(angle + Pi / 3) * arrowSize,
- cos(angle + Pi / 3) * arrowSize);
- QPointF arrowP2 = line().p1() + QPointF(sin(angle + Pi - Pi / 3) * arrowSize,
- cos(angle + Pi - Pi / 3) * arrowSize);
+ QPointF arrowP1 = line().p1() + QPointF(sin(angle + Pi / 3) * arrowSize,
+ cos(angle + Pi / 3) * arrowSize);
+ QPointF arrowP2 = line().p1() + QPointF(sin(angle + Pi - Pi / 3) * arrowSize,
+ cos(angle + Pi - Pi / 3) * arrowSize);
- arrowHead.clear();
- arrowHead << line().p1() << arrowP1 << arrowP2;
+ arrowHead.clear();
+ arrowHead << line().p1() << arrowP1 << arrowP2;
//! [6] //! [7]
- painter->drawLine(line());
- painter->drawPolygon(arrowHead);
- if (isSelected()) {
- painter->setPen(QPen(myColor, 1, Qt::DashLine));
+ painter->drawLine(line());
+ painter->drawPolygon(arrowHead);
+ if (isSelected()) {
+ painter->setPen(QPen(myColor, 1, Qt::DashLine));
QLineF myLine = line();
myLine.translate(0, 4.0);
painter->drawLine(myLine);
diff --git a/mkspecs/features/file_copies.prf b/mkspecs/features/file_copies.prf
new file mode 100644
index 0000000000..f679129e03
--- /dev/null
+++ b/mkspecs/features/file_copies.prf
@@ -0,0 +1,41 @@
+isEmpty(COPIES): return()
+contains(TEMPLATE, .*subdirs): error("COPIES does not work with TEMPLATE=subdirs")
+
+build_pass:build_all: \
+ debug_and_release:debug {
+ # Avoid that multiple build passes race with each other.
+ # This will fail to copy anything if the user explicitly invokes
+ # only the non-primary build. This is unfixable, as at qmake time
+ # we cannot possibly know how make will be invoked, yet we must
+ # predict it here.
+ return()
+}
+
+defineReplace(qtStripProPwd) {
+ return($$relative_path($$1, $$_PRO_FILE_PWD_))
+}
+
+for (cp, COPIES) {
+ isEmpty($${cp}.files): next()
+ pfx = copy_$${cp}
+ for (f, $${cp}.files): \
+ $${pfx}.files += $$absolute_path($$f, $$_PRO_FILE_PWD_)
+ path = $$eval($${cp}.path)
+ isEmpty(path): error("COPY $cp defines no .path")
+ base = $$eval($${cp}.base)
+ isEmpty(base) {
+ $${pfx}.output = $$path/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}
+ } else: isEqual(base, $$_PRO_FILE_PWD_) {
+ $${pfx}.output = $$path/${QMAKE_FUNC_FILE_IN_qtStripProPwd}
+ } else {
+ eval(defineReplace(qtStripSrcDir_$$cp) { \
+ return(\$\$relative_path(\$\$1, $$val_escape(base))) \
+ })
+ $${pfx}.output = $$path/${QMAKE_FUNC_FILE_IN_qtStripSrcDir_$$cp}
+ }
+ $${pfx}.input = $${pfx}.files
+ $${pfx}.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
+ $${pfx}.name = COPY ${QMAKE_FILE_IN}
+ $${pfx}.CONFIG = no_link no_clean target_predeps
+ QMAKE_EXTRA_COMPILERS += $${pfx}
+}
diff --git a/mkspecs/features/qml_module.prf b/mkspecs/features/qml_module.prf
index 2115b39c04..6b3ad81953 100644
--- a/mkspecs/features/qml_module.prf
+++ b/mkspecs/features/qml_module.prf
@@ -28,24 +28,6 @@ else: \
!qml1_target:static: CONFIG += builtin_resources
-!force_independent:if(!debug_and_release|!build_all|CONFIG(release, debug|release)) {
- # These bizarre rules copy the files to the qtbase build directory
-
- defineReplace(qmlModStripSrcDir) {
- return($$relative_path($$1, $$_PRO_FILE_PWD_))
- }
-
- !builtin_resources: qmlfiles2build.input = fq_qml_files
- else: qmlfiles2build.input = qmldir_file
- qmlfiles2build.output = $$instbase/$$TARGETPATH/${QMAKE_FUNC_FILE_IN_qmlModStripSrcDir}
- !contains(TEMPLATE, vc.*): qmlfiles2build.variable_out = PRE_TARGETDEPS
- qmlfiles2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
- qmlfiles2build.name = COPY ${QMAKE_FILE_IN}
- qmlfiles2build.CONFIG = no_link no_clean
-
- QMAKE_EXTRA_COMPILERS += qmlfiles2build
-}
-
builtin_resources {
URITARGET = $$replace(URI, "\\.", "_")
# Ensure the qml files are included in the resources
@@ -61,3 +43,5 @@ qmldir.base = $$_PRO_FILE_PWD_
else: qmldir.files = $$qmldir_file
qmldir.path = $$instbase/$$TARGETPATH
INSTALLS += qmldir
+
+!prefix_build: COPIES += qmldir
diff --git a/mkspecs/features/qt_common.prf b/mkspecs/features/qt_common.prf
index 39e6163967..bc661f4dd7 100644
--- a/mkspecs/features/qt_common.prf
+++ b/mkspecs/features/qt_common.prf
@@ -44,6 +44,10 @@ contains(TEMPLATE, .*lib) {
QMAKE_PRL_INSTALL_REPLACE += lib_replace
}
+# The remainder of this file must not apply to bootstrapped tools,
+# as the host compiler's version and capabilities are not checked.
+host_build:force_bootstrap: return()
+
# Extra warnings for Qt non-example code, to ensure cleanliness of the sources.
# The block below may turn these warnings into errors for some Qt targets.
# -Wdate-time: warn if we use __DATE__ or __TIME__ (we want to be able to reproduce the exact same binary)
diff --git a/mkspecs/features/spec_pre.prf b/mkspecs/features/spec_pre.prf
index ff310d9793..090f348ebf 100644
--- a/mkspecs/features/spec_pre.prf
+++ b/mkspecs/features/spec_pre.prf
@@ -51,5 +51,5 @@ equals(QMAKE_HOST.os, Windows) {
QMAKE_SH = sh
}
-CONFIG = qt warn_on release link_prl
+CONFIG = file_copies qt warn_on release link_prl
QT = core gui
diff --git a/qmake/generators/makefiledeps.cpp b/qmake/generators/makefiledeps.cpp
index 0f6326bc0e..57cb0ea854 100644
--- a/qmake/generators/makefiledeps.cpp
+++ b/qmake/generators/makefiledeps.cpp
@@ -405,9 +405,9 @@ static bool matchWhileUnsplitting(const char *buffer, int buffer_len, int start,
int *matchlen, int *lines)
{
int x = start;
- for (int n = 0; n < needle_len && x < buffer_len;
+ for (int n = 0; n < needle_len;
n++, x = skipEscapedLineEnds(buffer, buffer_len, x + 1, lines)) {
- if (buffer[x] != needle[n])
+ if (x >= buffer_len || buffer[x] != needle[n])
return false;
}
// That also skipped any remaining BSNLs immediately after the match.
@@ -568,24 +568,29 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
++x;
if (buffer_len >= x + 12 && !strncmp(buffer + x, "includehint", 11) &&
(buffer[x + 11] == ' ' || buffer[x + 11] == '>')) {
- for (x += 11; buffer[x] != '>'; ++x) {} // skip
+ for (x += 11; x < buffer_len && buffer[x] != '>'; ++x) {} // skip
int inc_len = 0;
- for (x += 1 ; buffer[x + inc_len] != '<'; ++inc_len) {} // skip
- buffer[x + inc_len] = '\0';
- inc = buffer + x;
+ for (++x; x + inc_len < buffer_len && buffer[x + inc_len] != '<'; ++inc_len) {} // skip
+ if (x + inc_len < buffer_len) {
+ buffer[x + inc_len] = '\0';
+ inc = buffer + x;
+ }
} else if (buffer_len >= x + 13 && !strncmp(buffer + x, "customwidget", 12) &&
(buffer[x + 12] == ' ' || buffer[x + 12] == '>')) {
- for (x += 13; buffer[x] != '>'; ++x) {} // skip up to >
+ for (x += 13; x < buffer_len && buffer[x] != '>'; ++x) {} // skip up to >
while(x < buffer_len) {
- for (x++; buffer[x] != '<'; ++x) {} // skip up to <
+ while (++x < buffer_len && buffer[x] != '<') {} // skip up to <
x++;
if(buffer_len >= x + 7 && !strncmp(buffer+x, "header", 6) &&
(buffer[x + 6] == ' ' || buffer[x + 6] == '>')) {
- for (x += 7; buffer[x] != '>'; ++x) {} // skip up to >
+ for (x += 7; x < buffer_len && buffer[x] != '>'; ++x) {} // skip up to >
int inc_len = 0;
- for (x += 1 ; buffer[x + inc_len] != '<'; ++inc_len) {} // skip
- buffer[x + inc_len] = '\0';
- inc = buffer + x;
+ for (++x; x + inc_len < buffer_len && buffer[x + inc_len] != '<';
+ ++inc_len) {} // skip
+ if (x + inc_len < buffer_len) {
+ buffer[x + inc_len] = '\0';
+ inc = buffer + x;
+ }
break;
} else if(buffer_len >= x + 14 && !strncmp(buffer+x, "/customwidget", 13) &&
(buffer[x + 13] == ' ' || buffer[x + 13] == '>')) {
@@ -595,20 +600,18 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
}
} else if(buffer_len >= x + 8 && !strncmp(buffer + x, "include", 7) &&
(buffer[x + 7] == ' ' || buffer[x + 7] == '>')) {
- for (x += 8; buffer[x] != '>'; ++x) {
+ for (x += 8; x < buffer_len && buffer[x] != '>'; ++x) {
if (buffer_len >= x + 9 && buffer[x] == 'i' &&
!strncmp(buffer + x, "impldecl", 8)) {
- for (x += 8; buffer[x] != '='; ++x) {} // skip
- if (buffer[x] != '=')
- continue;
- for (++x; buffer[x] == '\t' || buffer[x] == ' '; ++x) {} // skip
+ for (x += 8; x < buffer_len && buffer[x] != '='; ++x) {} // skip
+ while (++x < buffer_len && (buffer[x] == '\t' || buffer[x] == ' ')) {} // skip
char quote = 0;
- if (buffer[x] == '\'' || buffer[x] == '"') {
+ if (x < buffer_len && (buffer[x] == '\'' || buffer[x] == '"')) {
quote = buffer[x];
++x;
}
int val_len;
- for(val_len = 0; true; ++val_len) {
+ for (val_len = 0; x + val_len < buffer_len; ++val_len) {
if(quote) {
if (buffer[x + val_len] == quote)
break;
@@ -618,16 +621,22 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
}
}
//? char saved = buffer[x + val_len];
- buffer[x + val_len] = '\0';
- if(!strcmp(buffer+x, "in implementation")) {
- //### do this
+ if (x + val_len < buffer_len) {
+ buffer[x + val_len] = '\0';
+ if (!strcmp(buffer + x, "in implementation")) {
+ //### do this
+ }
}
}
}
int inc_len = 0;
- for (x += 1 ; buffer[x + inc_len] != '<'; ++inc_len) {} // skip
- buffer[x + inc_len] = '\0';
- inc = buffer + x;
+ for (++x; x + inc_len < buffer_len && buffer[x + inc_len] != '<';
+ ++inc_len) {} // skip
+
+ if (x + inc_len < buffer_len) {
+ buffer[x + inc_len] = '\0';
+ inc = buffer + x;
+ }
}
}
//read past new line now..
@@ -641,14 +650,16 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
#define SKIP_BSNL(pos) skipEscapedLineEnds(buffer, buffer_len, (pos), &line_count)
// Seek code or directive, skipping comments and space:
- for(; x < buffer_len; ++x) {
- x = SKIP_BSNL(x);
+ for (; (x = SKIP_BSNL(x)) < buffer_len; ++x) {
if (buffer[x] == ' ' || buffer[x] == '\t') {
// keep going
} else if (buffer[x] == '/') {
int extralines = 0;
int y = skipEscapedLineEnds(buffer, buffer_len, x + 1, &extralines);
- if (buffer[y] == '/') { // C++-style comment
+ if (y >= buffer_len) {
+ x = y;
+ break;
+ } else if (buffer[y] == '/') { // C++-style comment
line_count += extralines;
x = SKIP_BSNL(y + 1);
while (x < buffer_len && !qmake_endOfLine(buffer[x]))
@@ -659,8 +670,7 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
} else if (buffer[y] == '*') { // C-style comment
line_count += extralines;
x = y;
- while (++x < buffer_len) {
- x = SKIP_BSNL(x);
+ while ((x = SKIP_BSNL(++x)) < buffer_len) {
if (buffer[x] == '*') {
extralines = 0;
y = skipEscapedLineEnds(buffer, buffer_len,
diff --git a/qmake/generators/metamakefile.cpp b/qmake/generators/metamakefile.cpp
index b816fc21f8..874b4286bc 100644
--- a/qmake/generators/metamakefile.cpp
+++ b/qmake/generators/metamakefile.cpp
@@ -225,10 +225,8 @@ MakefileGenerator
build_proj->setExtraVars(basevars);
build_proj->setExtraConfigs(basecfgs);
- build_proj->read(project->projectFile());
-
- //done
- return createMakefileGenerator(build_proj);
+ if (build_proj->read(project->projectFile()))
+ return createMakefileGenerator(build_proj);
}
return 0;
}
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index 86d027eb35..a08fde8bb0 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -105,6 +105,12 @@
# endif
# define Q_DECL_EXPORT __declspec(dllexport)
# define Q_DECL_IMPORT __declspec(dllimport)
+# if _MSC_VER >= 1800
+# define QT_MAKE_UNCHECKED_ARRAY_ITERATOR(x) stdext::make_unchecked_array_iterator(x)
+# endif
+# if _MSC_VER >= 1500
+# define QT_MAKE_CHECKED_ARRAY_ITERATOR(x, N) stdext::make_checked_array_iterator(x, size_t(N))
+# endif
/* Intel C++ disguising as Visual C++: the `using' keyword avoids warnings */
# if defined(__INTEL_COMPILER)
# define Q_DECL_VARIABLE_DEPRECATED
@@ -1106,6 +1112,11 @@
# define Q_ALIGNOF(x) alignof(x)
#endif
+#if defined(Q_COMPILER_ALIGNAS)
+# undef Q_DECL_ALIGN
+# define Q_DECL_ALIGN(n) alignas(n)
+#endif
+
/*
* Fallback macros to certain compiler features
*/
@@ -1174,6 +1185,12 @@
#ifndef Q_DECL_CONST_FUNCTION
# define Q_DECL_CONST_FUNCTION Q_DECL_PURE_FUNCTION
#endif
+#ifndef QT_MAKE_UNCHECKED_ARRAY_ITERATOR
+# define QT_MAKE_UNCHECKED_ARRAY_ITERATOR(x) (x)
+#endif
+#ifndef QT_MAKE_CHECKED_ARRAY_ITERATOR
+# define QT_MAKE_CHECKED_ARRAY_ITERATOR(x, N) (x)
+#endif
/*
* SG10's SD-6 feature detection and some useful extensions from Clang and GCC
diff --git a/src/corelib/itemmodels/qidentityproxymodel.h b/src/corelib/itemmodels/qidentityproxymodel.h
index 7a75f42d81..e93740c1a2 100644
--- a/src/corelib/itemmodels/qidentityproxymodel.h
+++ b/src/corelib/itemmodels/qidentityproxymodel.h
@@ -62,6 +62,7 @@ public:
QModelIndex mapFromSource(const QModelIndex& sourceIndex) const Q_DECL_OVERRIDE;
QModelIndex mapToSource(const QModelIndex& proxyIndex) const Q_DECL_OVERRIDE;
QModelIndex parent(const QModelIndex& child) const Q_DECL_OVERRIDE;
+ using QObject::parent;
int rowCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) Q_DECL_OVERRIDE;
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 0c1c37c89d..7bb2e7a78c 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -419,7 +419,7 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
if (!isArgvModified(argc, argv)) {
origArgc = argc;
origArgv = new char *[argc];
- std::copy(argv, argv + argc, origArgv);
+ std::copy(argv, argv + argc, QT_MAKE_CHECKED_ARRAY_ITERATOR(origArgv, argc));
}
#endif // Q_OS_WIN && !Q_OS_WINRT
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index ebe118dce4..b68dbacbd3 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -1189,6 +1189,7 @@ public:
public:
template<class T> QAssociativeIterableImpl(const T*p)
: _iterable(p)
+ , _iterator(Q_NULLPTR)
, _metaType_id_key(qMetaTypeId<typename T::key_type>())
, _metaType_flags_key(QTypeInfo<typename T::key_type>::isPointer)
, _metaType_id_value(qMetaTypeId<typename T::mapped_type>())
@@ -1208,6 +1209,7 @@ public:
QAssociativeIterableImpl()
: _iterable(Q_NULLPTR)
+ , _iterator(Q_NULLPTR)
, _metaType_id_key(QMetaType::UnknownType)
, _metaType_flags_key(0)
, _metaType_id_value(QMetaType::UnknownType)
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index fc5e6abf00..2b0eff3708 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -2151,8 +2151,8 @@ void QObject::deleteLater()
Returns a translated version of \a sourceText, optionally based on a
\a disambiguation string and value of \a n for strings containing plurals;
- otherwise returns \a sourceText itself if no appropriate translated string
- is available.
+ otherwise returns QString::fromUtf8(\a sourceText) if no appropriate
+ translated string is available.
Example:
\snippet ../widgets/mainwindows/sdi/mainwindow.cpp implicit tr context
@@ -2178,7 +2178,7 @@ void QObject::deleteLater()
translators while performing translations is not supported. Doing
so will probably result in crashes or other undesirable behavior.
- \sa trUtf8(), QCoreApplication::translate(), {Internationalization with Qt}
+ \sa QCoreApplication::translate(), {Internationalization with Qt}
*/
/*!
diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp
index 21ad799e25..bf336a8f31 100644
--- a/src/corelib/tools/qarraydata.cpp
+++ b/src/corelib/tools/qarraydata.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include <QtCore/qarraydata.h>
+#include <QtCore/private/qnumeric_p.h>
#include <QtCore/private/qtools_p.h>
#include <stdlib.h>
@@ -93,16 +94,22 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment,
if (capacity > std::numeric_limits<size_t>::max() / objectSize)
return 0;
- size_t alloc = objectSize * capacity;
+ size_t alloc;
+ if (mul_overflow(objectSize, capacity, &alloc))
+ return 0;
- // Make sure qAllocMore won't overflow.
+ // Make sure qAllocMore won't overflow qAllocMore.
if (headerSize > size_t(MaxAllocSize) || alloc > size_t(MaxAllocSize) - headerSize)
return 0;
capacity = qAllocMore(int(alloc), int(headerSize)) / int(objectSize);
}
- size_t allocSize = headerSize + objectSize * capacity;
+ size_t allocSize;
+ if (mul_overflow(objectSize, capacity, &allocSize))
+ return 0;
+ if (add_overflow(allocSize, headerSize, &allocSize))
+ return 0;
QArrayData *header = static_cast<QArrayData *>(::malloc(allocSize));
if (header) {
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index 5509c3adce..ec279769eb 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -852,7 +852,7 @@ inline bool QList<T>::op_eq_impl(const QList &l, QListData::ArrayCompatibleLayou
const T *lb = reinterpret_cast<const T*>(l.p.begin());
const T *b = reinterpret_cast<const T*>(p.begin());
const T *e = reinterpret_cast<const T*>(p.end());
- return std::equal(b, e, lb);
+ return std::equal(b, e, QT_MAKE_CHECKED_ARRAY_ITERATOR(lb, l.p.size()));
}
template <typename T>
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index c3aae2fd22..9f968978dc 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -712,8 +712,8 @@ static int findChar(const QChar *str, int len, QChar ch, int from,
}
#define REHASH(a) \
- if (sl_minus_1 < (int)sizeof(int) * CHAR_BIT) \
- hashHaystack -= (a) << sl_minus_1; \
+ if (sl_minus_1 < sizeof(uint) * CHAR_BIT) \
+ hashHaystack -= uint(a) << sl_minus_1; \
hashHaystack <<= 1
inline bool qIsUpper(char ch)
@@ -3096,8 +3096,9 @@ int qFindString(
const ushort *needle = (const ushort *)needle0;
const ushort *haystack = (const ushort *)haystack0 + from;
const ushort *end = (const ushort *)haystack0 + (l-sl);
- const int sl_minus_1 = sl-1;
- int hashNeedle = 0, hashHaystack = 0, idx;
+ const uint sl_minus_1 = sl - 1;
+ uint hashNeedle = 0, hashHaystack = 0;
+ int idx;
if (cs == Qt::CaseSensitive) {
for (idx = 0; idx < sl; ++idx) {
@@ -3172,10 +3173,11 @@ static int lastIndexOfHelper(const ushort *haystack, int from, const ushort *nee
const ushort *end = haystack;
haystack += from;
- const int sl_minus_1 = sl-1;
+ const uint sl_minus_1 = sl - 1;
const ushort *n = needle+sl_minus_1;
const ushort *h = haystack+sl_minus_1;
- int hashNeedle = 0, hashHaystack = 0, idx;
+ uint hashNeedle = 0, hashHaystack = 0;
+ int idx;
if (cs == Qt::CaseSensitive) {
for (idx = 0; idx < sl; ++idx) {
diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h
index 24574dc90b..c3ac104399 100644
--- a/src/corelib/tools/qvarlengtharray.h
+++ b/src/corelib/tools/qvarlengtharray.h
@@ -102,7 +102,8 @@ public:
QVarLengthArray<T, Prealloc> &operator=(std::initializer_list<T> list)
{
resize(list.size());
- std::copy(list.begin(), list.end(), this->begin());
+ std::copy(list.begin(), list.end(),
+ QT_MAKE_CHECKED_ARRAY_ITERATOR(this->begin(), this->size()));
return *this;
}
#endif
@@ -473,7 +474,7 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA
int l = int(aend - ptr);
int n = l - f;
if (QTypeInfo<T>::isComplex) {
- std::copy(ptr + l, ptr + s, ptr + f);
+ std::copy(ptr + l, ptr + s, QT_MAKE_CHECKED_ARRAY_ITERATOR(ptr + f, s - f));
T *i = ptr + s;
T *b = ptr + s - n;
while (i != b) {
@@ -495,7 +496,7 @@ bool operator==(const QVarLengthArray<T, Prealloc1> &l, const QVarLengthArray<T,
const T *rb = r.begin();
const T *b = l.begin();
const T *e = l.end();
- return std::equal(b, e, rb);
+ return std::equal(b, e, QT_MAKE_CHECKED_ARRAY_ITERATOR(rb, r.size()));
}
template <typename T, int Prealloc1, int Prealloc2>
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 806a127cc2..557bec9676 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -773,7 +773,7 @@ bool QVector<T>::operator==(const QVector<T> &v) const
const T *vb = v.d->begin();
const T *b = d->begin();
const T *e = d->end();
- return std::equal(b, e, vb);
+ return std::equal(b, e, QT_MAKE_CHECKED_ARRAY_ITERATOR(vb, v.d->size));
}
template <typename T>
diff --git a/src/dbus/dbus_minimal_p.h b/src/dbus/dbus_minimal_p.h
index 8b40742e0c..b52b0153e4 100644
--- a/src/dbus/dbus_minimal_p.h
+++ b/src/dbus/dbus_minimal_p.h
@@ -105,9 +105,11 @@ typedef dbus_uint32_t dbus_bool_t;
/* dbus-shared.h */
#define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
#define DBUS_PATH_DBUS "/org/freedesktop/DBus"
+#define DBUS_PATH_LOCAL "/org/freedesktop/DBus/Local"
#define DBUS_INTERFACE_DBUS "org.freedesktop.DBus"
#define DBUS_INTERFACE_INTROSPECTABLE "org.freedesktop.DBus.Introspectable"
#define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties"
+#define DBUS_INTERFACE_LOCAL "org.freedesktop.DBus.Local"
#define DBUS_NAME_FLAG_ALLOW_REPLACEMENT 0x1 /**< Allow another service to become the primary owner if requested */
#define DBUS_NAME_FLAG_REPLACE_EXISTING 0x2 /**< Request to replace the current primary owner */
diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h
index b2fa8faae8..f00988c05f 100644
--- a/src/dbus/qdbusconnection_p.h
+++ b/src/dbus/qdbusconnection_p.h
@@ -265,6 +265,8 @@ private:
QString getNameOwnerNoCache(const QString &service);
+ void watchForDBusDisconnection();
+
void _q_newConnection(QDBusConnectionPrivate *newConnection);
protected:
@@ -284,6 +286,7 @@ private slots:
void serviceOwnerChangedNoLock(const QString &name, const QString &oldOwner, const QString &newOwner);
void registerServiceNoLock(const QString &serviceName);
void unregisterServiceNoLock(const QString &serviceName);
+ void handleDBusDisconnection();
signals:
void dispatchStatusChanged();
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index cc3080e6db..c73f808485 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -1126,6 +1126,12 @@ void QDBusConnectionPrivate::closeConnection()
rootNode.children.clear(); // free resources
}
+void QDBusConnectionPrivate::handleDBusDisconnection()
+{
+ while (!pendingCalls.isEmpty())
+ processFinishedCall(pendingCalls.first());
+}
+
void QDBusConnectionPrivate::checkThread()
{
Q_ASSERT(thread() == QDBusConnectionManager::instance());
@@ -1651,6 +1657,19 @@ void QDBusConnectionPrivate::handleSignal(const QDBusMessage& msg)
handleSignal(key, msg); // third try
}
+void QDBusConnectionPrivate::watchForDBusDisconnection()
+{
+ SignalHook hook;
+ // Initialize the hook for Disconnected signal
+ hook.service.clear(); // org.freedesktop.DBus.Local.Disconnected uses empty service name
+ hook.path = QDBusUtil::dbusPathLocal();
+ hook.obj = this;
+ hook.params << QMetaType::Void;
+ hook.midx = staticMetaObject.indexOfSlot("handleDBusDisconnection()");
+ Q_ASSERT(hook.midx != -1);
+ signalHooks.insert(QLatin1String("Disconnected:" DBUS_INTERFACE_LOCAL), hook);
+}
+
void QDBusConnectionPrivate::setServer(QDBusServer *object, DBusServer *s, const QDBusErrorInternal &error)
{
mode = ServerMode;
@@ -1716,6 +1735,8 @@ void QDBusConnectionPrivate::setPeer(DBusConnection *c, const QDBusErrorInternal
qDBusSignalFilter,
this, 0);
+ watchForDBusDisconnection();
+
QMetaObject::invokeMethod(this, "doDispatch", Qt::QueuedConnection);
}
@@ -1792,6 +1813,8 @@ void QDBusConnectionPrivate::setConnection(DBusConnection *dbc, const QDBusError
Q_ASSERT(hook.midx != -1);
signalHooks.insert(QLatin1String("NameOwnerChanged:" DBUS_INTERFACE_DBUS), hook);
+ watchForDBusDisconnection();
+
qDBusDebug() << this << ": connected successfully";
// schedule a dispatch:
@@ -1818,10 +1841,16 @@ void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call)
QDBusMessage &msg = call->replyMessage;
if (call->pending) {
- // decode the message
- DBusMessage *reply = q_dbus_pending_call_steal_reply(call->pending);
- msg = QDBusMessagePrivate::fromDBusMessage(reply, connection->capabilities);
- q_dbus_message_unref(reply);
+ // when processFinishedCall is called and pending call is not completed,
+ // it means we received disconnected signal from libdbus
+ if (q_dbus_pending_call_get_completed(call->pending)) {
+ // decode the message
+ DBusMessage *reply = q_dbus_pending_call_steal_reply(call->pending);
+ msg = QDBusMessagePrivate::fromDBusMessage(reply, connection->capabilities);
+ q_dbus_message_unref(reply);
+ } else {
+ msg = QDBusMessage::createError(QDBusError::Disconnected, QDBusUtil::disconnectedErrorMessage());
+ }
}
qDBusDebug() << connection << "got message reply:" << msg;
@@ -2121,8 +2150,8 @@ void QDBusConnectionPrivate::sendInternal(QDBusPendingCallPrivate *pcall, void *
pcall->pending = pending;
q_dbus_pending_call_set_notify(pending, qDBusResultReceived, pcall, 0);
- // DBus won't notify us when a peer disconnects so we need to track these ourselves
- if (mode == QDBusConnectionPrivate::PeerMode)
+ // DBus won't notify us when a peer disconnects or server terminates so we need to track these ourselves
+ if (mode == QDBusConnectionPrivate::PeerMode || mode == QDBusConnectionPrivate::ClientMode)
pendingCalls.append(pcall);
return;
diff --git a/src/dbus/qdbusutil_p.h b/src/dbus/qdbusutil_p.h
index e0ba92be2e..e11fe573b5 100644
--- a/src/dbus/qdbusutil_p.h
+++ b/src/dbus/qdbusutil_p.h
@@ -164,6 +164,8 @@ namespace QDBusUtil
{ return QStringLiteral(DBUS_SERVICE_DBUS); }
inline QString dbusPath()
{ return QStringLiteral(DBUS_PATH_DBUS); }
+ inline QString dbusPathLocal()
+ { return QStringLiteral(DBUS_PATH_LOCAL); }
inline QString dbusInterface()
{
// it's the same string, but just be sure
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index 8a6eeb4cc9..8ccd85795b 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -1643,7 +1643,7 @@ QDataStream &operator>>(QDataStream &s, QKeySequence &keysequence)
s >> keys[i];
}
qAtomicDetach(keysequence.d);
- std::copy(keys, keys + MaxKeys, keysequence.d->key);
+ std::copy(keys, keys + MaxKeys, QT_MAKE_CHECKED_ARRAY_ITERATOR(keysequence.d->key, MaxKeys));
return s;
}
diff --git a/src/gui/kernel/qkeysequence_p.h b/src/gui/kernel/qkeysequence_p.h
index eeea0f5772..116e91c0cd 100644
--- a/src/gui/kernel/qkeysequence_p.h
+++ b/src/gui/kernel/qkeysequence_p.h
@@ -76,7 +76,8 @@ public:
}
inline QKeySequencePrivate(const QKeySequencePrivate &copy) : ref(1)
{
- std::copy(copy.key, copy.key + MaxKeyCount, key);
+ std::copy(copy.key, copy.key + MaxKeyCount,
+ QT_MAKE_CHECKED_ARRAY_ITERATOR(key, MaxKeyCount));
}
QAtomicInt ref;
int key[MaxKeyCount];
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index bcef14ca61..0b205b8b0e 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -6183,7 +6183,8 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
QString key = QLatin1String("WaveUnderline-")
% pen.color().name()
- % HexString<qreal>(radiusBase);
+ % HexString<qreal>(radiusBase)
+ % HexString<qreal>(pen.widthF());
QPixmap pixmap;
if (QPixmapCache::find(key, pixmap))
@@ -6191,7 +6192,7 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
const qreal halfPeriod = qMax(qreal(2), qreal(radiusBase * 1.61803399)); // the golden ratio
const int width = qCeil(100 / (2 * halfPeriod)) * (2 * halfPeriod);
- const int radius = qFloor(radiusBase);
+ const qreal radius = qFloor(radiusBase * 2) / 2.;
QPainterPath path;
@@ -6214,7 +6215,7 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
// due to it having a rather thick width for the regular underline.
const qreal maxPenWidth = .8 * radius;
if (wavePen.widthF() > maxPenWidth)
- wavePen.setWidth(maxPenWidth);
+ wavePen.setWidthF(maxPenWidth);
QPainter imgPainter(&pixmap);
imgPainter.setPen(wavePen);
@@ -6267,14 +6268,15 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
if (underlineStyle == QTextCharFormat::WaveUnderline) {
painter->save();
painter->translate(0, pos.y() + 1);
+ qreal maxHeight = fe->descent().toReal() - qreal(1);
QColor uc = charFormat.underlineColor();
if (uc.isValid())
pen.setColor(uc);
// Adapt wave to underlineOffset or pen width, whatever is larger, to make it work on all platforms
- const QPixmap wave = generateWavyPixmap(qMax(underlineOffset, pen.widthF()), pen);
- const int descent = (int) fe->descent().toReal();
+ const QPixmap wave = generateWavyPixmap(qMin(qMax(underlineOffset, pen.widthF()), maxHeight / 2.), pen);
+ const int descent = qFloor(maxHeight);
painter->setBrushOrigin(painter->brushOrigin().x(), 0);
painter->fillRect(pos.x(), 0, qCeil(width), qMin(wave.height(), descent), wave);
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index 8189351bd8..9e38c5272f 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -1202,7 +1202,7 @@ void QPdfEngine::setPen()
switch(d->pen.joinStyle()) {
case Qt::MiterJoin:
case Qt::SvgMiterJoin:
- *d->currentPage << d->pen.miterLimit() << "M ";
+ *d->currentPage << qMax(qreal(1.0), d->pen.miterLimit()) << "M ";
pdfJoinStyle = 0;
break;
case Qt::BevelJoin:
diff --git a/src/gui/text/qzip.cpp b/src/gui/text/qzip.cpp
index 5178f5a9a8..7cb89543ba 100644
--- a/src/gui/text/qzip.cpp
+++ b/src/gui/text/qzip.cpp
@@ -822,12 +822,12 @@ void QZipWriterPrivate::addEntry(EntryType type, const QString &fileName, const
QZipReader::QZipReader(const QString &archive, QIODevice::OpenMode mode)
{
QScopedPointer<QFile> f(new QFile(archive));
- f->open(mode);
+ const bool result = f->open(mode);
QZipReader::Status status;
const QFileDevice::FileError error = f->error();
- if (error == QFile::NoError)
+ if (result && error == QFile::NoError) {
status = NoError;
- else {
+ } else {
if (error == QFile::ReadError)
status = FileReadError;
else if (error == QFile::OpenError)
@@ -1119,9 +1119,8 @@ void QZipReader::close()
QZipWriter::QZipWriter(const QString &fileName, QIODevice::OpenMode mode)
{
QScopedPointer<QFile> f(new QFile(fileName));
- f->open(mode);
QZipWriter::Status status;
- if (f->error() == QFile::NoError)
+ if (f->open(mode) && f->error() == QFile::NoError)
status = QZipWriter::NoError;
else {
if (f->error() == QFile::WriteError)
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 67b4550607..45caaffe75 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -287,7 +287,6 @@ int q_X509Callback(int ok, X509_STORE_CTX *ctx)
qCDebug(lcSsl) << QSslCertificatePrivate::QSslCertificate_from_X509(q_X509_STORE_CTX_get_current_cert(ctx)).toPem();
qCDebug(lcSsl) << "dumping chain";
foreach (QSslCertificate cert, QSslSocketBackendPrivate::STACKOFX509_to_QSslCertificates(q_X509_STORE_CTX_get_chain(ctx))) {
- QString certFormat(QStringLiteral("O=%1 CN=%2 L=%3 OU=%4 C=%5 ST=%6"));
qCDebug(lcSsl) << "Issuer:" << "O=" << cert.issuerInfo(QSslCertificate::Organization)
<< "CN=" << cert.issuerInfo(QSslCertificate::CommonName)
<< "L=" << cert.issuerInfo(QSslCertificate::LocalityName)
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
index b288a05e32..652a9f4add 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -69,12 +69,6 @@ static inline int mapToQtWeightForRange(int fcweight, int fcLower, int fcUpper,
return qtLower + ((fcweight - fcLower) * (qtUpper - qtLower)) / (fcUpper - fcLower);
}
-static inline bool requiresOpenType(int writingSystem)
-{
- return ((writingSystem >= QFontDatabase::Syriac && writingSystem <= QFontDatabase::Sinhala)
- || writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko);
-}
-
static inline int weightFromFcWeight(int fcweight)
{
// Font Config uses weights from 0 to 215 (the highest enum value) while QFont ranges from
@@ -300,10 +294,10 @@ static const char *languageForWritingSystem[] = {
Q_STATIC_ASSERT(sizeof(languageForWritingSystem) / sizeof(const char *) == QFontDatabase::WritingSystemsCount);
#if FC_VERSION >= 20297
-// Newer FontConfig let's us sort out fonts that contain certain glyphs, but no
-// open type tables for is directly. Do this so we don't pick some strange
-// pseudo unicode font
-static const char *openType[] = {
+// Newer FontConfig let's us sort out fonts that report certain scripts support,
+// but no open type tables for handling them correctly.
+// Check the reported script presence in the FC_CAPABILITY's "otlayout:" section.
+static const char *capabilityForWritingSystem[] = {
0, // Any
0, // Latin
0, // Greek
@@ -339,7 +333,7 @@ static const char *openType[] = {
0, // Runic
"nko " // N'Ko
};
-Q_STATIC_ASSERT(sizeof(openType) / sizeof(const char *) == QFontDatabase::WritingSystemsCount);
+Q_STATIC_ASSERT(sizeof(capabilityForWritingSystem) / sizeof(*capabilityForWritingSystem) == QFontDatabase::WritingSystemsCount);
#endif
static const char *getFcFamilyForStyleHint(const QFont::StyleHint style)
@@ -422,11 +416,23 @@ static void populateFromPattern(FcPattern *pattern)
FcResult res = FcPatternGetLangSet(pattern, FC_LANG, 0, &langset);
if (res == FcResultMatch) {
bool hasLang = false;
+#if FC_VERSION >= 20297
+ FcChar8 *cap = Q_NULLPTR;
+ FcResult capRes = FcResultNoMatch;
+#endif
for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
const FcChar8 *lang = (const FcChar8*) languageForWritingSystem[j];
if (lang) {
FcLangResult langRes = FcLangSetHasLang(langset, lang);
if (langRes != FcLangDifferentLang) {
+#if FC_VERSION >= 20297
+ if (capabilityForWritingSystem[j] != Q_NULLPTR) {
+ if (cap == Q_NULLPTR)
+ capRes = FcPatternGetString(pattern, FC_CAPABILITY, 0, &cap);
+ if (capRes == FcResultMatch && strstr(reinterpret_cast<const char *>(cap), capabilityForWritingSystem[j]) == 0)
+ continue;
+ }
+#endif
writingSystems.setSupported(QFontDatabase::WritingSystem(j));
hasLang = true;
}
@@ -442,18 +448,6 @@ static void populateFromPattern(FcPattern *pattern)
writingSystems.setSupported(QFontDatabase::Other);
}
-#if FC_VERSION >= 20297
- for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
- if (writingSystems.supported(QFontDatabase::WritingSystem(j))
- && requiresOpenType(j) && openType[j]) {
- FcChar8 *cap;
- res = FcPatternGetString (pattern, FC_CAPABILITY, 0, &cap);
- if (res != FcResultMatch || !strstr((const char *)cap, openType[j]))
- writingSystems.setSupported(QFontDatabase::WritingSystem(j),false);
- }
- }
-#endif
-
FontFile *fontFile = new FontFile;
fontFile->fileName = QString::fromLocal8Bit((const char *)file_value);
fontFile->indexValue = indexValue;
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index 0690a8e0fa..a388155c03 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -105,7 +105,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate);
- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu
{
Q_ASSERT(m_menu->nsMenu() == menu);
- return m_menu->items().count();
+ return menu.numberOfItems;
}
- (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 908277a1e3..697cece77f 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -747,8 +747,7 @@ QT_WARNING_POP
- (void)handleMouseEvent:(NSEvent *)theEvent
{
- if ([self handleTabletEvent: theEvent])
- return;
+ bool isTabletEvent = [self handleTabletEvent: theEvent];
QPointF qtWindowPoint;
QPointF qtScreenPoint;
@@ -777,7 +776,8 @@ QT_WARNING_POP
nativeDrag->setLastMouseEvent(theEvent, self);
Qt::KeyboardModifiers keyboardModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]];
- QWindowSystemInterface::handleMouseEvent(targetView->m_window, timestamp, qtWindowPoint, qtScreenPoint, m_buttons, keyboardModifiers);
+ QWindowSystemInterface::handleMouseEvent(targetView->m_window, timestamp, qtWindowPoint, qtScreenPoint, m_buttons, keyboardModifiers,
+ isTabletEvent ? Qt::MouseEventSynthesizedByQt : Qt::MouseEventNotSynthesized);
}
- (void)handleFrameStrutMouseEvent:(NSEvent *)theEvent
diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
index f34649e327..5ba49a8a98 100644
--- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp
+++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
@@ -45,6 +45,7 @@
#include <QtGui/qaccessible.h>
#include <QtGui/qclipboard.h>
#include <QtGui/qguiapplication.h>
+#include <QtGui/private/qhighdpiscaling_p.h>
#include <QtCore/qdebug.h>
#include <algorithm>
@@ -607,7 +608,8 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_keyBinding(long actionIndex
// The IDL documents that the client must free with CoTaskMemFree
arrayOfBindingsToReturn = coTaskMemAllocArray<BSTR>(numBindings);
std::transform(keyBindings.constBegin(), keyBindings.constEnd(),
- arrayOfBindingsToReturn, QStringToBSTR);
+ QT_MAKE_CHECKED_ARRAY_ITERATOR(arrayOfBindingsToReturn, numBindings),
+ QStringToBSTR);
}
}
*keyBindings = arrayOfBindingsToReturn;
@@ -666,9 +668,11 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_locationInParent(long *x, l
QAccessibleInterface *parentIface = accessible->parent();
if (parentIface && parentIface->isValid())
topLeft -= parentIface->rect().topLeft();
+ const QPoint nativeTopLeft = QHighDpi::toNativeLocalPosition(topLeft, accessible->window());
- *x = topLeft.x();
- *y = topLeft.y();
+
+ *x = nativeTopLeft.x();
+ *y = nativeTopLeft.y();
return S_OK;
}
@@ -989,7 +993,8 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selectedColumns(long **sele
*selectedColumns = Q_NULLPTR;
if (count) {
*selectedColumns = coTaskMemAllocArray<long>(count);
- std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(), *selectedColumns);
+ std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(),
+ QT_MAKE_CHECKED_ARRAY_ITERATOR(*selectedColumns, count));
}
return count ? S_OK : S_FALSE;
}
@@ -1011,7 +1016,8 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selectedRows(long **selecte
*selectedRows = Q_NULLPTR;
if (count) {
*selectedRows = coTaskMemAllocArray<long>(count);
- std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(), *selectedRows);
+ std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(),
+ QT_MAKE_CHECKED_ARRAY_ITERATOR(*selectedRows, count));
}
return count ? S_OK : S_FALSE;
}
@@ -1680,7 +1686,8 @@ HRESULT QWindowsIA2Accessible::wrapListOfCells(const QList<QAccessibleInterface*
if (count) {
*outputAccessibles = coTaskMemAllocArray<IUnknown *>(count);
std::transform(inputCells.constBegin(), inputCells.constEnd(),
- *outputAccessibles, QWindowsAccessibility::wrap);
+ QT_MAKE_CHECKED_ARRAY_ITERATOR(*outputAccessibles, count),
+ QWindowsAccessibility::wrap);
}
return count > 0 ? S_OK : S_FALSE;
}
diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
index 0fff804e29..5fb06a6ed1 100644
--- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
+++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
@@ -55,6 +55,7 @@
#include <QtGui/qguiapplication.h>
#include <qpa/qplatformnativeinterface.h>
#include <QtGui/qwindow.h>
+#include <QtGui/private/qhighdpiscaling_p.h>
//#include <uiautomationcoreapi.h>
#ifndef UiaRootObjectId
@@ -503,7 +504,8 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accHitTest(long xLeft, long yT
if (!accessible)
return E_FAIL;
- QAccessibleInterface *child = accessible->childAt(xLeft, yTop);
+ const QPoint pos = QHighDpi::fromNativeLocalPosition(QPoint(xLeft, yTop), accessible->window());
+ QAccessibleInterface *child = accessible->childAt(pos.x(), pos.y());
if (child == 0) {
// no child found, return this item if it contains the coordinates
if (accessible->rect().contains(xLeft, yTop)) {
@@ -545,7 +547,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accLocation(long *pxLeft, long
QAccessibleInterface *acc = childPointer(accessible, varID);
if (!acc || !acc->isValid())
return E_FAIL;
- const QRect rect = acc->rect();
+ const QRect rect = QHighDpi::toNativePixels(acc->rect(), accessible->window());
*pxLeft = rect.x();
*pyTop = rect.y();
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
index ea68ba8cab..501b956a68 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
@@ -654,7 +654,7 @@ int QWindowsInputContext::reconvertString(RECONVERTSTRING *reconv)
reconv->dwTargetStrOffset = reconv->dwCompStrOffset;
ushort *pastReconv = reinterpret_cast<ushort *>(reconv + 1);
std::copy(surroundingText.utf16(), surroundingText.utf16() + surroundingText.size(),
- pastReconv);
+ QT_MAKE_UNCHECKED_ARRAY_ITERATOR(pastReconv));
return memSize;
}
diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.cpp b/src/plugins/platforms/winrt/qwinrtfileengine.cpp
index ad81ef4f5f..53e7ebd30d 100644
--- a/src/plugins/platforms/winrt/qwinrtfileengine.cpp
+++ b/src/plugins/platforms/winrt/qwinrtfileengine.cpp
@@ -466,14 +466,20 @@ qint64 QWinRTFileEngine::read(char *data, qint64 maxlen)
hr = stream->ReadAsync(buffer.Get(), length, InputStreamOptions_None, &op);
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
- hr = QWinRTFunctions::await(op, buffer.GetAddressOf());
+ // Quoting MSDN IInputStream::ReadAsync() documentation:
+ // "Depending on the implementation, the data that's read might be placed
+ // into the input buffer, or it might be returned in a different buffer."
+ // Using GetAddressOf can cause ref counting errors leaking the original
+ // buffer.
+ ComPtr<IBuffer> effectiveBuffer;
+ hr = QWinRTFunctions::await(op, effectiveBuffer.GetAddressOf());
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
- hr = buffer->get_Length(&length);
+ hr = effectiveBuffer->get_Length(&length);
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
ComPtr<Windows::Storage::Streams::IBufferByteAccess> byteArrayAccess;
- hr = buffer.As(&byteArrayAccess);
+ hr = effectiveBuffer.As(&byteArrayAccess);
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
byte *bytes;
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index f3667aaa0d..aed33f6b48 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -955,8 +955,20 @@ HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *, IPointerEventArgs *args)
return S_OK;
}
-HRESULT QWinRTScreen::onPointerExited(ICoreWindow *, IPointerEventArgs *)
+HRESULT QWinRTScreen::onPointerExited(ICoreWindow *, IPointerEventArgs *args)
{
+ Q_D(QWinRTScreen);
+
+ ComPtr<IPointerPoint> pointerPoint;
+ if (FAILED(args->get_CurrentPoint(&pointerPoint)))
+ return E_INVALIDARG;
+
+ quint32 id;
+ if (FAILED(pointerPoint->get_PointerId(&id)))
+ return E_INVALIDARG;
+
+ d->touchPoints.remove(id);
+
QWindowSystemInterface::handleLeaveEvent(0);
return S_OK;
}
@@ -1040,6 +1052,7 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
break;
}
+ case PointerDeviceType_Pen:
case PointerDeviceType_Touch: {
if (!d->touchDevice) {
d->touchDevice = new QTouchDevice;
@@ -1058,51 +1071,45 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
float pressure;
properties->get_Pressure(&pressure);
- QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator it = d->touchPoints.find(id);
- if (it != d->touchPoints.end()) {
- boolean isPressed;
+ boolean isPressed;
#ifndef Q_OS_WINPHONE
- pointerPoint->get_IsInContact(&isPressed);
+ pointerPoint->get_IsInContact(&isPressed);
#else
- properties->get_IsLeftButtonPressed(&isPressed); // IsInContact not reliable on phone
+ properties->get_IsLeftButtonPressed(&isPressed); // IsInContact not reliable on phone
#endif
- it.value().state = isPressed ? Qt::TouchPointMoved : Qt::TouchPointReleased;
- } else {
+
+ const QRectF areaRect(area.X * d->scaleFactor, area.Y * d->scaleFactor,
+ area.Width * d->scaleFactor, area.Height * d->scaleFactor);
+
+ QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator it = d->touchPoints.find(id);
+ if (it == d->touchPoints.end()) {
it = d->touchPoints.insert(id, QWindowSystemInterface::TouchPoint());
- it.value().state = Qt::TouchPointPressed;
it.value().id = id;
}
- it.value().area = QRectF(area.X * d->scaleFactor, area.Y * d->scaleFactor,
- area.Width * d->scaleFactor, area.Height * d->scaleFactor);
+
+ if (isPressed && it.value().pressure == 0.)
+ it.value().state = Qt::TouchPointPressed;
+ else if (!isPressed && it.value().pressure > 0.)
+ it.value().state = Qt::TouchPointReleased;
+ else if (it.value().area == areaRect)
+ it.value().state = Qt::TouchPointStationary;
+ else
+ it.value().state = Qt::TouchPointMoved;
+
+ it.value().area = areaRect;
it.value().normalPosition = QPointF(point.X/d->logicalRect.width(), point.Y/d->logicalRect.height());
it.value().pressure = pressure;
QWindowSystemInterface::handleTouchEvent(topWindow(), d->touchDevice, d->touchPoints.values(), mods);
- // Remove released points, station others
- for (QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator i = d->touchPoints.begin(); i != d->touchPoints.end();) {
- if (i.value().state == Qt::TouchPointReleased)
- i = d->touchPoints.erase(i);
- else
- (i++).value().state = Qt::TouchPointStationary;
- }
-
- break;
- }
- case PointerDeviceType_Pen: {
- quint32 id;
- pointerPoint->get_PointerId(&id);
-
- boolean isPressed;
- pointerPoint->get_IsInContact(&isPressed);
+ // Fall-through for pen to generate tablet event
+ if (pointerDeviceType != PointerDeviceType_Pen)
+ break;
boolean isEraser;
properties->get_IsEraser(&isEraser);
int pointerType = isEraser ? 3 : 1;
- float pressure;
- properties->get_Pressure(&pressure);
-
float xTilt;
properties->get_XTilt(&xTilt);
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index ea20ef7a04..1c9faa17ea 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -1078,6 +1078,40 @@ void QXcbDrag::cancel()
send_leave();
}
+// find an ancestor with XdndAware on it
+static xcb_window_t findXdndAwareParent(QXcbConnection *c, xcb_window_t window)
+{
+ xcb_window_t target = 0;
+ forever {
+ // check if window has XdndAware
+ xcb_get_property_cookie_t gpCookie = Q_XCB_CALL(
+ xcb_get_property(c->xcb_connection(), false, window,
+ c->atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 0));
+ xcb_get_property_reply_t *gpReply = xcb_get_property_reply(
+ c->xcb_connection(), gpCookie, 0);
+ bool aware = gpReply && gpReply->type != XCB_NONE;
+ free(gpReply);
+ if (aware) {
+ target = window;
+ break;
+ }
+
+ // try window's parent
+ xcb_query_tree_cookie_t qtCookie = Q_XCB_CALL(
+ xcb_query_tree_unchecked(c->xcb_connection(), window));
+ xcb_query_tree_reply_t *qtReply = xcb_query_tree_reply(
+ c->xcb_connection(), qtCookie, NULL);
+ if (!qtReply)
+ break;
+ xcb_window_t root = qtReply->root;
+ xcb_window_t parent = qtReply->parent;
+ free(qtReply);
+ if (window == root)
+ break;
+ window = parent;
+ }
+ return target;
+}
void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event)
{
@@ -1105,17 +1139,16 @@ void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event
// xcb_convert_selection() that we sent the XdndDrop event to.
at = findTransactionByWindow(event->requestor);
}
-// if (at == -1 && event->time == XCB_CURRENT_TIME) {
-// // previous Qt versions always requested the data on a child of the target window
-// // using CurrentTime... but it could be asking for either drop data or the current drag's data
-// Window target = findXdndAwareParent(event->requestor);
-// if (target) {
-// if (current_target && current_target == target)
-// at = -2;
-// else
-// at = findXdndDropTransactionByWindow(target);
-// }
-// }
+
+ if (at == -1 && event->time == XCB_CURRENT_TIME) {
+ xcb_window_t target = findXdndAwareParent(connection(), event->requestor);
+ if (target) {
+ if (current_target == target)
+ at = -2;
+ else
+ at = findTransactionByWindow(target);
+ }
+ }
}
QDrag *transactionDrag = 0;
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index f4f758df6c..dcd1268f6f 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -239,6 +239,7 @@ namespace QTest
static int keyDelay = -1;
static int mouseDelay = -1;
static int eventDelay = -1;
+ static int timeout = -1;
static bool noCrashHandler = false;
/*! \internal
@@ -290,6 +291,18 @@ int Q_TESTLIB_EXPORT defaultKeyDelay()
return keyDelay;
}
+static int defaultTimeout()
+{
+ if (timeout == -1) {
+ bool ok = false;
+ timeout = qEnvironmentVariableIntValue("QTEST_FUNCTION_TIMEOUT", &ok);
+
+ if (!ok || timeout <= 0)
+ timeout = 5*60*1000;
+ }
+ return timeout;
+}
+
Q_TESTLIB_EXPORT bool printAvailableFunctions = false;
Q_TESTLIB_EXPORT QStringList testFunctions;
Q_TESTLIB_EXPORT QStringList testTags;
@@ -867,7 +880,7 @@ public:
void beginTest() {
QMutexLocker locker(&mutex);
- timeout.store(5*60*1000);
+ timeout.store(defaultTimeout());
waitCondition.wakeAll();
}
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index d9b6dc05bf..1cf2d2b05e 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -3596,7 +3596,7 @@ void QFileDialogPrivate::_q_enterDirectory(const QModelIndex &index)
}
} else {
// Do not accept when shift-clicking to multi-select a file in environments with single-click-activation (KDE)
- if (!q->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick)
+ if (!q->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, Q_NULLPTR, qFileDialogUi->treeView)
|| q->fileMode() != QFileDialog::ExistingFiles || !(QGuiApplication::keyboardModifiers() & Qt::CTRL)) {
q->accept();
}
diff --git a/src/widgets/dialogs/qfilesystemmodel.h b/src/widgets/dialogs/qfilesystemmodel.h
index b7e77f31db..6d50d0b606 100644
--- a/src/widgets/dialogs/qfilesystemmodel.h
+++ b/src/widgets/dialogs/qfilesystemmodel.h
@@ -81,6 +81,7 @@ public:
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
QModelIndex index(const QString &path, int column = 0) const;
QModelIndex parent(const QModelIndex &child) const Q_DECL_OVERRIDE;
+ using QObject::parent;
QModelIndex sibling(int row, int column, const QModelIndex &idx) const Q_DECL_OVERRIDE;
bool hasChildren(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
bool canFetchMore(const QModelIndex &parent) const Q_DECL_OVERRIDE;
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
index 103c49496e..3e17b22102 100644
--- a/src/widgets/styles/qstyle.cpp
+++ b/src/widgets/styles/qstyle.cpp
@@ -157,10 +157,10 @@ static int unpackControlTypes(QSizePolicy::ControlTypes controls, QSizePolicy::C
Qt's built-in widgets use QStyle to perform nearly all of their
drawing, ensuring that they look exactly like the equivalent
- native widgets. The diagram below shows a QComboBox in eight
+ native widgets. The diagram below shows a QComboBox in nine
different styles.
- \image qstyle-comboboxes.png Eight combo boxes
+ \image qstyle-comboboxes.png Nine combo boxes
Topics:
diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp
index 2ad9f88e6b..1482b990a6 100644
--- a/src/widgets/widgets/qabstractscrollarea.cpp
+++ b/src/widgets/widgets/qabstractscrollarea.cpp
@@ -310,7 +310,7 @@ void QAbstractScrollAreaPrivate::init()
viewportFilter.reset(new QAbstractScrollAreaFilter(this));
viewport->installEventFilter(viewportFilter.data());
viewport->setFocusProxy(q);
- q->setFocusPolicy(Qt::WheelFocus);
+ q->setFocusPolicy(Qt::StrongFocus);
q->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
layoutChildren();
diff --git a/src/widgets/widgets/qabstractslider.cpp b/src/widgets/widgets/qabstractslider.cpp
index 3f6185b4e7..4221ff40ef 100644
--- a/src/widgets/widgets/qabstractslider.cpp
+++ b/src/widgets/widgets/qabstractslider.cpp
@@ -734,9 +734,10 @@ bool QAbstractSliderPrivate::scrollByDelta(Qt::Orientation orientation, Qt::Keyb
if (stepsToScroll == 0) {
// We moved less than a line, but might still have accumulated partial scroll,
// unless we already are at one of the ends.
- if (offset_accumulated > 0.f && value < maximum)
+ const float effective_offset = invertedControls ? -offset_accumulated : offset_accumulated;
+ if (effective_offset > 0.f && value < maximum)
return true;
- if (offset_accumulated < 0.f && value > minimum)
+ if (effective_offset < 0.f && value > minimum)
return true;
offset_accumulated = 0;
return false;
diff --git a/src/widgets/widgets/qdatetimeedit_p.h b/src/widgets/widgets/qdatetimeedit_p.h
index 6abb3cd9a3..be7bc213a2 100644
--- a/src/widgets/widgets/qdatetimeedit_p.h
+++ b/src/widgets/widgets/qdatetimeedit_p.h
@@ -78,15 +78,14 @@ public:
void init(const QVariant &var);
void readLocaleSettings();
- void emitSignals(EmitPolicy ep, const QVariant &old);
- QString textFromValue(const QVariant &f) const;
- QVariant valueFromText(const QString &f) const;
-
QDateTime validateAndInterpret(QString &input, int &, QValidator::State &state,
bool fixup = false) const;
void clearSection(int index);
// Override QAbstractSpinBoxPrivate:
+ void emitSignals(EmitPolicy ep, const QVariant &old) Q_DECL_OVERRIDE;
+ QString textFromValue(const QVariant &f) const Q_DECL_OVERRIDE;
+ QVariant valueFromText(const QString &f) const Q_DECL_OVERRIDE;
void _q_editorCursorPositionChanged(int oldpos, int newpos) Q_DECL_OVERRIDE;
void interpret(EmitPolicy ep) Q_DECL_OVERRIDE;
void clearCache() const Q_DECL_OVERRIDE;
@@ -94,16 +93,18 @@ public:
void updateEditFieldGeometry() Q_DECL_OVERRIDE;
QVariant getZeroVariant() const Q_DECL_OVERRIDE;
void setRange(const QVariant &min, const QVariant &max) Q_DECL_OVERRIDE;
+ void updateEdit() Q_DECL_OVERRIDE;
- // Override QDateTimePraser:
+ // Override QDateTimeParser:
QString displayText() const Q_DECL_OVERRIDE { return edit->text(); }
QDateTime getMinimum() const Q_DECL_OVERRIDE { return minimum.toDateTime(); }
QDateTime getMaximum() const Q_DECL_OVERRIDE { return maximum.toDateTime(); }
QLocale locale() const Q_DECL_OVERRIDE { return q_func()->locale(); }
+ QString getAmPmText(AmPm ap, Case cs) const Q_DECL_OVERRIDE;
+ int cursorPosition() const Q_DECL_OVERRIDE { return edit ? edit->cursorPosition() : -1; }
int absoluteIndex(QDateTimeEdit::Section s, int index) const;
int absoluteIndex(const SectionNode &s) const;
- void updateEdit();
QDateTime stepBy(int index, int steps, bool test = false) const;
int sectionAt(int pos) const;
int closestSection(int index, bool forward) const;
@@ -114,8 +115,6 @@ public:
void updateTimeSpec();
QString valueToText(const QVariant &var) const { return textFromValue(var); }
- QString getAmPmText(AmPm ap, Case cs) const;
- int cursorPosition() const { return edit ? edit->cursorPosition() : -1; }
void _q_resetButton();
void updateArrow(QStyle::StateFlag state);
diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp
index 1da8028efb..9675e5e9f2 100644
--- a/src/widgets/widgets/qplaintextedit.cpp
+++ b/src/widgets/widgets/qplaintextedit.cpp
@@ -802,7 +802,7 @@ void QPlainTextEditPrivate::init(const QString &txt)
viewport->setBackgroundRole(QPalette::Base);
q->setAcceptDrops(true);
- q->setFocusPolicy(Qt::WheelFocus);
+ q->setFocusPolicy(Qt::StrongFocus);
q->setAttribute(Qt::WA_KeyCompression);
q->setAttribute(Qt::WA_InputMethodEnabled);
q->setInputMethodHints(Qt::ImhMultiLine);
diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp
index a81781bd4d..df69b49687 100644
--- a/src/widgets/widgets/qtextedit.cpp
+++ b/src/widgets/widgets/qtextedit.cpp
@@ -177,7 +177,7 @@ void QTextEditPrivate::init(const QString &html)
viewport->setBackgroundRole(QPalette::Base);
q->setAcceptDrops(true);
- q->setFocusPolicy(Qt::WheelFocus);
+ q->setFocusPolicy(Qt::StrongFocus);
q->setAttribute(Qt::WA_KeyCompression);
q->setAttribute(Qt::WA_InputMethodEnabled);
q->setInputMethodHints(Qt::ImhMultiLine);
diff --git a/tests/auto/corelib/tools/qtimezone/BLACKLIST b/tests/auto/corelib/tools/qtimezone/BLACKLIST
deleted file mode 100644
index 665e78bc08..0000000000
--- a/tests/auto/corelib/tools/qtimezone/BLACKLIST
+++ /dev/null
@@ -1,2 +0,0 @@
-[tzTest]
-opensuse-13.1
diff --git a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp
index 077a6a20f1..9fd418742c 100644
--- a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp
+++ b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp
@@ -762,16 +762,22 @@ void tst_QTimeZone::tzTest()
// Warning: This could vary depending on age of TZ file!
// Test low date uses first rule found
+ // Note: Depending on the OS in question, the database may be carrying the
+ // Local Mean Time. which for Berlin is 0:53:28
QTimeZonePrivate::Data dat = tzp.data(-9999999999999);
QCOMPARE(dat.atMSecsSinceEpoch, (qint64)-9999999999999);
- QCOMPARE(dat.standardTimeOffset, 3600);
QCOMPARE(dat.daylightTimeOffset, 0);
+ if (dat.abbreviation == "LMT") {
+ QCOMPARE(dat.standardTimeOffset, 3208);
+ } else {
+ QCOMPARE(dat.standardTimeOffset, 3600);
- // Test previous to low value is invalid
- dat = tzp.previousTransition(-9999999999999);
- QCOMPARE(dat.atMSecsSinceEpoch, std::numeric_limits<qint64>::min());
- QCOMPARE(dat.standardTimeOffset, std::numeric_limits<int>::min());
- QCOMPARE(dat.daylightTimeOffset, std::numeric_limits<int>::min());
+ // Test previous to low value is invalid
+ dat = tzp.previousTransition(-9999999999999);
+ QCOMPARE(dat.atMSecsSinceEpoch, std::numeric_limits<qint64>::min());
+ QCOMPARE(dat.standardTimeOffset, std::numeric_limits<int>::min());
+ QCOMPARE(dat.daylightTimeOffset, std::numeric_limits<int>::min());
+ }
dat = tzp.nextTransition(-9999999999999);
QCOMPARE(dat.atMSecsSinceEpoch, (qint64)-2422054408000);
diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp
index 3418a34c12..0163f44a36 100644
--- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp
+++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp
@@ -1213,6 +1213,27 @@ void tst_QDBusConnection::callVirtualObjectLocal()
QCOMPARE(obj.replyArguments, subPathReply.arguments());
}
+void tst_QDBusConnection::pendingCallWhenDisconnected()
+{
+ if (!QCoreApplication::instance())
+ QSKIP("Test requires a QCoreApplication");
+
+ QDBusServer *server = new QDBusServer;
+ QDBusConnection con = QDBusConnection::connectToPeer(server->address(), "disconnect");
+ QTestEventLoop::instance().enterLoop(2);
+ QVERIFY(con.isConnected());
+ QDBusMessage message = QDBusMessage::createMethodCall("", "/", QString(), "method");
+ QDBusPendingCall reply = con.asyncCall(message);
+
+ delete server;
+
+ QTestEventLoop::instance().enterLoop(2);
+ QVERIFY(!con.isConnected());
+ QVERIFY(reply.isFinished());
+ QVERIFY(reply.isError());
+ QVERIFY(reply.error().type() == QDBusError::Disconnected);
+}
+
QString MyObject::path;
QString MyObjectWithoutInterface::path;
QString MyObjectWithoutInterface::interface;
diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h
index 0e2943b1c4..0402889c6e 100644
--- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h
+++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h
@@ -116,6 +116,7 @@ private slots:
void registerVirtualObject();
void callVirtualObject();
void callVirtualObjectLocal();
+ void pendingCallWhenDisconnected();
public:
QString serviceName() const { return "org.qtproject.Qt.Autotests.QDBusConnection"; }
diff --git a/tests/auto/other/compiler/tst_compiler.cpp b/tests/auto/other/compiler/tst_compiler.cpp
index d554a50c8d..50cfe48cdf 100644
--- a/tests/auto/other/compiler/tst_compiler.cpp
+++ b/tests/auto/other/compiler/tst_compiler.cpp
@@ -679,25 +679,105 @@ void tst_Compiler::cxx11_atomics()
#endif
}
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_CLANG("-Wignored-attributes")
+QT_WARNING_DISABLE_CLANG("-Wunused-local-typedefs")
+QT_WARNING_DISABLE_GCC("-Wattributes")
+QT_WARNING_DISABLE_GCC("-Wunused-local-typedefs")
+
+#ifndef __has_cpp_attribute
+# define __has_cpp_attribute(x) 0
+#endif
+#ifdef Q_COMPILER_ATTRIBUTES
+[[noreturn]] void attribute_f1();
+void attribute_f2 [[noreturn]] ();
+# if (defined(__cpp_namespace_attributes) && __cpp_namespace_attributes >= 201411) && __has_cpp_attribute(deprecated)
+namespace NS [[deprecated]] { }
+# endif
+#endif
+
void tst_Compiler::cxx11_attributes()
{
#ifndef Q_COMPILER_ATTRIBUTES
QSKIP("Compiler does not support C++11 feature");
#else
- struct [[deprecated]] C {};
+ // Attributes in function parameters and using clauses cause MSVC 2015 to crash
+ // https://connect.microsoft.com/VisualStudio/feedback/details/2011594
+# if (!defined(Q_CC_MSVC) || _MSC_FULL_VER >= 190023811) && !defined(Q_CC_INTEL)
+ void f([[ ]] int);
+ [[ ]] using namespace QtPrivate;
+ [[ ]] try {
+ } catch ([[]] int) {
+ }
+# endif
+
+ struct [[ ]] A { };
+ struct B : A {
+ [[ ]] int m_i : 32;
+ [[noreturn]] void f() const { ::exit(0); }
+
+# ifdef Q_COMPILER_DEFAULT_DELETE_MEMBERS
+ [[ ]] ~B() = default;
+ [[ ]] B(const B &) = delete;
+# endif
+ };
+# if __has_cpp_attribute(deprecated)
+ struct [[deprecated]] C { };
+# endif
+ enum [[ ]] E { };
+ [[ ]] void [[ ]] * [[ ]] * [[ ]] ptr = 0;
+ int B::* [[ ]] pmm = 0;
+
+# if __has_cpp_attribute(deprecated)
+ enum [[deprecated]] E2 {
+# if defined(__cpp_enumerator_attributes) && __cpp_enumerator_attributes >= 201411
+ value [[deprecated]] = 0
+# endif
+ };
+# endif
+# ifdef Q_COMPILER_LAMBDA
+ []()[[ ]] {}();
+# endif
+# ifdef Q_COMPILER_TEMPLATE_ALIAS
+ using B2 [[ ]] = B;
+# endif
+
+ [[ ]] goto end;
+# ifdef Q_CC_GNU
+ // Attributes in gnu:: namespace
+ [[gnu::unused]] end:
+ ;
[[gnu::unused]] struct D {} d;
- [[noreturn]] void f();
struct D e [[gnu::used, gnu::unused]];
- [[gnu::aligned(8)]] int i;
+ [[gnu::aligned(8)]] int i [[ ]];
+ int array[][[]] = { 1 };
+# else
+ // Non GNU, so use an empty attribute
+ [[ ]] end:
+ ;
+ [[ ]] struct D {} d;
+ struct D e [[ ]];
+ [[ ]] int i [[ ]];
+ int array[][[]] = { 1 };
+# endif
-[[gnu::unused]] end:
- ;
+ int & [[ ]] lref = i;
+ int && [[ ]] rref = 1;
+ [[ ]] (void)1;
+ [[ ]] for (i = 0; i < 2; ++i)
+ ;
+ Q_UNUSED(ptr);
+ Q_UNUSED(pmm);
Q_UNUSED(d);
Q_UNUSED(e);
Q_UNUSED(i);
+ Q_UNUSED(array);
+ Q_UNUSED(lref);
+ Q_UNUSED(rref);
#endif
}
+QT_WARNING_POP
#ifdef Q_COMPILER_AUTO_FUNCTION
auto autoFunction() -> unsigned
diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
index 3183fc7375..f0e7cb5901 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -465,6 +465,7 @@ private:
const QString m_platform;
QSize m_testWidgetSize;
QPoint m_availableTopLeft;
+ QPoint m_safeCursorPos;
const bool m_windowsAnimationsEnabled;
};
@@ -622,6 +623,7 @@ void tst_QWidget::getSetCheck()
tst_QWidget::tst_QWidget()
: m_platform(QGuiApplication::platformName().toLower())
+ , m_safeCursorPos(0, 0)
, m_windowsAnimationsEnabled(windowsAnimationsEnabled())
{
if (m_windowsAnimationsEnabled) // Disable animations which can interfere with screen grabbing in moveChild(), showAndMoveChild()
@@ -664,7 +666,13 @@ void tst_QWidget::initTestCase()
// to avoid Windows warnings about minimum size for decorated windows.
int width = 200;
const QScreen *screen = QGuiApplication::primaryScreen();
- m_availableTopLeft = screen->availableGeometry().topLeft();
+ const QRect availableGeometry = screen->availableGeometry();
+ m_availableTopLeft = availableGeometry.topLeft();
+ // XCB: Determine "safe" cursor position at bottom/right corner of screen.
+ // Pushing the mouse rapidly to the top left corner can trigger KDE / KWin's
+ // "Present all Windows" (Ctrl+F9) feature also programmatically.
+ if (m_platform == QLatin1String("xcb"))
+ m_safeCursorPos = availableGeometry.bottomRight() - QPoint(40, 40);
const int screenWidth = screen->geometry().width();
if (screenWidth > 2000)
width = 100 * ((screenWidth + 500) / 1000);
@@ -5664,7 +5672,7 @@ void tst_QWidget::setToolTip()
// Mouse over doesn't work on Windows mobile, so skip the rest of the test for that platform.
#ifndef Q_OS_WINCE_WM
for (int pass = 0; pass < 2; ++pass) {
- QCursor::setPos(0, 0);
+ QCursor::setPos(m_safeCursorPos);
QScopedPointer<QWidget> popup(new QWidget(0, Qt::Popup));
popup->setObjectName(QLatin1String("tst_qwidget setToolTip #") + QString::number(pass));
popup->setWindowTitle(popup->objectName());
@@ -6015,7 +6023,7 @@ void tst_QWidget::childEvents()
// Move away the cursor; otherwise it might result in an enter event if it's
// inside the widget when the widget is shown.
- QCursor::setPos(qApp->desktop()->availableGeometry().bottomRight());
+ QCursor::setPos(m_safeCursorPos);
QTest::qWait(100);
{
@@ -8878,7 +8886,7 @@ void tst_QWidget::syntheticEnterLeave()
int numLeaveEvents;
};
- QCursor::setPos(QPoint(0,0));
+ QCursor::setPos(m_safeCursorPos);
MyWidget window;
window.setWindowFlags(Qt::WindowStaysOnTopHint);
@@ -8998,7 +9006,7 @@ void tst_QWidget::taskQTBUG_4055_sendSyntheticEnterLeave()
int numEnterEvents, numMouseMoveEvents;
};
- QCursor::setPos(QPoint(0,0));
+ QCursor::setPos(m_safeCursorPos);
SELParent parent;
parent.move(200, 200);
@@ -10174,7 +10182,7 @@ void tst_QWidget::destroyedSignal()
void tst_QWidget::underMouse()
{
// Move the mouse cursor to a safe location
- QCursor::setPos(0,0);
+ QCursor::setPos(m_safeCursorPos);
ColorWidget topLevelWidget(0, Qt::FramelessWindowHint, Qt::blue);
ColorWidget childWidget1(&topLevelWidget, Qt::Widget, Qt::yellow);
@@ -10430,7 +10438,7 @@ public:
void tst_QWidget::taskQTBUG_27643_enterEvents()
{
// Move the mouse cursor to a safe location so it won't interfere
- QCursor::setPos(0,0);
+ QCursor::setPos(m_safeCursorPos);
EnterTestMainDialog dialog;
QPushButton button(&dialog);
diff --git a/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp b/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp
index d4b221a4a7..e68463a00e 100644
--- a/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp
+++ b/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp
@@ -77,6 +77,8 @@ private slots:
#ifndef QT_NO_WHEELEVENT
void wheelEvent_data();
void wheelEvent();
+ void fineGrainedWheelEvent_data();
+ void fineGrainedWheelEvent();
#endif
void sliderPressedReleased_data();
void sliderPressedReleased();
@@ -892,6 +894,55 @@ void tst_QAbstractSlider::wheelEvent()
if (expectedSignalCount)
QVERIFY(actionTriggeredTimeStamp < valueChangedTimeStamp);
}
+
+void tst_QAbstractSlider::fineGrainedWheelEvent_data()
+{
+ QTest::addColumn<bool>("invertedControls");
+ QTest::newRow("invertedControls=false") << false;
+ QTest::newRow("invertedControls=true") << true;
+}
+
+void tst_QAbstractSlider::fineGrainedWheelEvent()
+{
+ QFETCH(bool, invertedControls);
+
+ QCoreApplication *applicationInstance = QCoreApplication::instance();
+ QVERIFY(applicationInstance != 0);
+ QApplication::setWheelScrollLines(3);
+
+ slider->setRange(0, 10);
+ slider->setSingleStep(1);
+ slider->setPageStep(10);
+ slider->setInvertedControls(invertedControls);
+ slider->setOrientation(Qt::Vertical);
+ slider->setSliderPosition(0);
+
+ const int singleStepDelta = invertedControls ? (-WHEEL_DELTA / 3) : (WHEEL_DELTA / 3);
+
+ QWheelEvent eventDown(slider->rect().bottomRight(), singleStepDelta / 2,
+ Qt::NoButton, Qt::NoModifier, Qt::Vertical);
+ QVERIFY(applicationInstance->sendEvent(slider,&eventDown));
+ QCOMPARE(slider->sliderPosition(), 0);
+ QVERIFY(applicationInstance->sendEvent(slider,&eventDown));
+ QCOMPARE(slider->sliderPosition(), 1);
+
+ QWheelEvent eventUp(slider->rect().bottomRight(), -singleStepDelta / 2,
+ Qt::NoButton, Qt::NoModifier, Qt::Vertical);
+ QVERIFY(applicationInstance->sendEvent(slider,&eventUp));
+ QCOMPARE(slider->sliderPosition(), 1);
+ QVERIFY(applicationInstance->sendEvent(slider,&eventUp));
+ QCOMPARE(slider->sliderPosition(), 0);
+ QVERIFY(applicationInstance->sendEvent(slider,&eventUp));
+ QCOMPARE(slider->sliderPosition(), 0);
+ QVERIFY(applicationInstance->sendEvent(slider,&eventUp));
+ QCOMPARE(slider->sliderPosition(), 0);
+
+ QVERIFY(applicationInstance->sendEvent(slider,&eventDown));
+ QCOMPARE(slider->sliderPosition(), 0);
+ QVERIFY(applicationInstance->sendEvent(slider,&eventDown));
+ QCOMPARE(slider->sliderPosition(), 1);
+}
+
#endif // !QT_NO_WHEELEVENT
void tst_QAbstractSlider::sliderPressedReleased_data()
diff --git a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp
index 607fc1625a..d568cf63d4 100644
--- a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp
+++ b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp
@@ -492,6 +492,7 @@ void tst_QMdiArea::subWindowActivated2()
spy.clear();
mdiArea.show();
+ mdiArea.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&mdiArea));
QTRY_COMPARE(spy.count(), 1);
QVERIFY(mdiArea.currentSubWindow());
diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro
index 8777cc6e11..bec098d462 100644
--- a/tests/manual/manual.pro
+++ b/tests/manual/manual.pro
@@ -31,6 +31,7 @@ qsysinfo \
qtabletevent \
qtexteditlist \
qtbug-8933 \
+qtbug-52641 \
qtouchevent \
touch \
qwidget_zorder \
diff --git a/tests/manual/qtabletevent/device_information/tabletwidget.cpp b/tests/manual/qtabletevent/device_information/tabletwidget.cpp
index a30e32b6d9..b4273bde8e 100644
--- a/tests/manual/qtabletevent/device_information/tabletwidget.cpp
+++ b/tests/manual/qtabletevent/device_information/tabletwidget.cpp
@@ -33,7 +33,7 @@
#include <QMetaObject>
#include <QMetaEnum>
-TabletWidget::TabletWidget(bool mouseToo) : mMouseToo(mouseToo)
+TabletWidget::TabletWidget(bool mouseToo) : mMouseToo(mouseToo), mWheelEventCount(0)
{
QPalette newPalette = palette();
newPalette.setColor(QPalette::Window, Qt::white);
@@ -82,6 +82,10 @@ bool TabletWidget::eventFilter(QObject *, QEvent *ev)
mGPos = event->globalPos();
mTimestamp = event->timestamp();
}
+ break;
+ case QEvent::Wheel:
+ ++mWheelEventCount;
+ break;
default:
break;
}
@@ -176,6 +180,8 @@ void TabletWidget::paintEvent(QPaintEvent *)
eventInfo << QString("z: %1").arg(QString::number(mZ));
eventInfo << QString("Unique Id: %1").arg(QString::number(mUnique));
+
+ eventInfo << QString("Total wheel events: %1").arg(QString::number(mWheelEventCount));
}
QString text = eventInfo.join("\n");
diff --git a/tests/manual/qtabletevent/device_information/tabletwidget.h b/tests/manual/qtabletevent/device_information/tabletwidget.h
index 4e6520e4cc..2b014a213a 100644
--- a/tests/manual/qtabletevent/device_information/tabletwidget.h
+++ b/tests/manual/qtabletevent/device_information/tabletwidget.h
@@ -61,6 +61,7 @@ private:
qint64 mUnique;
bool mMouseToo;
ulong mTimestamp;
+ int mWheelEventCount;
};
#endif // TABLETWIDGET_H
diff --git a/tests/manual/qtbug-52641/main.cpp b/tests/manual/qtbug-52641/main.cpp
new file mode 100644
index 0000000000..33ebd8584c
--- /dev/null
+++ b/tests/manual/qtbug-52641/main.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Kai Pastor
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite 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$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include <QFileDialog>
+#include <QPainter>
+#include <QPdfWriter>
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+
+ QString filepath = QFileDialog::getSaveFileName(nullptr, "Save File", "",
+ "PDF files (*.pdf)");
+ if (filepath.isEmpty())
+ return 1;
+ QPdfWriter writer(filepath);
+ writer.setPageSize(QPageSize(QPageSize::A4));
+ writer.setResolution(300);
+
+ QPainterPath path;
+ path.moveTo(0,0);
+ path.lineTo(1000,0);
+ path.lineTo(1000,1000);
+ path.lineTo(0,800);
+ path.lineTo(500,100);
+ path.lineTo(800,900);
+ path.lineTo(300,600);
+
+ QPen pen;
+ pen.setWidth(30);
+ pen.setJoinStyle(Qt::MiterJoin);
+
+ // The black path on the first page must always be visible in the PDF viewer.
+ QPainter p(&writer);
+ pen.setMiterLimit(6.0);
+ p.setPen(pen);
+ p.drawPath(path);
+
+ // If a miter limit below 1.0 is written to the PDF,
+ // broken PDF viewers may not show the red path on the second page.
+ writer.newPage();
+ pen.setMiterLimit(0.6);
+ pen.setColor(Qt::red);
+ p.setPen(pen);
+ p.drawPath(path);
+
+ p.end();
+ return 0;
+}
diff --git a/tests/manual/qtbug-52641/qtbug-52641.pro b/tests/manual/qtbug-52641/qtbug-52641.pro
new file mode 100644
index 0000000000..5a9ff6df52
--- /dev/null
+++ b/tests/manual/qtbug-52641/qtbug-52641.pro
@@ -0,0 +1,5 @@
+TARGET = qtbug-52641
+TEMPLATE = app
+QT = core gui widgets
+SOURCES = main.cpp
+