summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2018-02-15 10:14:11 +0100
committerLiang Qi <liang.qi@qt.io>2018-02-15 10:14:11 +0100
commitbb0fec8057dd11c359bfcb4aefb66d9b210f52a6 (patch)
tree903e3220087ff7a3210390933ba3d8b8f7eb5ea3
parent8920bf32eebe03cfc8a1a5e97f5b34c09c79a11b (diff)
parent4ba535616b8d3dfda7fbe162c6513f3008c1077a (diff)
Merge remote-tracking branch 'origin/5.10' into 5.11
Conflicts: src/corelib/corelib.pro src/corelib/global/qrandom.cpp src/network/access/qhttpnetworkrequest_p.h src/plugins/platforms/cocoa/qcocoamenu.mm src/plugins/platforms/cocoa/qcocoansmenu.mm src/plugins/platforms/cocoa/qcocoawindow.mm src/plugins/platforms/cocoa/qnsview.mm src/plugins/platforms/offscreen/qoffscreenintegration.h src/widgets/kernel/qaction.cpp src/widgets/widgets.pro Done-with: Andy Shaw <andy.shaw@qt.io> Change-Id: Ib01547cf4184023f19858ccf0ce7fb824fed2a8d
-rw-r--r--examples/gui/rasterwindow/rasterwindow.cpp1
-rw-r--r--examples/widgets/tutorials/notepad/notepad.cpp11
-rw-r--r--examples/widgets/tutorials/notepad/notepad.pro2
-rw-r--r--mkspecs/features/mac/default_pre.prf7
-rw-r--r--mkspecs/features/qt_module.prf2
-rw-r--r--mkspecs/win32-g++/qmake.conf8
-rw-r--r--mkspecs/win32-icc/qmake.conf3
-rw-r--r--src/3rdparty/libjpeg/qt_attribution.json2
-rw-r--r--src/3rdparty/libjpeg/src/ChangeLog.md44
-rw-r--r--src/3rdparty/libjpeg/src/jcdctmgr.c2
-rw-r--r--src/3rdparty/libjpeg/src/jdapistd.c33
-rw-r--r--src/3rdparty/libjpeg/src/jdcolor.c2
-rw-r--r--src/3rdparty/libjpeg/src/jdmerge.c2
-rw-r--r--src/3rdparty/pcre2/pcre2.pro2
-rw-r--r--src/concurrent/concurrent.pro2
-rw-r--r--src/corelib/corelib.pro2
-rw-r--r--src/corelib/global/qrandom.cpp2
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp5
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp23
-rw-r--r--src/corelib/kernel/qeventdispatcher_win_p.h1
-rw-r--r--src/corelib/tools/qstring.cpp27
-rw-r--r--src/gui/image/qmovie.cpp8
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp3
-rw-r--r--src/gui/painting/painting.pri2
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp2
-rw-r--r--src/network/access/qhttpnetworkheader.cpp5
-rw-r--r--src/network/access/qhttpnetworkheader_p.h1
-rw-r--r--src/network/access/qhttpnetworkrequest.cpp5
-rw-r--r--src/network/access/qhttpnetworkrequest_p.h1
-rw-r--r--src/network/configure.json11
-rw-r--r--src/network/network.pro2
-rw-r--r--src/opengl/opengl.pro2
-rw-r--r--src/plugins/platforms/cocoa/qcocoansmenu.mm15
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm24
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h3
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm48
-rw-r--r--src/plugins/platforms/ios/qioswindow.h4
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm13
-rw-r--r--src/plugins/platforms/ios/quiview.mm35
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h1
-rw-r--r--src/sql/sql.pro2
-rw-r--r--src/widgets/graphicsview/qgraphicsview.cpp6
-rw-r--r--src/widgets/kernel/qapplication.cpp2
-rw-r--r--src/widgets/widgets.pro2
-rw-r--r--src/xml/xml.pro2
-rw-r--r--tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp64
-rw-r--r--tests/auto/gui/image/qmovie/tst_qmovie.cpp10
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp76
-rw-r--r--tests/manual/touchGraphicsItem/main.cpp163
-rw-r--r--tests/manual/touchGraphicsItem/touchGraphicsItem.pro5
52 files changed, 611 insertions, 101 deletions
diff --git a/examples/gui/rasterwindow/rasterwindow.cpp b/examples/gui/rasterwindow/rasterwindow.cpp
index 68d1d7f524..3eacd20145 100644
--- a/examples/gui/rasterwindow/rasterwindow.cpp
+++ b/examples/gui/rasterwindow/rasterwindow.cpp
@@ -111,6 +111,7 @@ void RasterWindow::renderNow()
painter.fillRect(0, 0, width(), height(), Qt::white);
render(&painter);
+ painter.end();
m_backingStore->endPaint();
m_backingStore->flush(rect);
diff --git a/examples/widgets/tutorials/notepad/notepad.cpp b/examples/widgets/tutorials/notepad/notepad.cpp
index b4f6cf7f8f..44d8597cb7 100644
--- a/examples/widgets/tutorials/notepad/notepad.cpp
+++ b/examples/widgets/tutorials/notepad/notepad.cpp
@@ -52,8 +52,15 @@
#include <QFileDialog>
#include <QTextStream>
#include <QMessageBox>
+#if defined(QT_PRINTSUPPORT_LIB)
+#include <QtPrintSupport/qtprintsupportglobal.h>
+#if QT_CONFIG(printer)
+#if QT_CONFIG(printdialog)
#include <QPrintDialog>
+#endif // QT_CONFIG(printdialog)
#include <QPrinter>
+#endif // QT_CONFIG(printer)
+#endif // QT_PRINTSUPPORT_LIB
#include <QFont>
#include <QFontDialog>
@@ -136,11 +143,15 @@ void Notepad::on_actionSave_as_triggered()
void Notepad::on_actionPrint_triggered()
{
+#if QT_CONFIG(printer)
QPrinter printDev;
+#if QT_CONFIG(printdialog)
QPrintDialog dialog(&printDev, this);
if (dialog.exec() == QDialog::Rejected)
return;
+#endif // QT_CONFIG(printdialog)
ui->textEdit->print(&printDev);
+#endif // QT_CONFIG(printer)
}
void Notepad::on_actionExit_triggered()
diff --git a/examples/widgets/tutorials/notepad/notepad.pro b/examples/widgets/tutorials/notepad/notepad.pro
index a552dacf00..6451f22735 100644
--- a/examples/widgets/tutorials/notepad/notepad.pro
+++ b/examples/widgets/tutorials/notepad/notepad.pro
@@ -1,7 +1,7 @@
TEMPLATE = app
TARGET = notepad
-QT += printsupport
+qtHaveModule(printsupport): QT += printsupport
requires(qtConfig(fontdialog))
SOURCES += \
diff --git a/mkspecs/features/mac/default_pre.prf b/mkspecs/features/mac/default_pre.prf
index e3534561a5..f1a4ca77b2 100644
--- a/mkspecs/features/mac/default_pre.prf
+++ b/mkspecs/features/mac/default_pre.prf
@@ -58,3 +58,10 @@ QMAKE_XCODE_LIBRARY_SUFFIX_SETTING = QT_LIBRARY_SUFFIX
xcode_copy_phase_strip_setting.name = COPY_PHASE_STRIP
xcode_copy_phase_strip_setting.value = NO
QMAKE_MAC_XCODE_SETTINGS += xcode_copy_phase_strip_setting
+
+xcode_product_bundle_identifier_setting.name = PRODUCT_BUNDLE_IDENTIFIER
+xcode_product_bundle_identifier_setting.value = $$QMAKE_TARGET_BUNDLE_PREFIX
+isEmpty(xcode_product_bundle_identifier_setting.value): \
+ xcode_product_bundle_identifier_setting.value = "com.yourcompany"
+xcode_product_bundle_identifier_setting.value = "$${xcode_product_bundle_identifier_setting.value}.${PRODUCT_NAME:rfc1034identifier}"
+QMAKE_MAC_XCODE_SETTINGS += xcode_product_bundle_identifier_setting
diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf
index c0a8dcc251..e6a0d97f1a 100644
--- a/mkspecs/features/qt_module.prf
+++ b/mkspecs/features/qt_module.prf
@@ -274,7 +274,7 @@ load(qt_targets)
else: \
QMAKE_PKGCONFIG_LIBDIR = $$[QT_INSTALL_LIBS/raw]
QMAKE_PKGCONFIG_INCDIR = $$[QT_INSTALL_HEADERS/raw]
- QMAKE_PKGCONFIG_CFLAGS = -I${includedir}/$$MODULE_INCNAME
+ QMAKE_PKGCONFIG_CFLAGS = -D$$MODULE_DEFINE -I${includedir}/$$MODULE_INCNAME
QMAKE_PKGCONFIG_NAME = $$replace(TARGET, ^Qt, "Qt$$QT_MAJOR_VERSION ")
QMAKE_PKGCONFIG_FILE = $$replace(TARGET, ^Qt, Qt$$QT_MAJOR_VERSION)
for(i, MODULE_DEPENDS): \
diff --git a/mkspecs/win32-g++/qmake.conf b/mkspecs/win32-g++/qmake.conf
index 12f3567754..9f366e08b8 100644
--- a/mkspecs/win32-g++/qmake.conf
+++ b/mkspecs/win32-g++/qmake.conf
@@ -10,6 +10,8 @@
load(device_config)
include(../common/gcc-base.conf)
include(../common/g++-base.conf)
+include(../common/angle.conf)
+include(../common/windows-vulkan.conf)
# modifications to gcc-base.conf and g++-base.conf
@@ -31,8 +33,6 @@ QMAKE_CFLAGS += -fno-keep-inline-dllexport
QMAKE_CFLAGS_WARN_ON += -Wextra
QMAKE_CFLAGS_SSE2 += -mstackrealign
-QMAKE_CFLAGS_AESNI = -maes
-QMAKE_CFLAGS_SHANI = -msha
QMAKE_CXX = $${CROSS_COMPILE}g++
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
@@ -86,8 +86,4 @@ QMAKE_STRIPFLAGS_LIB += --strip-unneeded
QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy
QMAKE_NM = $${CROSS_COMPILE}nm -P
-include(../common/angle.conf)
-include(../common/windows-vulkan.conf)
-include(../common/gcc-base.conf)
-
load(qt_config)
diff --git a/mkspecs/win32-icc/qmake.conf b/mkspecs/win32-icc/qmake.conf
index cc9c6e7363..6acb07f8aa 100644
--- a/mkspecs/win32-icc/qmake.conf
+++ b/mkspecs/win32-icc/qmake.conf
@@ -58,7 +58,4 @@ QMAKE_LFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG
QMAKE_LIB = xilib /NOLOGO
-include(../common/angle.conf)
-include(../common/windows-vulkan.conf)
-
load(qt_config)
diff --git a/src/3rdparty/libjpeg/qt_attribution.json b/src/3rdparty/libjpeg/qt_attribution.json
index a1966d43d6..9bfc14f29d 100644
--- a/src/3rdparty/libjpeg/qt_attribution.json
+++ b/src/3rdparty/libjpeg/qt_attribution.json
@@ -6,7 +6,7 @@
"Description": "The Independent JPEG Group's JPEG software",
"Homepage": "http://libjpeg-turbo.virtualgl.org/",
- "Version": "1.5.2",
+ "Version": "1.5.3",
"License": "Independent JPEG Group License",
"LicenseId": "IJG",
"LicenseFile": "LICENSE",
diff --git a/src/3rdparty/libjpeg/src/ChangeLog.md b/src/3rdparty/libjpeg/src/ChangeLog.md
index 2aaa50c148..f5fe44bf85 100644
--- a/src/3rdparty/libjpeg/src/ChangeLog.md
+++ b/src/3rdparty/libjpeg/src/ChangeLog.md
@@ -1,3 +1,47 @@
+1.5.3
+=====
+
+### Significant changes relative to 1.5.2:
+
+1. Fixed a NullPointerException in the TurboJPEG Java wrapper that occurred
+when using the YUVImage constructor that creates an instance backed by separate
+image planes and allocates memory for the image planes.
+
+2. Fixed an issue whereby the Java version of TJUnitTest would fail when
+testing BufferedImage encoding/decoding on big endian systems.
+
+3. Fixed a segfault in djpeg that would occur if an output format other than
+PPM/PGM was selected along with the `-crop` option. The `-crop` option now
+works with the GIF and Targa formats as well (unfortunately, it cannot be made
+to work with the BMP and RLE formats due to the fact that those output engines
+write scanlines in bottom-up order.) djpeg will now exit gracefully if an
+output format other than PPM/PGM, GIF, or Targa is selected along with the
+`-crop` option.
+
+4. Fixed an issue whereby `jpeg_skip_scanlines()` would segfault if color
+quantization was enabled.
+
+5. TJBench (both C and Java versions) will now display usage information if any
+command-line argument is unrecognized. This prevents the program from silently
+ignoring typos.
+
+6. Fixed an access violation in tjbench.exe (Windows) that occurred when the
+program was used to decompress an existing JPEG image.
+
+7. Fixed an ArrayIndexOutOfBoundsException in the TJExample Java program that
+occurred when attempting to decompress a JPEG image that had been compressed
+with 4:1:1 chrominance subsampling.
+
+8. Fixed an issue whereby, when using `jpeg_skip_scanlines()` to skip to the
+end of a single-scan (non-progressive) image, subsequent calls to
+`jpeg_consume_input()` would return `JPEG_SUSPENDED` rather than
+`JPEG_REACHED_EOI`.
+
+9. `jpeg_crop_scanlines()` now works correctly when decompressing grayscale
+JPEG images that were compressed with a sampling factor other than 1 (for
+instance, with `cjpeg -grayscale -sample 2x2`).
+
+
1.5.2
=====
diff --git a/src/3rdparty/libjpeg/src/jcdctmgr.c b/src/3rdparty/libjpeg/src/jcdctmgr.c
index aef8517f9c..6e3b19bcb3 100644
--- a/src/3rdparty/libjpeg/src/jcdctmgr.c
+++ b/src/3rdparty/libjpeg/src/jcdctmgr.c
@@ -216,7 +216,7 @@ compute_reciprocal (UINT16 divisor, DCTELEM *dtbl)
#endif
dtbl[DCTSIZE2 * 3] = (DCTELEM) r - sizeof(DCTELEM)*8; /* shift */
- if(r <= 16) return 0;
+ if (r <= 16) return 0;
else return 1;
}
diff --git a/src/3rdparty/libjpeg/src/jdapistd.c b/src/3rdparty/libjpeg/src/jdapistd.c
index 37afc8448b..105121df2b 100644
--- a/src/3rdparty/libjpeg/src/jdapistd.c
+++ b/src/3rdparty/libjpeg/src/jdapistd.c
@@ -4,7 +4,7 @@
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1994-1996, Thomas G. Lane.
* libjpeg-turbo Modifications:
- * Copyright (C) 2010, 2015-2016, D. R. Commander.
+ * Copyright (C) 2010, 2015-2017, D. R. Commander.
* Copyright (C) 2015, Google, Inc.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
@@ -190,7 +190,10 @@ jpeg_crop_scanline (j_decompress_ptr cinfo, JDIMENSION *xoffset,
* single-pass decompression case, allowing us to use the same MCU column
* width for all of the components.
*/
- align = cinfo->_min_DCT_scaled_size * cinfo->max_h_samp_factor;
+ if (cinfo->comps_in_scan == 1 && cinfo->num_components == 1)
+ align = cinfo->_min_DCT_scaled_size;
+ else
+ align = cinfo->_min_DCT_scaled_size * cinfo->max_h_samp_factor;
/* Adjust xoffset to the nearest iMCU boundary <= the requested value */
input_xoffset = *xoffset;
@@ -215,6 +218,9 @@ jpeg_crop_scanline (j_decompress_ptr cinfo, JDIMENSION *xoffset,
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
+ int hsf = (cinfo->comps_in_scan == 1 && cinfo->num_components == 1) ?
+ 1 : compptr->h_samp_factor;
+
/* Set downsampled_width to the new output width. */
orig_downsampled_width = compptr->downsampled_width;
compptr->downsampled_width =
@@ -228,11 +234,10 @@ jpeg_crop_scanline (j_decompress_ptr cinfo, JDIMENSION *xoffset,
* values will be used in multi-scan decompressions.
*/
cinfo->master->first_MCU_col[ci] =
- (JDIMENSION) (long) (*xoffset * compptr->h_samp_factor) /
- (long) align;
+ (JDIMENSION) (long) (*xoffset * hsf) / (long) align;
cinfo->master->last_MCU_col[ci] =
(JDIMENSION) jdiv_round_up((long) ((*xoffset + cinfo->output_width) *
- compptr->h_samp_factor),
+ hsf),
(long) align) - 1;
}
@@ -293,6 +298,14 @@ noop_convert (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
}
+/* Dummy quantize function used by jpeg_skip_scanlines() */
+LOCAL(void)
+noop_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+ JSAMPARRAY output_buf, int num_rows)
+{
+}
+
+
/*
* In some cases, it is best to call jpeg_read_scanlines() and discard the
* output, rather than skipping the scanlines, because this allows us to
@@ -308,14 +321,22 @@ read_and_discard_scanlines (j_decompress_ptr cinfo, JDIMENSION num_lines)
void (*color_convert) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
JDIMENSION input_row, JSAMPARRAY output_buf,
int num_rows);
+ void (*color_quantize) (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+ JSAMPARRAY output_buf, int num_rows) = NULL;
color_convert = cinfo->cconvert->color_convert;
cinfo->cconvert->color_convert = noop_convert;
+ if (cinfo->cquantize && cinfo->cquantize->color_quantize) {
+ color_quantize = cinfo->cquantize->color_quantize;
+ cinfo->cquantize->color_quantize = noop_quantize;
+ }
for (n = 0; n < num_lines; n++)
jpeg_read_scanlines(cinfo, NULL, 1);
cinfo->cconvert->color_convert = color_convert;
+ if (color_quantize)
+ cinfo->cquantize->color_quantize = color_quantize;
}
@@ -370,6 +391,8 @@ jpeg_skip_scanlines (j_decompress_ptr cinfo, JDIMENSION num_lines)
/* Do not skip past the bottom of the image. */
if (cinfo->output_scanline + num_lines >= cinfo->output_height) {
cinfo->output_scanline = cinfo->output_height;
+ (*cinfo->inputctl->finish_input_pass) (cinfo);
+ cinfo->inputctl->eoi_reached = TRUE;
return cinfo->output_height - cinfo->output_scanline;
}
diff --git a/src/3rdparty/libjpeg/src/jdcolor.c b/src/3rdparty/libjpeg/src/jdcolor.c
index ab8fa24925..05cbf4df1f 100644
--- a/src/3rdparty/libjpeg/src/jdcolor.c
+++ b/src/3rdparty/libjpeg/src/jdcolor.c
@@ -616,7 +616,7 @@ static const JLONG dither_matrix[4] = {
static INLINE boolean is_big_endian(void)
{
int test_value = 1;
- if(*(char *)&test_value != 1)
+ if (*(char *)&test_value != 1)
return TRUE;
return FALSE;
}
diff --git a/src/3rdparty/libjpeg/src/jdmerge.c b/src/3rdparty/libjpeg/src/jdmerge.c
index 6276dd0950..ca6f16c252 100644
--- a/src/3rdparty/libjpeg/src/jdmerge.c
+++ b/src/3rdparty/libjpeg/src/jdmerge.c
@@ -503,7 +503,7 @@ static const JLONG dither_matrix[4] = {
static INLINE boolean is_big_endian(void)
{
int test_value = 1;
- if(*(char *)&test_value != 1)
+ if (*(char *)&test_value != 1)
return TRUE;
return FALSE;
}
diff --git a/src/3rdparty/pcre2/pcre2.pro b/src/3rdparty/pcre2/pcre2.pro
index 3dde2f62f8..296e65cd59 100644
--- a/src/3rdparty/pcre2/pcre2.pro
+++ b/src/3rdparty/pcre2/pcre2.pro
@@ -16,6 +16,8 @@ DEFINES += HAVE_CONFIG_H
# platform/compiler specific definitions
uikit|qnx|winrt: DEFINES += PCRE2_DISABLE_JIT
+win32:contains(QT_ARCH, "arm"): DEFINES += PCRE2_DISABLE_JIT
+win32:contains(QT_ARCH, "arm64"): DEFINES += PCRE2_DISABLE_JIT
SOURCES += \
$$PWD/src/pcre2_auto_possess.c \
diff --git a/src/concurrent/concurrent.pro b/src/concurrent/concurrent.pro
index 017153c74d..18510e38a1 100644
--- a/src/concurrent/concurrent.pro
+++ b/src/concurrent/concurrent.pro
@@ -4,7 +4,7 @@ CONFIG += exceptions
DEFINES += QT_NO_USING_NAMESPACE QT_NO_FOREACH
-win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x66000000
+msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x66000000
QMAKE_DOCS = $$PWD/doc/qtconcurrent.qdocconf
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro
index 2079d2117f..3db2e2ceb8 100644
--- a/src/corelib/corelib.pro
+++ b/src/corelib/corelib.pro
@@ -12,7 +12,7 @@ CONFIG += qt_tracepoints
CONFIG += $$MODULE_CONFIG
DEFINES += $$MODULE_DEFINES
DEFINES += QT_NO_USING_NAMESPACE QT_NO_FOREACH
-win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x67000000
+msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x67000000
CONFIG += simd optimize_full
diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp
index 6c26d4682d..9143e04d45 100644
--- a/src/corelib/global/qrandom.cpp
+++ b/src/corelib/global/qrandom.cpp
@@ -74,7 +74,7 @@ DECLSPEC_IMPORT BOOLEAN WINAPI SystemFunction036(PVOID RandomBuffer, ULONG Rando
}
#endif
-#if defined(Q_OS_ANDROID)
+#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
# include <private/qjni_p.h>
#endif
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index 7dd4f6556d..bc39ea73ee 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -185,10 +185,11 @@ bool QFSFileEnginePrivate::nativeFlush()
bool QFSFileEnginePrivate::nativeSyncToDisk()
{
Q_Q(QFSFileEngine);
+ int ret;
#if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
- const int ret = fdatasync(nativeHandle());
+ EINTR_LOOP(ret, fdatasync(nativeHandle()));
#else
- const int ret = fsync(nativeHandle());
+ EINTR_LOOP(ret, fsync(nativeHandle()));
#endif
if (ret != 0)
q->setError(QFile::WriteError, qt_error_string(errno));
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index bbd442d570..330870f219 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -905,6 +905,7 @@ bool QEventDispatcherWin32::registerEventNotifier(QWinEventNotifier *notifier)
return true;
d->winEventNotifierList.append(notifier);
+ d->winEventNotifierListModified = true;
if (!d->winEventNotifierActivatedEvent)
d->winEventNotifierActivatedEvent = CreateEvent(0, TRUE, FALSE, nullptr);
@@ -928,6 +929,7 @@ void QEventDispatcherWin32::unregisterEventNotifier(QWinEventNotifier *notifier)
if (i == -1)
return;
d->winEventNotifierList.takeAt(i);
+ d->winEventNotifierListModified = true;
QWinEventNotifierPrivate *nd = QWinEventNotifierPrivate::get(notifier);
if (nd->waitHandle)
nd->unregisterWaitObject();
@@ -938,16 +940,19 @@ void QEventDispatcherWin32::activateEventNotifiers()
Q_D(QEventDispatcherWin32);
ResetEvent(d->winEventNotifierActivatedEvent);
- // Iterate backwards, because the notifier might remove itself on activate().
- for (int i = d->winEventNotifierList.count(); --i >= 0;) {
- QWinEventNotifier *notifier = d->winEventNotifierList.at(i);
- QWinEventNotifierPrivate *nd = QWinEventNotifierPrivate::get(notifier);
- if (nd->signaledCount.load() != 0) {
- --nd->signaledCount;
- nd->unregisterWaitObject();
- d->activateEventNotifier(notifier);
+ // Activate signaled notifiers. Our winEventNotifierList can be modified in activation slots.
+ do {
+ d->winEventNotifierListModified = false;
+ for (int i = 0; i < d->winEventNotifierList.count(); ++i) {
+ QWinEventNotifier *notifier = d->winEventNotifierList.at(i);
+ QWinEventNotifierPrivate *nd = QWinEventNotifierPrivate::get(notifier);
+ if (nd->signaledCount.load() != 0) {
+ --nd->signaledCount;
+ nd->unregisterWaitObject();
+ d->activateEventNotifier(notifier);
+ }
}
- }
+ } while (d->winEventNotifierListModified);
// Re-register the remaining activated notifiers.
for (int i = 0; i < d->winEventNotifierList.count(); ++i) {
diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h
index 683c7f8f36..a7ed8dda8a 100644
--- a/src/corelib/kernel/qeventdispatcher_win_p.h
+++ b/src/corelib/kernel/qeventdispatcher_win_p.h
@@ -195,6 +195,7 @@ public:
HANDLE winEventNotifierActivatedEvent;
QList<QWinEventNotifier *> winEventNotifierList;
+ bool winEventNotifierListModified = false;
void activateEventNotifier(QWinEventNotifier * wen);
QList<MSG> queuedUserInputEvents;
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 25f829c38c..08fe9b899d 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -6887,6 +6887,8 @@ QString QString::vasprintf(const char *cformat, va_list ap)
\snippet qstring/main.cpp 74
+ This function ignores leading and trailing whitespace.
+
\sa number(), toULongLong(), toInt(), QLocale::toLongLong()
*/
@@ -6927,6 +6929,8 @@ qlonglong QString::toIntegral_helper(const QChar *data, int len, bool *ok, int b
\snippet qstring/main.cpp 79
+ This function ignores leading and trailing whitespace.
+
\sa number(), toLongLong(), QLocale::toULongLong()
*/
@@ -6969,6 +6973,8 @@ qulonglong QString::toIntegral_helper(const QChar *data, uint len, bool *ok, int
\snippet qstring/main.cpp 73
+ This function ignores leading and trailing whitespace.
+
\sa number(), toULong(), toInt(), QLocale::toInt()
*/
@@ -6998,6 +7004,8 @@ long QString::toLong(bool *ok, int base) const
\snippet qstring/main.cpp 78
+ This function ignores leading and trailing whitespace.
+
\sa number(), QLocale::toUInt()
*/
@@ -7026,6 +7034,8 @@ ulong QString::toULong(bool *ok, int base) const
\snippet qstring/main.cpp 72
+ This function ignores leading and trailing whitespace.
+
\sa number(), toUInt(), toDouble(), QLocale::toInt()
*/
@@ -7053,6 +7063,8 @@ int QString::toInt(bool *ok, int base) const
\snippet qstring/main.cpp 77
+ This function ignores leading and trailing whitespace.
+
\sa number(), toInt(), QLocale::toUInt()
*/
@@ -7080,6 +7092,8 @@ uint QString::toUInt(bool *ok, int base) const
\snippet qstring/main.cpp 76
+ This function ignores leading and trailing whitespace.
+
\sa number(), toUShort(), toInt(), QLocale::toShort()
*/
@@ -7107,6 +7121,8 @@ short QString::toShort(bool *ok, int base) const
\snippet qstring/main.cpp 80
+ This function ignores leading and trailing whitespace.
+
\sa number(), toShort(), QLocale::toUShort()
*/
@@ -7126,7 +7142,10 @@ ushort QString::toUShort(bool *ok, int base) const
\snippet qstring/main.cpp 66
- \warning The QString content may only contain valid numerical characters which includes the plus/minus sign, the characters g and e used in scientific notation, and the decimal point. Including the unit or additional characters leads to a conversion error.
+ \warning The QString content may only contain valid numerical characters
+ which includes the plus/minus sign, the characters g and e used in scientific
+ notation, and the decimal point. Including the unit or additional characters
+ leads to a conversion error.
\snippet qstring/main.cpp 67
@@ -7141,6 +7160,8 @@ ushort QString::toUShort(bool *ok, int base) const
\snippet qstring/main.cpp 69
+ This function ignores leading and trailing whitespace.
+
\sa number(), QLocale::setDefault(), QLocale::toDouble(), trimmed()
*/
@@ -7155,6 +7176,8 @@ double QString::toDouble(bool *ok) const
If a conversion error occurs, *\a{ok} is set to \c false; otherwise
*\a{ok} is set to \c true. Returns 0.0 if the conversion fails.
+ This function ignores leading and trailing whitespace.
+
The string conversion will always happen in the 'C' locale. For locale
dependent conversion use QLocale::toFloat()
@@ -7162,6 +7185,8 @@ double QString::toDouble(bool *ok) const
\snippet qstring/main.cpp 71
+ This function ignores leading and trailing whitespace.
+
\sa number(), toDouble(), toInt(), QLocale::toFloat()
*/
diff --git a/src/gui/image/qmovie.cpp b/src/gui/image/qmovie.cpp
index d5e8b1b974..010760de4c 100644
--- a/src/gui/image/qmovie.cpp
+++ b/src/gui/image/qmovie.cpp
@@ -470,6 +470,10 @@ bool QMoviePrivate::next()
currentPixmap = QPixmap::fromImage( info.pixmap.toImage().scaled(scaledSize) );
else
currentPixmap = info.pixmap;
+
+ if (!speed)
+ return true;
+
nextDelay = speedAdjustedDelay(info.delay);
// Adjust delay according to the time it took to read the frame
int processingTime = time.elapsed();
@@ -504,7 +508,7 @@ void QMoviePrivate::_q_loadNextFrame(bool starting)
emit q->updated(frameRect);
emit q->frameChanged(currentFrameNumber);
- if (movieState == QMovie::Running)
+ if (speed && movieState == QMovie::Running)
nextImageTimer.start(nextDelay);
} else {
// Could not read another frame
@@ -926,6 +930,8 @@ void QMovie::setPaused(bool paused)
void QMovie::setSpeed(int percentSpeed)
{
Q_D(QMovie);
+ if (!d->speed && d->movieState == Running)
+ d->nextImageTimer.start(nextFrameDelay());
d->speed = percentSpeed;
}
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 35a9ede227..318a280a40 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -283,9 +283,10 @@ QT_DEFINE_QPA_EVENT_HANDLER(void, handleApplicationStateChanged, Qt::Application
QWindowSystemInterfacePrivate::GeometryChangeEvent::GeometryChangeEvent(QWindow *window, const QRect &newGeometry)
: WindowSystemEvent(GeometryChange)
, window(window)
- , requestedGeometry(window->handle() ? window->handle()->QPlatformWindow::geometry() : QRect())
, newGeometry(newGeometry)
{
+ if (const QPlatformWindow *pw = window->handle())
+ requestedGeometry = QHighDpi::fromNativePixels(pw->QPlatformWindow::geometry(), window);
}
QT_DEFINE_QPA_EVENT_HANDLER(void, handleGeometryChange, QWindow *window, const QRect &newRect)
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 1e14498f79..29bef14f0c 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -127,7 +127,7 @@ AVX2_SOURCES += painting/qdrawhelper_avx2.cpp
NEON_SOURCES += painting/qdrawhelper_neon.cpp painting/qimagescale_neon.cpp
NEON_HEADERS += painting/qdrawhelper_neon_p.h
NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S
-!uikit:contains(QT_ARCH, "arm"): CONFIG += no_clang_integrated_as
+!uikit:!win32:contains(QT_ARCH, "arm"): CONFIG += no_clang_integrated_as
!uikit:!win32:!contains(QT_ARCH, "arm64"): DEFINES += ENABLE_PIXMAN_DRAWHELPERS
MIPS_DSP_SOURCES += painting/qdrawhelper_mips_dsp.cpp
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index 517af326a8..0e2c257952 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -354,7 +354,7 @@ void QHttpNetworkConnectionPrivate::prepareRequest(HttpMessagePair &messagePair)
host += QByteArray::number(port);
}
- request.setHeaderField("Host", host);
+ request.prependHeaderField("Host", host);
}
reply->d_func()->requestIsPrepared = true;
diff --git a/src/network/access/qhttpnetworkheader.cpp b/src/network/access/qhttpnetworkheader.cpp
index 19a3dfcfe8..3326f89d2f 100644
--- a/src/network/access/qhttpnetworkheader.cpp
+++ b/src/network/access/qhttpnetworkheader.cpp
@@ -112,6 +112,11 @@ void QHttpNetworkHeaderPrivate::setHeaderField(const QByteArray &name, const QBy
fields.append(qMakePair(name, data));
}
+void QHttpNetworkHeaderPrivate::prependHeaderField(const QByteArray &name, const QByteArray &data)
+{
+ fields.prepend(qMakePair(name, data));
+}
+
bool QHttpNetworkHeaderPrivate::operator==(const QHttpNetworkHeaderPrivate &other) const
{
return (url == other.url);
diff --git a/src/network/access/qhttpnetworkheader_p.h b/src/network/access/qhttpnetworkheader_p.h
index f46c259919..3adb0ed7f1 100644
--- a/src/network/access/qhttpnetworkheader_p.h
+++ b/src/network/access/qhttpnetworkheader_p.h
@@ -92,6 +92,7 @@ public:
QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const;
QList<QByteArray> headerFieldValues(const QByteArray &name) const;
void setHeaderField(const QByteArray &name, const QByteArray &data);
+ void prependHeaderField(const QByteArray &name, const QByteArray &data);
bool operator==(const QHttpNetworkHeaderPrivate &other) const;
};
diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp
index 3fcf946945..cf4be3df95 100644
--- a/src/network/access/qhttpnetworkrequest.cpp
+++ b/src/network/access/qhttpnetworkrequest.cpp
@@ -279,6 +279,11 @@ void QHttpNetworkRequest::setHeaderField(const QByteArray &name, const QByteArra
d->setHeaderField(name, data);
}
+void QHttpNetworkRequest::prependHeaderField(const QByteArray &name, const QByteArray &data)
+{
+ d->prependHeaderField(name, data);
+}
+
QHttpNetworkRequest &QHttpNetworkRequest::operator=(const QHttpNetworkRequest &other)
{
d = other.d;
diff --git a/src/network/access/qhttpnetworkrequest_p.h b/src/network/access/qhttpnetworkrequest_p.h
index 2cbb8e255e..bc797537ae 100644
--- a/src/network/access/qhttpnetworkrequest_p.h
+++ b/src/network/access/qhttpnetworkrequest_p.h
@@ -102,6 +102,7 @@ public:
QList<QPair<QByteArray, QByteArray> > header() const override;
QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const override;
void setHeaderField(const QByteArray &name, const QByteArray &data) override;
+ void prependHeaderField(const QByteArray &name, const QByteArray &data);
Operation operation() const;
void setOperation(Operation operation);
diff --git a/src/network/configure.json b/src/network/configure.json
index 94a23bbc78..89bb1efffa 100644
--- a/src/network/configure.json
+++ b/src/network/configure.json
@@ -141,10 +141,10 @@
"use": "network"
},
"openssl11": {
- "label": "OpenSSL v. 1.1 support",
+ "label": "OpenSSL 1.1 support",
"type": "compile",
"test": "unix/openssl11",
- "use": "network"
+ "use": "openssl"
}
},
@@ -213,9 +213,9 @@
"output": [ "publicFeature", "feature" ]
},
"opensslv11": {
- "label": "OpenSSL v. 1.1",
- "condition": "tests.openssl11",
- "output": ["publicFeature", "feature"]
+ "label": "OpenSSL 1.1",
+ "condition": "features.openssl && tests.openssl11",
+ "output": [ "publicFeature" ]
},
"sctp": {
"label": "SCTP",
@@ -341,6 +341,7 @@ For example:
},
"openssl",
"openssl-linked",
+ "opensslv11",
"sctp",
"system-proxies"
]
diff --git a/src/network/network.pro b/src/network/network.pro
index b8272d91d6..9082439f1c 100644
--- a/src/network/network.pro
+++ b/src/network/network.pro
@@ -10,7 +10,7 @@ DEFINES += QT_NO_USING_NAMESPACE QT_NO_FOREACH
#DEFINES += QTCPSOCKETENGINE_DEBUG QTCPSOCKET_DEBUG QTCPSERVER_DEBUG QSSLSOCKET_DEBUG
#DEFINES += QUDPSOCKET_DEBUG QUDPSERVER_DEBUG
#DEFINES += QSCTPSOCKET_DEBUG QSCTPSERVER_DEBUG
-win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x64000000
+msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x64000000
QMAKE_DOCS = $$PWD/doc/qtnetwork.qdocconf
diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro
index 077b190d3e..8b2349ff2f 100644
--- a/src/opengl/opengl.pro
+++ b/src/opengl/opengl.pro
@@ -3,7 +3,7 @@ QT = core-private gui-private widgets-private
DEFINES += QT_NO_USING_NAMESPACE QT_NO_FOREACH
-win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x63000000
+msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x63000000
solaris-cc*:QMAKE_CXXFLAGS_RELEASE -= -O2
QMAKE_DOCS = $$PWD/doc/qtopengl.qdocconf
diff --git a/src/plugins/platforms/cocoa/qcocoansmenu.mm b/src/plugins/platforms/cocoa/qcocoansmenu.mm
index 996a4ff194..6be2569dbc 100644
--- a/src/plugins/platforms/cocoa/qcocoansmenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoansmenu.mm
@@ -40,6 +40,8 @@
#import "qcocoansmenu.h"
#include "qcocoamenu.h"
#include "qcocoamenuitem.h"
+#include "qcocoamenubar.h"
+#include "qcocoawindow.h"
#import "qnsview.h"
#include <QtCore/qmetaobject.h>
@@ -291,6 +293,19 @@ static NSString *qt_mac_removePrivateUnicode(NSString* string)
return nil;
}
+// Cocoa will query the menu item's target for the worksWhenModal selector.
+// So we need to implement this to allow the items to be handled correctly
+// when a modal dialog is visible.
+- (BOOL)worksWhenModal
+{
+ if (!QGuiApplication::modalWindow())
+ return YES;
+ const auto &qpaMenu = static_cast<QCocoaNSMenu *>(self).qpaMenu;
+ if (auto *mb = qobject_cast<QCocoaMenuBar *>(qpaMenu->menuParent()))
+ return QGuiApplication::modalWindow()->handle() == mb->cocoaWindow() ? YES : NO;
+ return YES;
+}
+
@end
#undef CHECK_MENU_CLASS
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 562872a300..ca580e7d17 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -503,9 +503,10 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags)
{
const Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
const bool frameless = (flags & Qt::FramelessWindowHint) || windowIsPopupType(type);
+ const bool resizeable = type != Qt::Dialog; // Dialogs: remove zoom button by disabling resize
- // Select base window type.
- NSUInteger styleMask = frameless ? NSBorderlessWindowMask : NSResizableWindowMask;
+ // Select base window type. Note that the value of NSBorderlessWindowMask is 0.
+ NSUInteger styleMask = (frameless || !resizeable) ? NSBorderlessWindowMask : NSResizableWindowMask;
if (frameless) {
// No further customizations for frameless since there are no window decorations.
@@ -1156,23 +1157,6 @@ void QCocoaWindow::handleExposeEvent(const QRegion &region)
m_exposedRect = QRect();
}
- QWindowPrivate *windowPrivate = qt_window_private(window());
- if (windowPrivate->updateRequestPending) {
- // We can only deliver update request events when the window is exposed,
- // and we also have to make sure we deliver any change to the exposed
- // rect as a real expose event (including going from non-exposed to
- // exposed). FIXME: Should this logic live in QGuiApplication?
- if (isExposed() && m_exposedRect == previouslyExposedRect) {
- qCDebug(lcQpaCocoaDrawing) << "QCocoaWindow::handleExposeEvent" << window() << region << "as update request";
- windowPrivate->deliverUpdateRequest();
- return;
- } else {
- // Since updateRequestPending is still set, we will issue a deferred setNeedsDisplay
- // from drawRect and get back into this code on the next display cycle, delivering
- // the pending update request.
- }
- }
-
qCDebug(lcQpaCocoaDrawing) << "QCocoaWindow::handleExposeEvent" << window() << region << "isExposed" << isExposed();
QWindowSystemInterface::handleExposeEvent<QWindowSystemInterface::SynchronousDelivery>(window(), region);
}
@@ -1347,7 +1331,7 @@ void QCocoaWindow::recreateWindowIfNeeded()
void QCocoaWindow::requestUpdate()
{
qCDebug(lcQpaCocoaDrawing) << "QCocoaWindow::requestUpdate" << window();
- [m_view setNeedsDisplay:YES];
+ [m_view requestUpdate];
}
void QCocoaWindow::requestActivateWindow()
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index f8903725a6..e2ea862cd5 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -81,6 +81,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
NSEvent *m_currentlyInterpretedKeyEvent;
bool m_isMenuView;
QSet<quint32> m_acceptedKeyDowns;
+ bool m_updateRequested;
}
@property (nonatomic, retain) NSCursor *cursor;
@@ -105,6 +106,8 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
- (void)resetMouseButtons;
+- (void)requestUpdate;
+
- (void)handleMouseEvent:(NSEvent *)theEvent;
- (bool)handleMouseDownEvent:(NSEvent *)theEvent withButton:(int)buttonNumber;
- (bool)handleMouseDraggedEvent:(NSEvent *)theEvent withButton:(int)buttonNumber;
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 216b2f1287..ec1d126ab9 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -148,6 +148,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
m_isMenuView = false;
self.focusRingType = NSFocusRingTypeNone;
self.cursor = nil;
+ m_updateRequested = false;
}
return self;
}
@@ -300,6 +301,25 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
return m_platformWindow->isOpaque();
}
+- (void)requestUpdate
+{
+ if (self.needsDisplay) {
+ // If the view already has needsDisplay set it means that there may be code waiting for
+ // a real expose event, so we can't issue setNeedsDisplay now as a way to trigger an
+ // update request. We will re-trigger requestUpdate from drawRect.
+ return;
+ }
+
+ [self setNeedsDisplay:YES];
+ m_updateRequested = true;
+}
+
+- (void)setNeedsDisplayInRect:(NSRect)rect
+{
+ [super setNeedsDisplayInRect:rect];
+ m_updateRequested = false;
+}
+
- (void)drawRect:(NSRect)dirtyRect
{
Q_UNUSED(dirtyRect);
@@ -315,7 +335,11 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
exposedRegion += QRectF::fromCGRect(dirtyRects[i]).toRect();
qCDebug(lcQpaCocoaDrawing) << "[QNSView drawRect:]" << m_platformWindow->window() << exposedRegion;
+ [self updateRegion:exposedRegion];
+}
+- (void)updateRegion:(QRegion)dirtyRegion
+{
#ifndef QT_NO_OPENGL
if (m_glContext && m_shouldSetGLContextinDrawRect) {
[m_glContext->nsOpenGLContext() setView:self];
@@ -323,18 +347,24 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
}
#endif
- m_platformWindow->handleExposeEvent(exposedRegion);
+ QWindowPrivate *windowPrivate = qt_window_private(m_platformWindow->window());
+
+ if (m_updateRequested) {
+ Q_ASSERT(windowPrivate->updateRequestPending);
+ qCDebug(lcQpaCocoaWindow) << "Delivering update request to" << m_platformWindow->window();
+ windowPrivate->deliverUpdateRequest();
+ m_updateRequested = false;
+ } else {
+ m_platformWindow->handleExposeEvent(dirtyRegion);
+ }
- if (qt_window_private(m_platformWindow->window())->updateRequestPending) {
- // A call to QWindow::requestUpdate was issued during the expose event, or we
- // had to deliver a real expose event and still need to deliver the update.
- // But AppKit will reset the needsDisplay state of the view after completing
+ if (windowPrivate->updateRequestPending) {
+ // A call to QWindow::requestUpdate was issued during event delivery above,
+ // but AppKit will reset the needsDisplay state of the view after completing
// the current display cycle, so we need to defer the request to redisplay.
// FIXME: Perhaps this should be a trigger to enable CADisplayLink?
qCDebug(lcQpaCocoaDrawing) << "[QNSView drawRect:] issuing deferred setNeedsDisplay due to pending update request";
- dispatch_async(dispatch_get_main_queue (), ^{
- [self setNeedsDisplay:YES];
- });
+ dispatch_async(dispatch_get_main_queue (), ^{ [self requestUpdate]; });
}
}
@@ -351,7 +381,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
qCDebug(lcQpaCocoaDrawing) << "[QNSView updateLayer]" << m_platformWindow->window();
// FIXME: Find out if there's a way to resolve the dirty rect like in drawRect:
- m_platformWindow->handleExposeEvent(QRectF::fromCGRect(self.bounds).toRect());
+ [self updateRegion:QRectF::fromCGRect(self.bounds).toRect()];
}
- (void)viewDidChangeBackingProperties
diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h
index d5af31044d..2028fc2a42 100644
--- a/src/plugins/platforms/ios/qioswindow.h
+++ b/src/plugins/platforms/ios/qioswindow.h
@@ -110,6 +110,10 @@ private:
friend class QIOSScreen;
};
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug debug, const QIOSWindow *window);
+#endif
+
QT_END_NAMESPACE
#endif // QIOSWINDOW_H
diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm
index 38136c05db..6ee258e363 100644
--- a/src/plugins/platforms/ios/qioswindow.mm
+++ b/src/plugins/platforms/ios/qioswindow.mm
@@ -381,6 +381,19 @@ CAEAGLLayer *QIOSWindow::eaglLayer() const
return static_cast<CAEAGLLayer *>(m_view.layer);
}
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug debug, const QIOSWindow *window)
+{
+ QDebugStateSaver saver(debug);
+ debug.nospace();
+ debug << "QIOSWindow(" << (const void *)window;
+ if (window)
+ debug << ", window=" << window->window();
+ debug << ')';
+ return debug;
+}
+#endif // !QT_NO_DEBUG_STREAM
+
#include "moc_qioswindow.cpp"
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm
index 6960698bf1..584dfe9b41 100644
--- a/src/plugins/platforms/ios/quiview.mm
+++ b/src/plugins/platforms/ios/quiview.mm
@@ -149,6 +149,21 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
[super dealloc];
}
+- (NSString *)description
+{
+ NSMutableString *description = [NSMutableString stringWithString:[super description]];
+
+#ifndef QT_NO_DEBUG_STREAM
+ QString platformWindowDescription;
+ QDebug debug(&platformWindowDescription);
+ debug.nospace() << "; " << m_qioswindow << ">";
+ NSRange lastCharacter = [description rangeOfComposedCharacterSequenceAtIndex:description.length - 1];
+ [description replaceCharactersInRange:lastCharacter withString:platformWindowDescription.toNSString()];
+#endif
+
+ return description;
+}
+
- (void)willMoveToWindow:(UIWindow *)newWindow
{
// UIKIt will normally set the scale factor of a view to match the corresponding
@@ -193,13 +208,12 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
// when the size is also changed.
if (!CGAffineTransformIsIdentity(self.transform))
- qWarning() << m_qioswindow->window()
- << "is backed by a UIView that has a transform set. This is not supported.";
+ qWarning() << self << "has a transform set. This is not supported.";
QWindow *window = m_qioswindow->window();
QRect lastReportedGeometry = qt_window_private(window)->geometry;
QRect currentGeometry = QRectF::fromCGRect(self.frame).toRect();
- qCDebug(lcQpaWindow) << m_qioswindow->window() << "new geometry is" << currentGeometry;
+ qCDebug(lcQpaWindow) << m_qioswindow << "new geometry is" << currentGeometry;
QWindowSystemInterface::handleGeometryChange(window, currentGeometry);
if (currentGeometry.size() != lastReportedGeometry.size()) {
@@ -232,7 +246,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
region = QRect(QPoint(), bounds);
}
- qCDebug(lcQpaWindow) << m_qioswindow->window() << region << "isExposed" << m_qioswindow->isExposed();
+ qCDebug(lcQpaWindow) << m_qioswindow << region << "isExposed" << m_qioswindow->isExposed();
QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), region);
}
@@ -256,16 +270,14 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
// blocked by this guard.
FirstResponderCandidate firstResponderCandidate(self);
- qImDebug() << "win:" << m_qioswindow->window() << "self:" << self
- << "first:" << [UIResponder currentFirstResponder];
+ qImDebug() << "self:" << self << "first:" << [UIResponder currentFirstResponder];
if (![super becomeFirstResponder]) {
- qImDebug() << m_qioswindow->window()
- << "was not allowed to become first responder";
+ qImDebug() << self << "was not allowed to become first responder";
return NO;
}
- qImDebug() << m_qioswindow->window() << "became first responder";
+ qImDebug() << self << "became first responder";
}
if (qGuiApp->focusWindow() != m_qioswindow->window())
@@ -297,13 +309,12 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
- (BOOL)resignFirstResponder
{
- qImDebug() << "win:" << m_qioswindow->window() << "self:" << self
- << "first:" << [UIResponder currentFirstResponder];
+ qImDebug() << "self:" << self << "first:" << [UIResponder currentFirstResponder];
if (![super resignFirstResponder])
return NO;
- qImDebug() << m_qioswindow->window() << "resigned first responder";
+ qImDebug() << self << "resigned first responder";
UIResponder *newResponder = FirstResponderCandidate::currentCandidate();
if ([self responderShouldTriggerWindowDeactivation:newResponder])
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index c146f8ec25..3d0dbd7b1a 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -980,8 +980,10 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
case QtWindows::QuerySizeHints:
d->m_creationContext->applyToMinMaxInfo(reinterpret_cast<MINMAXINFO *>(lParam));
return true;
- case QtWindows::ResizeEvent:
- d->m_creationContext->obtainedGeometry.setSize(QSize(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
+ case QtWindows::ResizeEvent: {
+ const QSize size(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) - d->m_creationContext->menuHeight);
+ d->m_creationContext->obtainedGeometry.setSize(size);
+ }
return true;
case QtWindows::MoveEvent:
d->m_creationContext->obtainedGeometry.moveTo(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 038ee5cd62..159e1250d0 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1034,8 +1034,10 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w,
const QMargins effectiveMargins = margins + customMargins;
frameWidth = effectiveMargins.left() + geometry.width() + effectiveMargins.right();
frameHeight = effectiveMargins.top() + geometry.height() + effectiveMargins.bottom();
- if (QWindowsMenuBar::menuBarOf(w) != nullptr)
- frameHeight += GetSystemMetrics(SM_CYMENU);
+ if (QWindowsMenuBar::menuBarOf(w) != nullptr) {
+ menuHeight = GetSystemMetrics(SM_CYMENU);
+ frameHeight += menuHeight;
+ }
const bool isDefaultPosition = !frameX && !frameY && w->isTopLevel();
if (!QWindowsGeometryHint::positionIncludesFrame(w) && !isDefaultPosition) {
frameX -= effectiveMargins.left();
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index 3732255738..8d29b871bf 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -101,6 +101,7 @@ struct QWindowCreationContext
int frameY = CW_USEDEFAULT;
int frameWidth = CW_USEDEFAULT;
int frameHeight = CW_USEDEFAULT;
+ int menuHeight = 0;
};
struct QWindowsWindowData
diff --git a/src/sql/sql.pro b/src/sql/sql.pro
index 133bf831c8..821ae1c9b9 100644
--- a/src/sql/sql.pro
+++ b/src/sql/sql.pro
@@ -2,7 +2,7 @@ TARGET = QtSql
QT = core-private
DEFINES += QT_NO_USING_NAMESPACE
-win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x62000000
+msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x62000000
QMAKE_DOCS = $$PWD/doc/qtsql.qdocconf
diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp
index 1cc8543fdd..0c847b899e 100644
--- a/src/widgets/graphicsview/qgraphicsview.cpp
+++ b/src/widgets/graphicsview/qgraphicsview.cpp
@@ -313,13 +313,15 @@ void QGraphicsViewPrivate::translateTouchEvent(QGraphicsViewPrivate *d, QTouchEv
QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
for (int i = 0; i < touchPoints.count(); ++i) {
QTouchEvent::TouchPoint &touchPoint = touchPoints[i];
+ const QSizeF ellipseDiameters = touchPoint.ellipseDiameters();
// the scene will set the item local pos, startPos, lastPos, and rect before delivering to
// an item, but for now those functions are returning the view's local coordinates
- touchPoint.setSceneRect(d->mapToScene(touchPoint.rect()));
+ touchPoint.setScenePos(d->mapToScene(touchPoint.pos()));
touchPoint.setStartScenePos(d->mapToScene(touchPoint.startPos()));
touchPoint.setLastScenePos(d->mapToScene(touchPoint.lastPos()));
+ touchPoint.setEllipseDiameters(ellipseDiameters);
- // screenPos, startScreenPos, lastScreenPos, and screenRect are already set
+ // screenPos, startScreenPos, and lastScreenPos are already set
}
touchEvent->setTouchPoints(touchPoints);
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index 9e4910ebd0..b855e32f2d 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -2847,7 +2847,7 @@ void QApplication::setStartDragDistance(int l)
and the current position (e.g. in the mouse move event) is \c currentPos,
you can find out if a drag should be started with code like this:
- \snippet code/src_gui_kernel_qapplication.cpp 6
+ \snippet code/src_gui_kernel_qapplication.cpp 7
Qt uses this value internally, e.g. in QFileDialog.
diff --git a/src/widgets/widgets.pro b/src/widgets/widgets.pro
index 27d7fe9874..e028a691c8 100644
--- a/src/widgets/widgets.pro
+++ b/src/widgets/widgets.pro
@@ -4,7 +4,7 @@ MODULE_CONFIG = uic
CONFIG += $$MODULE_CONFIG
DEFINES += QT_NO_USING_NAMESPACE
-win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x65000000
+msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x65000000
QMAKE_DOCS = $$PWD/doc/qtwidgets.qdocconf
diff --git a/src/xml/xml.pro b/src/xml/xml.pro
index cf9feda9bc..31d742d6ea 100644
--- a/src/xml/xml.pro
+++ b/src/xml/xml.pro
@@ -3,7 +3,7 @@ QT = core-private
DEFINES += QT_NO_USING_NAMESPACE QT_NO_FOREACH
-win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x61000000
+msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x61000000
QMAKE_DOCS = $$PWD/doc/qtxml.qdocconf
diff --git a/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp b/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp
index 15a39b62c0..76efa008f7 100644
--- a/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp
+++ b/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp
@@ -29,8 +29,11 @@
#include <QtTest/QtTest>
#include <qwineventnotifier.h>
#include <qtimer.h>
+#include <qvarlengtharray.h>
+#include <qvector.h>
#include <qt_windows.h>
+#include <algorithm>
#include <memory>
class tst_QWinEventNotifier : public QObject
@@ -44,6 +47,8 @@ private slots:
void simple_data();
void simple();
void manyNotifiers();
+ void disableNotifiersInActivatedSlot_data();
+ void disableNotifiersInActivatedSlot();
private:
HANDLE simpleHEvent;
@@ -109,9 +114,6 @@ public:
this, &EventWithNotifier::onNotifierActivated);
notifier.setHandle(CreateEvent(0, TRUE, FALSE, 0));
notifier.setEnabled(true);
-
- static int nextIndex = 0;
- idx = nextIndex++;
}
~EventWithNotifier()
@@ -122,6 +124,7 @@ public:
HANDLE eventHandle() const { return notifier.handle(); }
int numberOfTimesActivated() const { return activatedCount; }
+ void setEnabled(bool b) { notifier.setEnabled(b); }
signals:
void activated();
@@ -137,7 +140,6 @@ public slots:
private:
QWinEventNotifier notifier;
int activatedCount = 0;
- int idx = 0;
};
void tst_QWinEventNotifier::manyNotifiers()
@@ -184,6 +186,60 @@ void tst_QWinEventNotifier::manyNotifiers()
}));
}
+using Indices = QVector<int>;
+
+void tst_QWinEventNotifier::disableNotifiersInActivatedSlot_data()
+{
+ QTest::addColumn<int>("count");
+ QTest::addColumn<Indices>("notifiersToSignal");
+ QTest::addColumn<Indices>("notifiersToDisable");
+ QTest::addColumn<bool>("deleteNotifiers");
+ QTest::newRow("disable_signaled") << 3 << Indices{1} << Indices{1} << false;
+ QTest::newRow("disable_signaled2") << 3 << Indices{1, 2} << Indices{1} << false;
+ QTest::newRow("disable_before_signaled") << 3 << Indices{1} << Indices{0, 1} << false;
+ QTest::newRow("disable_after_signaled") << 3 << Indices{1} << Indices{1, 2} << false;
+ QTest::newRow("delete_signaled") << 3 << Indices{1} << Indices{1} << true;
+ QTest::newRow("delete_before_signaled1") << 3 << Indices{1} << Indices{0} << true;
+ QTest::newRow("delete_before_signaled2") << 3 << Indices{1} << Indices{0, 1} << true;
+ QTest::newRow("delete_before_signaled3") << 4 << Indices{3, 1} << Indices{0, 1} << true;
+ QTest::newRow("delete_after_signaled1") << 3 << Indices{1} << Indices{1, 2} << true;
+ QTest::newRow("delete_after_signaled2") << 4 << Indices{1, 3} << Indices{1, 2} << true;
+ QTest::newRow("delete_after_signaled3") << 5 << Indices{1} << Indices{1, 4} << true;
+}
+
+void tst_QWinEventNotifier::disableNotifiersInActivatedSlot()
+{
+ QFETCH(int, count);
+ QFETCH(Indices, notifiersToSignal);
+ QFETCH(Indices, notifiersToDisable);
+ QFETCH(bool, deleteNotifiers);
+
+ QVarLengthArray<std::unique_ptr<EventWithNotifier>, 10> events(count);
+ for (int i = 0; i < count; ++i)
+ events[i].reset(new EventWithNotifier);
+
+ auto isActivatedOrNull = [&events](int i) {
+ return !events.at(i) || events.at(i)->numberOfTimesActivated() > 0;
+ };
+
+ for (auto &e : events) {
+ connect(e.get(), &EventWithNotifier::activated, [&]() {
+ for (int i : notifiersToDisable) {
+ if (deleteNotifiers)
+ events[i].reset();
+ else
+ events.at(i)->setEnabled(false);
+ }
+ if (std::all_of(notifiersToSignal.begin(), notifiersToSignal.end(), isActivatedOrNull))
+ QTimer::singleShot(0, &QTestEventLoop::instance(), SLOT(exitLoop()));
+ });
+ }
+ for (int i : notifiersToSignal)
+ SetEvent(events.at(i)->eventHandle());
+ QTestEventLoop::instance().enterLoop(30);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+}
+
QTEST_MAIN(tst_QWinEventNotifier)
#include "tst_qwineventnotifier.moc"
diff --git a/tests/auto/gui/image/qmovie/tst_qmovie.cpp b/tests/auto/gui/image/qmovie/tst_qmovie.cpp
index bcaa759faa..4e9e9b8115 100644
--- a/tests/auto/gui/image/qmovie/tst_qmovie.cpp
+++ b/tests/auto/gui/image/qmovie/tst_qmovie.cpp
@@ -170,6 +170,16 @@ void tst_QMovie::playMovie()
QCOMPARE(movie.state(), QMovie::NotRunning);
QCOMPARE(movie.frameCount(), frameCount);
#endif
+
+ movie.stop();
+ QSignalSpy finishedSpy(&movie, &QMovie::finished);
+ movie.setSpeed(0);
+ movie.start();
+ QCOMPARE(movie.state(), QMovie::Running);
+ QTestEventLoop::instance().enterLoop(2);
+ QCOMPARE(finishedSpy.count(), 0);
+ QCOMPARE(movie.state(), QMovie::Running);
+ QCOMPARE(movie.currentFrameNumber(), 0);
}
void tst_QMovie::jumpToFrame_data()
diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp
index 3b340d06ab..fe8571abf1 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp
@@ -254,6 +254,7 @@ private slots:
void zeroScale();
void focusItemChangedSignal();
void minimumRenderSize();
+ void checkTouchPointsEllipseDiameters();
// task specific tests below me
void task139710_bspTreeCrash();
@@ -4764,6 +4765,81 @@ void tst_QGraphicsScene::minimumRenderSize()
QVERIFY(smallChild->repaints > smallerGrandChild->repaints);
}
+class TouchItem : public QGraphicsRectItem
+{
+public:
+ TouchItem() : QGraphicsRectItem(QRectF(-10, -10, 20, 20)),
+ seenTouch(false)
+ {
+ setAcceptTouchEvents(true);
+ setFlag(QGraphicsItem::ItemIgnoresTransformations);
+ }
+ bool seenTouch;
+ QList<QTouchEvent::TouchPoint> touchPoints;
+protected:
+ bool sceneEvent(QEvent *event) override
+ {
+ switch (event->type()) {
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ seenTouch = true;
+ touchPoints = static_cast<QTouchEvent *>(event)->touchPoints();
+ event->accept();
+ return true;
+ default:
+ break;
+ }
+ return QGraphicsRectItem::sceneEvent(event);
+ }
+};
+
+void tst_QGraphicsScene::checkTouchPointsEllipseDiameters()
+{
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+ scene.setSceneRect(1, 1, 198, 198);
+ view.scale(1.5, 1.5);
+ view.setFocus();
+ TouchItem *rect = new TouchItem;
+ scene.addItem(rect);
+ view.show();
+ QApplication::setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowActive(&view));
+
+ const QSizeF ellipseDiameters(10.0, 10.0);
+ QTouchEvent::TouchPoint touchPoint(0);
+ touchPoint.setState(Qt::TouchPointPressed);
+ touchPoint.setPos(view.mapFromScene(rect->mapToScene(rect->boundingRect().center())));
+ touchPoint.setScreenPos(view.mapToGlobal(touchPoint.pos().toPoint()));
+ touchPoint.setEllipseDiameters(ellipseDiameters);
+
+ QList<QTouchEvent::TouchPoint> touchPoints = { touchPoint };
+
+ QTouchDevice *testDevice = QTest::createTouchDevice(QTouchDevice::TouchPad);
+ QTouchEvent touchEvent(QEvent::TouchBegin,
+ testDevice,
+ Qt::NoModifier,
+ Qt::TouchPointPressed,
+ touchPoints);
+ QApplication::sendEvent(view.viewport(), &touchEvent);
+ QVERIFY(rect->seenTouch);
+ QVERIFY(rect->touchPoints.size() == 1);
+ QCOMPARE(ellipseDiameters, rect->touchPoints.first().ellipseDiameters());
+
+ rect->seenTouch = false;
+ rect->touchPoints.clear();
+ QTouchEvent touchUpdateEvent(QEvent::TouchUpdate,
+ testDevice,
+ Qt::NoModifier,
+ Qt::TouchPointMoved,
+ touchPoints);
+ QApplication::sendEvent(view.viewport(), &touchEvent);
+ QVERIFY(rect->seenTouch);
+ QVERIFY(rect->touchPoints.size() == 1);
+ QCOMPARE(ellipseDiameters, rect->touchPoints.first().ellipseDiameters());
+}
+
void tst_QGraphicsScene::taskQTBUG_15977_renderWithDeviceCoordinateCache()
{
QGraphicsScene scene;
diff --git a/tests/manual/touchGraphicsItem/main.cpp b/tests/manual/touchGraphicsItem/main.cpp
new file mode 100644
index 0000000000..7afadc7edd
--- /dev/null
+++ b/tests/manual/touchGraphicsItem/main.cpp
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 <QtWidgets>
+
+class TouchableItem : public QGraphicsRectItem
+{
+public:
+ TouchableItem() : QGraphicsRectItem(50, 50, 400, 400)
+ {
+ setBrush(Qt::yellow);
+ setAcceptTouchEvents(true);
+ }
+protected:
+ bool sceneEvent(QEvent *e)
+ {
+ const bool ret = QGraphicsRectItem::sceneEvent(e);
+ switch (e->type()) {
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ {
+ QTouchEvent *te = static_cast<QTouchEvent *>(e);
+ for (const QTouchEvent::TouchPoint &tp : te->touchPoints()) {
+ QGraphicsEllipseItem *diameterItem = nullptr;
+ QSizeF ellipse = tp.ellipseDiameters();
+ if (ellipse.isNull()) {
+ ellipse = QSizeF(5, 5);
+ } else {
+ diameterItem = new QGraphicsEllipseItem(QRectF(tp.pos().x() - ellipse.width() / 2, tp.pos().y() - ellipse.height() / 2,
+ ellipse.width(), ellipse.height()), this);
+ diameterItem->setPen(QPen(Qt::red));
+ diameterItem->setBrush(QBrush(Qt::red));
+ if (ellipse.width() > qreal(2) && ellipse.height() > qreal(2))
+ ellipse.scale(ellipse.width() - 2, ellipse.height() - 2, Qt::IgnoreAspectRatio);
+ }
+ QGraphicsItem *parent = diameterItem ? static_cast<QGraphicsItem *>(diameterItem) : static_cast<QGraphicsItem *>(this);
+ QGraphicsEllipseItem *ellipseItem = new QGraphicsEllipseItem(QRectF(tp.pos().x() - ellipse.width() / 2,
+ tp.pos().y() - ellipse.height() / 2,
+ ellipse.width(), ellipse.height()), parent);
+ ellipseItem->setPen(QPen(Qt::blue));
+ ellipseItem->setBrush(QBrush(Qt::blue));
+ }
+ te->accept();
+ return true;
+ }
+ default:
+ break;
+ }
+ return ret;
+ }
+};
+
+int main(int argc, char **argv)
+{
+ QApplication a(argc, argv);
+ QMainWindow mw;
+ QWidget *w = new QWidget;
+ QVBoxLayout *vbox = new QVBoxLayout;
+ vbox->addWidget(new QLabel("The blue ellipses should indicate touch point contact patches"));
+ qDebug() << "Touch devices:";
+ for (const QTouchDevice *device : QTouchDevice::devices()) {
+ QString result;
+ QTextStream str(&result);
+ str << (device->type() == QTouchDevice::TouchScreen ? "TouchScreen" : "TouchPad")
+ << " \"" << device->name() << "\", max " << device->maximumTouchPoints()
+ << " touch points, capabilities:";
+ const QTouchDevice::Capabilities capabilities = device->capabilities();
+ if (capabilities & QTouchDevice::Position)
+ str << " Position";
+ if (capabilities & QTouchDevice::Area)
+ str << " Area";
+ if (capabilities & QTouchDevice::Pressure)
+ str << " Pressure";
+ if (capabilities & QTouchDevice::Velocity)
+ str << " Velocity";
+ if (capabilities & QTouchDevice::RawPositions)
+ str << " RawPositions";
+ if (capabilities & QTouchDevice::NormalizedPosition)
+ str << " NormalizedPosition";
+ if (capabilities & QTouchDevice::MouseEmulation)
+ str << " MouseEmulation";
+ vbox->addWidget(new QLabel(result));
+ qDebug() << " " << result;
+ }
+ QGraphicsView *view = new QGraphicsView;
+ view->viewport()->setAttribute(Qt::WA_AcceptTouchEvents);
+ QGraphicsScene *scene = new QGraphicsScene(0, 0, 500, 500);
+ TouchableItem *touchableItem = new TouchableItem;
+ scene->addItem(touchableItem);
+ view->setScene(scene);
+ vbox->addWidget(view);
+ w->setLayout(vbox);
+ mw.setCentralWidget(w);
+ QMenu *menu = mw.menuBar()->addMenu("Menu");
+ QAction *clear = new QAction("Clear");
+ QObject::connect(clear, &QAction::triggered, [=]() {
+ qDeleteAll(touchableItem->childItems());
+ });
+ menu->addAction(clear);
+ QAction *ignoreTransform = new QAction("Ignore transformations");
+ QObject::connect(ignoreTransform, &QAction::triggered, [=]() {
+ view->scale(1.5, 1.5);
+ touchableItem->setFlag(QGraphicsItem::ItemIgnoresTransformations);
+ });
+ menu->addAction(ignoreTransform);
+ QAction *quit = new QAction("Quit");
+ quit->setShortcut(QKeySequence::Quit);
+ QObject::connect(quit, &QAction::triggered, &QApplication::quit);
+ menu->addAction(quit);
+ mw.show();
+
+ return a.exec();
+}
+
+
diff --git a/tests/manual/touchGraphicsItem/touchGraphicsItem.pro b/tests/manual/touchGraphicsItem/touchGraphicsItem.pro
new file mode 100644
index 0000000000..67799ce9c4
--- /dev/null
+++ b/tests/manual/touchGraphicsItem/touchGraphicsItem.pro
@@ -0,0 +1,5 @@
+QT+=widgets
+TEMPLATE = app
+TARGET = touchGraphicsItem
+INCLUDEPATH += .
+SOURCES += main.cpp