summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.json1
-rw-r--r--examples/widgets/widgets/tablet/mainwindow.cpp16
-rw-r--r--examples/widgets/widgets/tablet/mainwindow.h3
-rw-r--r--examples/widgets/widgets/tablet/tabletcanvas.cpp6
-rw-r--r--examples/widgets/widgets/tablet/tabletcanvas.h1
-rw-r--r--mkspecs/common/macx.conf3
-rw-r--r--mkspecs/macx-clang/qmake.conf4
-rw-r--r--mkspecs/macx-g++/qmake.conf4
-rw-r--r--mkspecs/macx-icc/qmake.conf4
-rw-r--r--mkspecs/win32-icc/qmake.conf1
-rw-r--r--src/corelib/global/qnamespace.qdoc3
-rw-r--r--src/corelib/io/qloggingcategory.cpp16
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.cpp4
-rw-r--r--src/corelib/tools/qvarlengtharray.h6
-rw-r--r--src/gui/configure.json4
-rw-r--r--src/gui/image/qimage.cpp14
-rw-r--r--src/gui/kernel/qevent.cpp2
-rw-r--r--src/gui/kernel/qguiapplication.cpp3
-rw-r--r--src/gui/opengl/qopengltextureuploader.cpp10
-rw-r--r--src/gui/painting/qdrawhelper.cpp56
-rw-r--r--src/gui/painting/qdrawhelper_p.h71
-rw-r--r--src/gui/painting/qimagescale.cpp235
-rw-r--r--src/gui/painting/qrgba64_p.h13
-rw-r--r--src/gui/text/qtextengine.cpp29
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp5
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp3
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.h1
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp53
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.h8
-rw-r--r--src/plugins/platforms/windows/qwindowsopengltester.cpp62
-rw-r--r--src/plugins/platforms/windows/qwindowsopengltester.h1
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp84
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp2
-rw-r--r--src/plugins/printsupport/cups/qcupsprintersupport.cpp6
-rw-r--r--src/testlib/3rdparty/qt_attribution.json3
-rw-r--r--src/tools/androiddeployqt/main.cpp23
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp11
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp3
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp232
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h4
-rw-r--r--tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST1
-rw-r--r--tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp5
-rw-r--r--tests/auto/gui/image/qimage/tst_qimage.cpp34
-rw-r--r--tests/auto/other/qaccessibility/tst_qaccessibility.cpp2
-rw-r--r--tests/auto/widgets/dialogs/qdialog/BLACKLIST2
-rw-r--r--tests/auto/widgets/kernel/qwidget/BLACKLIST2
-rw-r--r--tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp30
48 files changed, 929 insertions, 159 deletions
diff --git a/configure.json b/configure.json
index 16a2af5bab..1f45f2ccb2 100644
--- a/configure.json
+++ b/configure.json
@@ -161,6 +161,7 @@
},
"sources": [
{ "libs": "-lzdll", "condition": "config.msvc" },
+ { "libs": "-lzlib", "condition": "config.msvc" },
{ "libs": "-lz", "condition": "!config.msvc" }
]
},
diff --git a/examples/widgets/widgets/tablet/mainwindow.cpp b/examples/widgets/widgets/tablet/mainwindow.cpp
index 994666d4de..a048119533 100644
--- a/examples/widgets/widgets/tablet/mainwindow.cpp
+++ b/examples/widgets/widgets/tablet/mainwindow.cpp
@@ -104,15 +104,16 @@ void MainWindow::setEventCompression(bool compress)
}
//! [5]
-void MainWindow::save()
+bool MainWindow::save()
{
QString path = QDir::currentPath() + "/untitled.png";
QString fileName = QFileDialog::getSaveFileName(this, tr("Save Picture"),
path);
-
- if (!m_canvas->saveImage(fileName))
+ bool success = m_canvas->saveImage(fileName);
+ if (!success)
QMessageBox::information(this, "Error Saving Picture",
"Could not save the image");
+ return success;
}
//! [5]
@@ -128,6 +129,14 @@ void MainWindow::load()
}
//! [6]
+void MainWindow::clear()
+{
+ if (QMessageBox::question(this, tr("Save changes"), tr("Do you want to save your changes?"),
+ QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel,
+ QMessageBox::Save) != QMessageBox::Save || save())
+ m_canvas->clear();
+}
+
//! [7]
void MainWindow::about()
{
@@ -142,6 +151,7 @@ void MainWindow::createMenus()
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(tr("&Open..."), this, &MainWindow::load, QKeySequence::Open);
fileMenu->addAction(tr("&Save As..."), this, &MainWindow::save, QKeySequence::SaveAs);
+ fileMenu->addAction(tr("&New"), this, &MainWindow::clear, QKeySequence::New);
fileMenu->addAction(tr("E&xit"), this, &MainWindow::close, QKeySequence::Quit);
QMenu *brushMenu = menuBar()->addMenu(tr("&Brush"));
diff --git a/examples/widgets/widgets/tablet/mainwindow.h b/examples/widgets/widgets/tablet/mainwindow.h
index 4b99324f04..4be28784b5 100644
--- a/examples/widgets/widgets/tablet/mainwindow.h
+++ b/examples/widgets/widgets/tablet/mainwindow.h
@@ -72,8 +72,9 @@ private slots:
void setLineWidthValuator(QAction *action);
void setSaturationValuator(QAction *action);
void setEventCompression(bool compress);
- void save();
+ bool save();
void load();
+ void clear();
void about();
private:
diff --git a/examples/widgets/widgets/tablet/tabletcanvas.cpp b/examples/widgets/widgets/tablet/tabletcanvas.cpp
index 73678ab754..3ff26d2ec8 100644
--- a/examples/widgets/widgets/tablet/tabletcanvas.cpp
+++ b/examples/widgets/widgets/tablet/tabletcanvas.cpp
@@ -90,6 +90,12 @@ bool TabletCanvas::loadImage(const QString &file)
}
//! [2]
+void TabletCanvas::clear()
+{
+ m_pixmap.fill(Qt::white);
+ update();
+}
+
//! [3]
void TabletCanvas::tabletEvent(QTabletEvent *event)
{
diff --git a/examples/widgets/widgets/tablet/tabletcanvas.h b/examples/widgets/widgets/tablet/tabletcanvas.h
index 671d5376f8..c63ef76893 100644
--- a/examples/widgets/widgets/tablet/tabletcanvas.h
+++ b/examples/widgets/widgets/tablet/tabletcanvas.h
@@ -79,6 +79,7 @@ public:
bool saveImage(const QString &file);
bool loadImage(const QString &file);
+ void clear();
void setAlphaChannelValuator(Valuator type)
{ m_alphaChannelValuator = type; }
void setColorSaturationValuator(Valuator type)
diff --git a/mkspecs/common/macx.conf b/mkspecs/common/macx.conf
index 7017d60e71..810b94fc9e 100644
--- a/mkspecs/common/macx.conf
+++ b/mkspecs/common/macx.conf
@@ -5,6 +5,9 @@
QMAKE_PLATFORM += macos osx macx
QMAKE_MAC_SDK = macosx
+QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.11
+QMAKE_APPLE_DEVICE_ARCHS = x86_64
+
device.sdk = macosx
device.target = device
device.dir_affix = $${device.sdk}
diff --git a/mkspecs/macx-clang/qmake.conf b/mkspecs/macx-clang/qmake.conf
index 14c885fd78..464f327ac4 100644
--- a/mkspecs/macx-clang/qmake.conf
+++ b/mkspecs/macx-clang/qmake.conf
@@ -2,10 +2,6 @@
# qmake configuration for Clang on OS X
#
-QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.11
-
-QMAKE_APPLE_DEVICE_ARCHS = x86_64
-
# Opt-in xcb QPA support with XQuartz:
#
# configure \
diff --git a/mkspecs/macx-g++/qmake.conf b/mkspecs/macx-g++/qmake.conf
index 5686610b17..d0e0026f1e 100644
--- a/mkspecs/macx-g++/qmake.conf
+++ b/mkspecs/macx-g++/qmake.conf
@@ -10,10 +10,6 @@ MAKEFILE_GENERATOR = UNIX
CONFIG += app_bundle incremental global_init_link_order lib_version_first
QMAKE_INCREMENTAL_STYLE = sublib
-QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.11
-
-QMAKE_APPLE_DEVICE_ARCHS = x86_64
-
include(../common/macx.conf)
include(../common/gcc-base-mac.conf)
include(../common/g++-macx.conf)
diff --git a/mkspecs/macx-icc/qmake.conf b/mkspecs/macx-icc/qmake.conf
index bf3854c7c5..4daad497af 100644
--- a/mkspecs/macx-icc/qmake.conf
+++ b/mkspecs/macx-icc/qmake.conf
@@ -29,9 +29,5 @@ QMAKE_LFLAGS_HEADERPAD = -headerpad_max_install_names
QMAKE_LFLAGS_VERSION = -current_version$${LITERAL_WHITESPACE}
QMAKE_LFLAGS_COMPAT_VERSION = -compatibility_version$${LITERAL_WHITESPACE}
-QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.11
-
-QMAKE_APPLE_DEVICE_ARCHS = x86_64
-
include(../common/macx.conf)
load(qt_config)
diff --git a/mkspecs/win32-icc/qmake.conf b/mkspecs/win32-icc/qmake.conf
index 3cb0d58824..2447c712b1 100644
--- a/mkspecs/win32-icc/qmake.conf
+++ b/mkspecs/win32-icc/qmake.conf
@@ -12,6 +12,7 @@ include(../common/msvc-desktop.conf)
# modifications to msvc-desktop.conf
QMAKE_COMPILER += intel_icl
+DEFINES += _ENABLE_EXTENDED_ALIGNED_STORAGE
QMAKE_CFLAGS_OPTIMIZE_FULL = -O3
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index e3c51f4be0..37144dcf17 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -383,7 +383,8 @@
\value AltModifier An Alt key on the keyboard is pressed.
\value MetaModifier A Meta key on the keyboard is pressed.
\value KeypadModifier A keypad button is pressed.
- \value GroupSwitchModifier X11 only. A Mode_switch key on the keyboard is pressed.
+ \value GroupSwitchModifier X11 only (unless activated on Windows by a command line argument).
+ A Mode_switch key on the keyboard is pressed.
\omitvalue KeyboardModifierMask
diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp
index d8402c4eb6..aa84f56368 100644
--- a/src/corelib/io/qloggingcategory.cpp
+++ b/src/corelib/io/qloggingcategory.cpp
@@ -471,8 +471,6 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\note Arguments are not processed if debug output for the category is not
enabled, so do not rely on any side effects.
- \note Using the macro is thread-safe.
-
\sa qDebug()
*/
@@ -493,8 +491,6 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\note Arguments might not be processed if debug output for the category is
not enabled, so do not rely on any side effects.
- \note Using the macro is thread-safe.
-
\sa qDebug()
*/
@@ -518,8 +514,6 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\note Arguments are not processed if debug output for the category is not
enabled, so do not rely on any side effects.
- \note Using the macro is thread-safe.
-
\sa qInfo()
*/
@@ -540,8 +534,6 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\note Arguments might not be processed if debug output for the category is
not enabled, so do not rely on any side effects.
- \note Using the macro is thread-safe.
-
\sa qInfo()
*/
@@ -565,8 +557,6 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\note Arguments are not processed if warning output for the category is not
enabled, so do not rely on any side effects.
- \note Using the macro is thread-safe.
-
\sa qWarning()
*/
@@ -587,8 +577,6 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\note Arguments might not be processed if warning output for the category is
not enabled, so do not rely on any side effects.
- \note Using the macro is thread-safe.
-
\sa qWarning()
*/
@@ -612,8 +600,6 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\note Arguments are not processed if critical output for the category is not
enabled, so do not rely on any side effects.
- \note Using the macro is thread-safe.
-
\sa qCritical()
*/
@@ -634,8 +620,6 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\note Arguments might not be processed if critical output for the category
is not enabled, so do not rely on any side effects.
- \note Using the macro is thread-safe.
-
\sa qCritical()
*/
/*!
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
index d8b4c8cc97..6b59b0723b 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
@@ -2347,7 +2347,7 @@ bool QSortFilterProxyModel::insertRows(int row, int count, const QModelIndex &pa
if (row > m->source_rows.count())
return false;
int source_row = (row >= m->source_rows.count()
- ? m->source_rows.count()
+ ? m->proxy_rows.count()
: m->source_rows.at(row));
return d->model->insertRows(source_row, count, source_parent);
}
@@ -2367,7 +2367,7 @@ bool QSortFilterProxyModel::insertColumns(int column, int count, const QModelInd
if (column > m->source_columns.count())
return false;
int source_column = (column >= m->source_columns.count()
- ? m->source_columns.count()
+ ? m->proxy_columns.count()
: m->source_columns.at(column));
return d->model->insertColumns(source_column, count, source_parent);
}
diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h
index a6bd7847a5..b74b1fd123 100644
--- a/src/corelib/tools/qvarlengtharray.h
+++ b/src/corelib/tools/qvarlengtharray.h
@@ -490,7 +490,7 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA
}
} else {
T *b = ptr + offset;
- memmove(b + 1, b, (s - offset) * sizeof(T));
+ memmove(static_cast<void *>(b + 1), static_cast<const void *>(b), (s - offset) * sizeof(T));
new (b) T(std::move(t));
}
s += 1;
@@ -518,7 +518,7 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA
} else {
T *b = ptr + offset;
T *i = b + n;
- memmove(i, b, (s - offset - n) * sizeof(T));
+ memmove(static_cast<void *>(i), static_cast<const void *>(b), (s - offset - n) * sizeof(T));
while (i != b)
new (--i) T(copy);
}
@@ -544,7 +544,7 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA
i->~T();
}
} else {
- memmove(ptr + f, ptr + l, (s - l) * sizeof(T));
+ memmove(static_cast<void *>(ptr + f), static_cast<const void *>(ptr + l), (s - l) * sizeof(T));
}
s -= n;
return ptr + f;
diff --git a/src/gui/configure.json b/src/gui/configure.json
index 8e6569c069..26a5ae9a3d 100644
--- a/src/gui/configure.json
+++ b/src/gui/configure.json
@@ -294,7 +294,7 @@
},
"sources": [
{ "libs": "-llibjpeg", "condition": "config.msvc" },
- { "libs": "-ljpeg", "condition": "!config.msvc" }
+ "-ljpeg"
]
},
"libpng": {
@@ -305,7 +305,9 @@
},
"sources": [
{ "type": "pkgConfig", "args": "libpng" },
+ { "libs": "-llibpng16", "condition": "config.msvc" },
{ "libs": "-llibpng", "condition": "config.msvc" },
+ { "libs": "-lpng16", "condition": "!config.msvc" },
{ "libs": "-lpng", "condition": "!config.msvc" }
],
"use": [
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 32ef67763a..8a4c6b7fda 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -1829,7 +1829,14 @@ void QImage::fill(const QColor &color)
else
fill((uint) 0);
break;
- case QImage::Format_RGBX64:
+ case QImage::Format_RGBX64: {
+ QRgba64 c = color.rgba64();
+ c.setAlpha(65535);
+ qt_rectfill<quint64>(reinterpret_cast<quint64*>(d->data), c,
+ 0, 0, d->width, d->height, d->bytes_per_line);
+ break;
+
+ }
case QImage::Format_RGBA64:
case QImage::Format_RGBA64_Premultiplied:
qt_rectfill<quint64>(reinterpret_cast<quint64*>(d->data), color.rgba64(),
@@ -4616,6 +4623,11 @@ QImage QImage::smoothScaled(int w, int h) const {
case QImage::Format_RGBX8888:
#endif
case QImage::Format_RGBA8888_Premultiplied:
+ case QImage::Format_RGBX64:
+ case QImage::Format_RGBA64_Premultiplied:
+ break;
+ case QImage::Format_RGBA64:
+ src = src.convertToFormat(QImage::Format_RGBA64_Premultiplied);
break;
default:
if (src.hasAlphaChannel())
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index f5527354a2..6f8ea6dc70 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -4163,7 +4163,7 @@ QDebug operator<<(QDebug dbg, const QEvent *e)
const QNativeGestureEvent *ne = static_cast<const QNativeGestureEvent *>(e);
dbg << "QNativeGestureEvent(";
QtDebugUtils::formatQEnum(dbg, ne->gestureType());
- dbg << "localPos=";
+ dbg << ", localPos=";
QtDebugUtils::formatQPoint(dbg, ne->localPos());
dbg << ", value=" << ne->value() << ')';
}
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 40d82d9269..93e8b6ee8f 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -594,6 +594,9 @@ static QWindowGeometrySpecification windowGeometrySpecification = Q_WINDOW_GEOME
By default, they will be used if the application is not an
instance of QApplication or for Qt Quick Controls 2
applications.
+
+ \li \c {altgr}, detect the key \c {AltGr} found on some keyboards as
+ Qt::GroupSwitchModifier.
\endlist
The following parameter is available for \c {-platform cocoa} (on macOS):
diff --git a/src/gui/opengl/qopengltextureuploader.cpp b/src/gui/opengl/qopengltextureuploader.cpp
index fc449d8090..2428baed93 100644
--- a/src/gui/opengl/qopengltextureuploader.cpp
+++ b/src/gui/opengl/qopengltextureuploader.cpp
@@ -140,9 +140,12 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag
// No support for direct ARGB32 upload.
break;
}
+#else
+ // Big endian requires GL_UNSIGNED_INT_8_8_8_8_REV for ARGB to match BGRA
+ break;
+#endif
}
targetFormat = image.format();
-#endif
break;
case QImage::Format_BGR30:
case QImage::Format_A2BGR30_Premultiplied:
@@ -310,6 +313,11 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag
if (newSize != tx.size())
tx = tx.scaled(newSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ // Handle cases where the QImage is actually a sub image of its image data:
+ qsizetype naturalBpl = ((qsizetype(tx.width()) * tx.depth() + 31) >> 5) << 2;
+ if (tx.bytesPerLine() != naturalBpl)
+ tx = tx.copy(tx.rect());
+
funcs->glTexImage2D(target, 0, internalFormat, tx.width(), tx.height(), 0, externalFormat, pixelType, tx.constBits());
qsizetype cost = qint64(tx.width()) * tx.height() * tx.depth() / 8;
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index b1424b5b0a..8f189994f1 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -342,7 +342,7 @@ static void QT_FASTCALL convertToRGB32(uint *buffer, int count, const QVector<QR
buffer[i] = convertPixelToRGB32<Format>(buffer[i]);
}
-#if defined(__SSE2__) && !defined(__SSSE3__)
+#if defined(__SSE2__) && !defined(__SSSE3__) && QT_COMPILER_SUPPORTS_SSSE3
extern const uint * QT_FASTCALL fetchPixelsBPP24_ssse3(uint *dest, const uchar*src, int index, int count);
#endif
@@ -351,7 +351,7 @@ static const uint *QT_FASTCALL fetchRGBToRGB32(uint *buffer, const uchar *src, i
const QVector<QRgb> *, QDitherInfo *)
{
constexpr QPixelLayout::BPP BPP = bitsPerPixel<Format>();
-#if defined(__SSE2__) && !defined(__SSSE3__)
+#if defined(__SSE2__) && !defined(__SSSE3__) && QT_COMPILER_SUPPORTS_SSSE3
if (BPP == QPixelLayout::BPP24 && qCpuHasFeature(SSSE3)) {
// With SSE2 can convertToRGB32 be vectorized, but it takes SSSE3
// to vectorize the deforested version below.
@@ -442,7 +442,7 @@ static const uint *QT_FASTCALL fetchARGBPMToARGB32PM(uint *buffer, const uchar *
const QVector<QRgb> *, QDitherInfo *)
{
constexpr QPixelLayout::BPP BPP = bitsPerPixel<Format>();
-#if defined(__SSE2__) && !defined(__SSSE3__)
+#if defined(__SSE2__) && !defined(__SSSE3__) && QT_COMPILER_SUPPORTS_SSSE3
if (BPP == QPixelLayout::BPP24 && qCpuHasFeature(SSSE3)) {
// With SSE2 can convertToRGB32 be vectorized, but it takes SSSE3
// to vectorize the deforested version below.
@@ -640,6 +640,19 @@ void QT_FASTCALL rbSwap<QImage::Format_RGBA8888>(uchar *d, const uchar *s, int c
{
return rbSwap_rgb32(d, s, count);
}
+#else
+template<>
+void QT_FASTCALL rbSwap<QImage::Format_RGBA8888>(uchar *d, const uchar *s, int count)
+{
+ const uint *src = reinterpret_cast<const uint *>(s);
+ uint *dest = reinterpret_cast<uint *>(d);
+ for (int i = 0; i < count; ++i) {
+ const uint c = src[i];
+ const uint rb = c & 0xff00ff00;
+ const uint ga = c & 0x00ff00ff;
+ dest[i] = ga | (rb << 16) | (rb >> 16);
+ }
+}
#endif
static void QT_FASTCALL rbSwap_rgb30(uchar *d, const uchar *s, int count)
@@ -2264,43 +2277,6 @@ static inline uint interpolate_4_pixels_16(uint tl, uint tr, uint bl, uint br, u
}
#endif
-#if defined(__SSE2__)
-static inline QRgba64 interpolate_4_pixels_rgb64(const QRgba64 t[], const QRgba64 b[], uint distx, uint disty)
-{
- __m128i vt = _mm_loadu_si128((const __m128i*)t);
- if (disty) {
- __m128i vb = _mm_loadu_si128((const __m128i*)b);
- vt = _mm_mulhi_epu16(vt, _mm_set1_epi16(0x10000 - disty));
- vb = _mm_mulhi_epu16(vb, _mm_set1_epi16(disty));
- vt = _mm_add_epi16(vt, vb);
- }
- if (distx) {
- const __m128i vdistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(distx), _MM_SHUFFLE(0, 0, 0, 0));
- const __m128i vidistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(0x10000 - distx), _MM_SHUFFLE(0, 0, 0, 0));
- vt = _mm_mulhi_epu16(vt, _mm_unpacklo_epi64(vidistx, vdistx));
- vt = _mm_add_epi16(vt, _mm_srli_si128(vt, 8));
- }
-#ifdef Q_PROCESSOR_X86_64
- return QRgba64::fromRgba64(_mm_cvtsi128_si64(vt));
-#else
- QRgba64 out;
- _mm_storel_epi64((__m128i*)&out, vt);
- return out;
-#endif
-}
-#else
-static inline QRgba64 interpolate_4_pixels_rgb64(const QRgba64 t[], const QRgba64 b[], uint distx, uint disty)
-{
- const uint dx = distx>>8;
- const uint dy = disty>>8;
- const uint idx = 256 - dx;
- const uint idy = 256 - dy;
- QRgba64 xtop = interpolate256(t[0], idx, t[1], dx);
- QRgba64 xbot = interpolate256(b[0], idx, b[1], dx);
- return interpolate256(xtop, idy, xbot, dy);
-}
-#endif
-
template<TextureBlendType blendType>
void fetchTransformedBilinear_pixelBounds(int max, int l1, int l2, int &v1, int &v2);
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index 078ab62251..fb08261205 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -747,6 +747,77 @@ static constexpr inline bool hasFastInterpolate4() { return false; }
#endif
+static inline QRgba64 multiplyAlpha256(QRgba64 rgba64, uint alpha256)
+{
+ return QRgba64::fromRgba64((rgba64.red() * alpha256) >> 8,
+ (rgba64.green() * alpha256) >> 8,
+ (rgba64.blue() * alpha256) >> 8,
+ (rgba64.alpha() * alpha256) >> 8);
+}
+static inline QRgba64 interpolate256(QRgba64 x, uint alpha1, QRgba64 y, uint alpha2)
+{
+ return QRgba64::fromRgba64(multiplyAlpha256(x, alpha1) + multiplyAlpha256(y, alpha2));
+}
+
+#ifdef __SSE2__
+static inline QRgba64 interpolate_4_pixels_rgb64(const QRgba64 t[], const QRgba64 b[], uint distx, uint disty)
+{
+ __m128i vt = _mm_loadu_si128((const __m128i*)t);
+ if (disty) {
+ __m128i vb = _mm_loadu_si128((const __m128i*)b);
+ vt = _mm_mulhi_epu16(vt, _mm_set1_epi16(0x10000 - disty));
+ vb = _mm_mulhi_epu16(vb, _mm_set1_epi16(disty));
+ vt = _mm_add_epi16(vt, vb);
+ }
+ if (distx) {
+ const __m128i vdistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(distx), _MM_SHUFFLE(0, 0, 0, 0));
+ const __m128i vidistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(0x10000 - distx), _MM_SHUFFLE(0, 0, 0, 0));
+ vt = _mm_mulhi_epu16(vt, _mm_unpacklo_epi64(vidistx, vdistx));
+ vt = _mm_add_epi16(vt, _mm_srli_si128(vt, 8));
+ }
+#ifdef Q_PROCESSOR_X86_64
+ return QRgba64::fromRgba64(_mm_cvtsi128_si64(vt));
+#else
+ QRgba64 out;
+ _mm_storel_epi64((__m128i*)&out, vt);
+ return out;
+#endif // Q_PROCESSOR_X86_64
+}
+#elif defined(__ARM_NEON__)
+static inline QRgba64 interpolate_4_pixels_rgb64(const QRgba64 t[], const QRgba64 b[], uint distx, uint disty)
+{
+ uint64x1x2_t vt = vld2_u64(reinterpret_cast<const uint64_t *>(t));
+ if (disty) {
+ uint64x1x2_t vb = vld2_u64(reinterpret_cast<const uint64_t *>(b));
+ uint32x4_t vt0 = vmull_n_u16(vreinterpret_u16_u64(vt.val[0]), 0x10000 - disty);
+ uint32x4_t vt1 = vmull_n_u16(vreinterpret_u16_u64(vt.val[1]), 0x10000 - disty);
+ vt0 = vmlal_n_u16(vt0, vreinterpret_u16_u64(vb.val[0]), disty);
+ vt1 = vmlal_n_u16(vt1, vreinterpret_u16_u64(vb.val[1]), disty);
+ vt.val[0] = vreinterpret_u64_u16(vshrn_n_u32(vt0, 16));
+ vt.val[1] = vreinterpret_u64_u16(vshrn_n_u32(vt1, 16));
+ }
+ if (distx) {
+ uint32x4_t vt0 = vmull_n_u16(vreinterpret_u16_u64(vt.val[0]), 0x10000 - distx);
+ vt0 = vmlal_n_u16(vt0, vreinterpret_u16_u64(vt.val[1]), distx);
+ vt.val[0] = vreinterpret_u64_u16(vshrn_n_u32(vt0, 16));
+ }
+ QRgba64 out;
+ vst1_u64(reinterpret_cast<uint64_t *>(&out), vt.val[0]);
+ return out;
+}
+#else
+static inline QRgba64 interpolate_4_pixels_rgb64(const QRgba64 t[], const QRgba64 b[], uint distx, uint disty)
+{
+ const uint dx = distx>>8;
+ const uint dy = disty>>8;
+ const uint idx = 256 - dx;
+ const uint idy = 256 - dy;
+ QRgba64 xtop = interpolate256(t[0], idx, t[1], dx);
+ QRgba64 xbot = interpolate256(b[0], idx, b[1], dx);
+ return interpolate256(xtop, idy, xbot, dy);
+}
+#endif // __SSE2__
+
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
static Q_ALWAYS_INLINE quint32 RGBA2ARGB(quint32 x) {
quint32 rgb = x >> 8;
diff --git a/src/gui/painting/qimagescale.cpp b/src/gui/painting/qimagescale.cpp
index 22787b91fe..ca7930500e 100644
--- a/src/gui/painting/qimagescale.cpp
+++ b/src/gui/painting/qimagescale.cpp
@@ -41,6 +41,7 @@
#include "qimage.h"
#include "qcolor.h"
+#include "qrgba64_p.h"
QT_BEGIN_NAMESPACE
@@ -85,7 +86,7 @@ QT_BEGIN_NAMESPACE
* #ifdef'ed code, and removal of unneeded border calculation code.
* Later the code has been refactored, an SSE4.1 optimizated path have been
* added instead of the removed MMX assembler, and scaling of clipped area
- * removed.
+ * removed, and an RGBA64 version written
*
* Imlib2 is (C) Carsten Haitzler and various contributors. The MMX code
* is by Willem Monsuwe <willem@stack.nl>. All other modifications are
@@ -94,12 +95,11 @@ QT_BEGIN_NAMESPACE
namespace QImageScale {
- const unsigned int** qimageCalcYPoints(const unsigned int *src, int sw, int sh, int dh);
- int* qimageCalcXPoints(int sw, int dw);
- int* qimageCalcApoints(int s, int d, int up);
- QImageScaleInfo* qimageFreeScaleInfo(QImageScaleInfo *isi);
- QImageScaleInfo *qimageCalcScaleInfo(const QImage &img, int sw, int sh,
- int dw, int dh, char aa);
+ static const unsigned int** qimageCalcYPoints(const unsigned int *src, int sw, int sh, int dh);
+ static int* qimageCalcXPoints(int sw, int dw);
+ static int* qimageCalcApoints(int s, int d, int up);
+ static QImageScaleInfo* qimageFreeScaleInfo(QImageScaleInfo *isi);
+ static QImageScaleInfo *qimageCalcScaleInfo(const QImage &img, int sw, int sh, int dw, int dh, char aa);
}
using namespace QImageScale;
@@ -108,8 +108,8 @@ using namespace QImageScale;
// Code ported from Imlib...
//
-const unsigned int** QImageScale::qimageCalcYPoints(const unsigned int *src,
- int sw, int sh, int dh)
+static const unsigned int** QImageScale::qimageCalcYPoints(const unsigned int *src,
+ int sw, int sh, int dh)
{
const unsigned int **p;
int j = 0, rv = 0;
@@ -138,7 +138,7 @@ const unsigned int** QImageScale::qimageCalcYPoints(const unsigned int *src,
return(p);
}
-int* QImageScale::qimageCalcXPoints(int sw, int dw)
+static int* QImageScale::qimageCalcXPoints(int sw, int dw)
{
int *p, j = 0, rv = 0;
qint64 val, inc;
@@ -167,7 +167,7 @@ int* QImageScale::qimageCalcXPoints(int sw, int dw)
return p;
}
-int* QImageScale::qimageCalcApoints(int s, int d, int up)
+static int* QImageScale::qimageCalcApoints(int s, int d, int up)
{
int *p, j = 0, rv = 0;
@@ -214,7 +214,7 @@ int* QImageScale::qimageCalcApoints(int s, int d, int up)
return p;
}
-QImageScaleInfo* QImageScale::qimageFreeScaleInfo(QImageScaleInfo *isi)
+static QImageScaleInfo* QImageScale::qimageFreeScaleInfo(QImageScaleInfo *isi)
{
if (isi) {
delete[] isi->xpoints;
@@ -226,9 +226,9 @@ QImageScaleInfo* QImageScale::qimageFreeScaleInfo(QImageScaleInfo *isi)
return 0;
}
-QImageScaleInfo* QImageScale::qimageCalcScaleInfo(const QImage &img,
- int sw, int sh,
- int dw, int dh, char aa)
+static QImageScaleInfo* QImageScale::qimageCalcScaleInfo(const QImage &img,
+ int sw, int sh,
+ int dw, int dh, char aa)
{
QImageScaleInfo *isi;
int scw, sch;
@@ -333,7 +333,7 @@ static void qt_qimageScaleAARGBA_up_xy(QImageScaleInfo *isi, unsigned int *dest,
}
}
-/* scale by area sampling */
+/* scale by area sampling - with alpha */
static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest,
int dw, int dh, int dow, int sow)
{
@@ -529,6 +529,204 @@ static void qt_qimageScaleAARGBA_down_xy(QImageScaleInfo *isi, unsigned int *des
}
}
+static void qt_qimageScaleRgba64_up_x_down_y(QImageScaleInfo *isi, QRgba64 *dest,
+ int dw, int dh, int dow, int sow);
+
+static void qt_qimageScaleRgba64_down_x_up_y(QImageScaleInfo *isi, QRgba64 *dest,
+ int dw, int dh, int dow, int sow);
+
+static void qt_qimageScaleRgba64_down_xy(QImageScaleInfo *isi, QRgba64 *dest,
+ int dw, int dh, int dow, int sow);
+
+static void qt_qimageScaleRgba64_up_xy(QImageScaleInfo *isi, QRgba64 *dest,
+ int dw, int dh, int dow, int sow)
+{
+ const QRgba64 **ypoints = (const QRgba64 **)isi->ypoints;
+ int *xpoints = isi->xpoints;
+ int *xapoints = isi->xapoints;
+ int *yapoints = isi->yapoints;
+
+ for (int y = 0; y < dh; y++) {
+ const QRgba64 *sptr = ypoints[y];
+ QRgba64 *dptr = dest + (y * dow);
+ const int yap = yapoints[y];
+ if (yap > 0) {
+ for (int x = 0; x < dw; x++) {
+ const QRgba64 *pix = sptr + xpoints[x];
+ const int xap = xapoints[x];
+ if (xap > 0)
+ *dptr = interpolate_4_pixels_rgb64(pix, pix + sow, xap * 256, yap * 256);
+ else
+ *dptr = interpolate256(pix[0], 256 - yap, pix[sow], yap);
+ dptr++;
+ }
+ } else {
+ for (int x = 0; x < dw; x++) {
+ const QRgba64 *pix = sptr + xpoints[x];
+ const int xap = xapoints[x];
+ *dptr = interpolate256(pix[0], 256 - xap, pix[1], xap);
+ dptr++;
+ }
+ }
+ }
+}
+
+void qt_qimageScaleRgba64(QImageScaleInfo *isi, QRgba64 *dest,
+ int dw, int dh, int dow, int sow)
+{
+ if (isi->xup_yup == 3)
+ qt_qimageScaleRgba64_up_xy(isi, dest, dw, dh, dow, sow);
+ else if (isi->xup_yup == 1)
+ qt_qimageScaleRgba64_up_x_down_y(isi, dest, dw, dh, dow, sow);
+ else if (isi->xup_yup == 2)
+ qt_qimageScaleRgba64_down_x_up_y(isi, dest, dw, dh, dow, sow);
+ else
+ qt_qimageScaleRgba64_down_xy(isi, dest, dw, dh, dow, sow);
+}
+
+inline static void qt_qimageScaleRgba64_helper(const QRgba64 *pix, int xyap, int Cxy, int step, qint64 &r, qint64 &g, qint64 &b, qint64 &a)
+{
+ r = pix->red() * xyap;
+ g = pix->green() * xyap;
+ b = pix->blue() * xyap;
+ a = pix->alpha() * xyap;
+ int j;
+ for (j = (1 << 14) - xyap; j > Cxy; j -= Cxy ){
+ pix += step;
+ r += pix->red() * Cxy;
+ g += pix->green() * Cxy;
+ b += pix->blue() * Cxy;
+ a += pix->alpha() * Cxy;
+ }
+ pix += step;
+ r += pix->red() * j;
+ g += pix->green() * j;
+ b += pix->blue() * j;
+ a += pix->alpha() * j;
+}
+
+static void qt_qimageScaleRgba64_up_x_down_y(QImageScaleInfo *isi, QRgba64 *dest,
+ int dw, int dh, int dow, int sow)
+{
+ const QRgba64 **ypoints = (const QRgba64 **)isi->ypoints;
+ int *xpoints = isi->xpoints;
+ int *xapoints = isi->xapoints;
+ int *yapoints = isi->yapoints;
+
+ for (int y = 0; y < dh; y++) {
+ int Cy = (yapoints[y]) >> 16;
+ int yap = (yapoints[y]) & 0xffff;
+
+ QRgba64 *dptr = dest + (y * dow);
+ for (int x = 0; x < dw; x++) {
+ const QRgba64 *sptr = ypoints[y] + xpoints[x];
+ qint64 r, g, b, a;
+ qt_qimageScaleRgba64_helper(sptr, yap, Cy, sow, r, g, b, a);
+
+ int xap = xapoints[x];
+ if (xap > 0) {
+ qint64 rr, gg, bb, aa;
+ qt_qimageScaleRgba64_helper(sptr + 1, yap, Cy, sow, rr, gg, bb, aa);
+
+ r = r * (256 - xap);
+ g = g * (256 - xap);
+ b = b * (256 - xap);
+ a = a * (256 - xap);
+ r = (r + (rr * xap)) >> 8;
+ g = (g + (gg * xap)) >> 8;
+ b = (b + (bb * xap)) >> 8;
+ a = (a + (aa * xap)) >> 8;
+ }
+ *dptr++ = qRgba64(r >> 14, g >> 14, b >> 14, a >> 14);
+ }
+ }
+}
+
+static void qt_qimageScaleRgba64_down_x_up_y(QImageScaleInfo *isi, QRgba64 *dest,
+ int dw, int dh, int dow, int sow)
+{
+ const QRgba64 **ypoints = (const QRgba64 **)isi->ypoints;
+ int *xpoints = isi->xpoints;
+ int *xapoints = isi->xapoints;
+ int *yapoints = isi->yapoints;
+
+ for (int y = 0; y < dh; y++) {
+ QRgba64 *dptr = dest + (y * dow);
+ for (int x = 0; x < dw; x++) {
+ int Cx = xapoints[x] >> 16;
+ int xap = xapoints[x] & 0xffff;
+
+ const QRgba64 *sptr = ypoints[y] + xpoints[x];
+ qint64 r, g, b, a;
+ qt_qimageScaleRgba64_helper(sptr, xap, Cx, 1, r, g, b, a);
+
+ int yap = yapoints[y];
+ if (yap > 0) {
+ qint64 rr, gg, bb, aa;
+ qt_qimageScaleRgba64_helper(sptr + sow, xap, Cx, 1, rr, gg, bb, aa);
+
+ r = r * (256 - yap);
+ g = g * (256 - yap);
+ b = b * (256 - yap);
+ a = a * (256 - yap);
+ r = (r + (rr * yap)) >> 8;
+ g = (g + (gg * yap)) >> 8;
+ b = (b + (bb * yap)) >> 8;
+ a = (a + (aa * yap)) >> 8;
+ }
+ *dptr = qRgba64(r >> 14, g >> 14, b >> 14, a >> 14);
+ dptr++;
+ }
+ }
+}
+
+static void qt_qimageScaleRgba64_down_xy(QImageScaleInfo *isi, QRgba64 *dest,
+ int dw, int dh, int dow, int sow)
+{
+ const QRgba64 **ypoints = (const QRgba64 **)isi->ypoints;
+ int *xpoints = isi->xpoints;
+ int *xapoints = isi->xapoints;
+ int *yapoints = isi->yapoints;
+
+ for (int y = 0; y < dh; y++) {
+ int Cy = (yapoints[y]) >> 16;
+ int yap = (yapoints[y]) & 0xffff;
+
+ QRgba64 *dptr = dest + (y * dow);
+ for (int x = 0; x < dw; x++) {
+ int Cx = xapoints[x] >> 16;
+ int xap = xapoints[x] & 0xffff;
+
+ const QRgba64 *sptr = ypoints[y] + xpoints[x];
+ qint64 rx, gx, bx, ax;
+ qt_qimageScaleRgba64_helper(sptr, xap, Cx, 1, rx, gx, bx, ax);
+
+ qint64 r = rx * yap;
+ qint64 g = gx * yap;
+ qint64 b = bx * yap;
+ qint64 a = ax * yap;
+ int j;
+ for (j = (1 << 14) - yap; j > Cy; j -= Cy) {
+ sptr += sow;
+ qt_qimageScaleRgba64_helper(sptr, xap, Cx, 1, rx, gx, bx, ax);
+ r += rx * Cy;
+ g += gx * Cy;
+ b += bx * Cy;
+ a += ax * Cy;
+ }
+ sptr += sow;
+ qt_qimageScaleRgba64_helper(sptr, xap, Cx, 1, rx, gx, bx, ax);
+ r += rx * j;
+ g += gx * j;
+ b += bx * j;
+ a += ax * j;
+
+ *dptr = qRgba64(r >> 28, g >> 28, b >> 28, a >> 28);
+ dptr++;
+ }
+ }
+}
+
static void qt_qimageScaleAARGB_up_x_down_y(QImageScaleInfo *isi, unsigned int *dest,
int dw, int dh, int dow, int sow);
@@ -745,7 +943,10 @@ QImage qSmoothScaleImage(const QImage &src, int dw, int dh)
return QImage();
}
- if (src.hasAlphaChannel())
+ if (src.depth() > 32)
+ qt_qimageScaleRgba64(scaleinfo, (QRgba64 *)buffer.scanLine(0),
+ dw, dh, dw, src.bytesPerLine() / 8);
+ else if (src.hasAlphaChannel())
qt_qimageScaleAARGBA(scaleinfo, (unsigned int *)buffer.scanLine(0),
dw, dh, dw, src.bytesPerLine() / 4);
else
diff --git a/src/gui/painting/qrgba64_p.h b/src/gui/painting/qrgba64_p.h
index 1ed0e82182..b7e4d4d905 100644
--- a/src/gui/painting/qrgba64_p.h
+++ b/src/gui/painting/qrgba64_p.h
@@ -64,14 +64,6 @@ inline QRgba64 combineAlpha256(QRgba64 rgba64, uint alpha256)
return QRgba64::fromRgba64(rgba64.red(), rgba64.green(), rgba64.blue(), (rgba64.alpha() * alpha256) >> 8);
}
-inline QRgba64 multiplyAlpha256(QRgba64 rgba64, uint alpha256)
-{
- return QRgba64::fromRgba64((rgba64.red() * alpha256) >> 8,
- (rgba64.green() * alpha256) >> 8,
- (rgba64.blue() * alpha256) >> 8,
- (rgba64.alpha() * alpha256) >> 8);
-}
-
inline QRgba64 multiplyAlpha65535(QRgba64 rgba64, uint alpha65535)
{
return QRgba64::fromRgba64(qt_div_65535(rgba64.red() * alpha65535),
@@ -126,11 +118,6 @@ inline T multiplyAlpha255(T rgba64, uint alpha255)
#endif
}
-inline QRgba64 interpolate256(QRgba64 x, uint alpha1, QRgba64 y, uint alpha2)
-{
- return QRgba64::fromRgba64(multiplyAlpha256(x, alpha1) + multiplyAlpha256(y, alpha2));
-}
-
inline QRgba64 interpolate255(QRgba64 x, uint alpha1, QRgba64 y, uint alpha2)
{
return QRgba64::fromRgba64(multiplyAlpha255(x, alpha1) + multiplyAlpha255(y, alpha2));
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 6826f62b61..4e9b00f9c9 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -1043,19 +1043,31 @@ struct QBidiAlgorithm {
}
}
- bool process()
+ bool checkForBidi() const
{
- memset(analysis, 0, length * sizeof(QScriptAnalysis));
-
- bool hasBidi = (baseLevel != 0);
- if (!hasBidi) {
- for (int i = 0; i < length; ++i) {
- if (text[i].unicode() >= 0x590) {
- hasBidi = true;
+ if (baseLevel != 0)
+ return true;
+ for (int i = 0; i < length; ++i) {
+ if (text[i].unicode() >= 0x590) {
+ switch (text[i].direction()) {
+ case QChar::DirR: case QChar::DirAN:
+ case QChar::DirLRE: case QChar::DirLRO: case QChar::DirAL:
+ case QChar::DirRLE: case QChar::DirRLO: case QChar::DirPDF:
+ case QChar::DirLRI: case QChar::DirRLI: case QChar::DirFSI: case QChar::DirPDI:
+ return true;
+ default:
break;
}
}
}
+ return false;
+ }
+
+ bool process()
+ {
+ memset(analysis, 0, length * sizeof(QScriptAnalysis));
+
+ bool hasBidi = checkForBidi();
if (!hasBidi)
return false;
@@ -2071,7 +2083,6 @@ void QTextEngine::itemize() const
case QChar::Nbsp:
if (option.flags() & QTextOption::ShowTabsAndSpaces) {
analysis->flags = (*uc == QChar::Space) ? QScriptAnalysis::Space : QScriptAnalysis::Nbsp;
- analysis->bidiLevel = bidi.baseLevel;
break;
}
Q_FALLTHROUGH();
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index bba7d044f7..e29e5b8187 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -378,6 +378,11 @@ void QWindowsContext::setTabletAbsoluteRange(int a)
#endif
}
+void QWindowsContext::setDetectAltGrModifier(bool a)
+{
+ d->m_keyMapper.setDetectAltGrModifier(a);
+}
+
int QWindowsContext::processDpiAwareness()
{
int result;
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index fe83c83934..3709d9deee 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -208,6 +208,8 @@ public:
void setProcessDpiAwareness(QtWindows::ProcessDpiAwareness dpiAwareness);
static int processDpiAwareness();
+ void setDetectAltGrModifier(bool a);
+
// Returns a combination of SystemInfoFlags
unsigned systemInfo() const;
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 1a1d51cae1..4824de5c9c 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -198,6 +198,8 @@ static inline unsigned parseOptions(const QStringList &paramList,
} else if (param.endsWith(QLatin1String("none"))) {
options |= QWindowsIntegration::NoNativeDialogs;
}
+ } else if (param == QLatin1String("altgr")) {
+ options |= QWindowsIntegration::DetectAltGrModifier;
} else if (param == QLatin1String("gl=gdi")) {
options |= QWindowsIntegration::DisableArb;
} else if (param == QLatin1String("nodirectwrite")) {
@@ -269,6 +271,7 @@ QWindowsIntegration::QWindowsIntegration(const QStringList &paramList) :
d->m_clipboard.registerViewer();
#endif
d->m_context.screenManager().handleScreenChanges();
+ d->m_context.setDetectAltGrModifier((d->m_options & DetectAltGrModifier) != 0);
}
QWindowsIntegration::~QWindowsIntegration()
diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h
index 25f485679d..da86852766 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.h
+++ b/src/plugins/platforms/windows/qwindowsintegration.h
@@ -69,6 +69,7 @@ public:
AlwaysUseNativeMenus = 0x100,
NoNativeMenus = 0x200,
DontUseWMPointer = 0x400,
+ DetectAltGrModifier = 0x800
};
explicit QWindowsIntegration(const QStringList &paramList);
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index e7efd6e057..1209b6c4b4 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -672,6 +672,7 @@ void QWindowsKeyMapper::changeKeyboard()
bidi = true;
keyboardInputDirection = bidi ? Qt::RightToLeft : Qt::LeftToRight;
+ m_seenAltGr = false;
}
// Helper function that is used when obtaining the list of characters that can be produced by one key and
@@ -906,8 +907,34 @@ bool QWindowsKeyMapper::translateMultimediaKeyEventInternal(QWindow *window, con
#endif
}
-bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &msg, bool /* grab */, LRESULT *lResult)
+// QTBUG-69317: Check for AltGr found on some keyboards
+// which is a sequence of left Ctrl (SYSKEY) + right Menu (Alt).
+static bool isAltGr(MSG *msg)
{
+ enum : LONG_PTR { RightFlag = 0x1000000 };
+ if (msg->wParam != VK_CONTROL || (msg->lParam & RightFlag) != 0
+ || (msg->message != WM_KEYDOWN && msg->message != WM_SYSKEYUP)) {
+ return false;
+ }
+ const UINT expectedMessage = msg->message == WM_SYSKEYUP
+ ? WM_KEYUP : msg->message;
+ MSG peekedMsg;
+ if (PeekMessage(&peekedMsg, msg->hwnd, 0, 0, PM_NOREMOVE) == FALSE
+ || peekedMsg.message != expectedMessage || peekedMsg.wParam != VK_MENU
+ || (peekedMsg.lParam & RightFlag) == 0) {
+ return false;
+ }
+ *msg = peekedMsg;
+ PeekMessage(&peekedMsg, msg->hwnd, 0, 0, PM_REMOVE);
+ return true;
+}
+
+bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, MSG msg,
+ bool /* grab */, LRESULT *lResult)
+{
+ const bool altGr = m_detectAltGrModifier && isAltGr(&msg);
+ if (altGr)
+ m_seenAltGr = true;
const UINT msgType = msg.message;
const quint32 scancode = (msg.lParam >> 16) & scancodeBitmask;
@@ -936,10 +963,12 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms
// Get the modifier states (may be altered later, depending on key code)
int state = 0;
state |= (nModifiers & ShiftAny ? int(Qt::ShiftModifier) : 0);
- state |= (nModifiers & ControlAny ? int(Qt::ControlModifier) : 0);
- state |= (nModifiers & AltAny ? int(Qt::AltModifier) : 0);
+ state |= (nModifiers & AltLeft ? int(Qt::AltModifier) : 0);
+ if ((nModifiers & AltRight) != 0)
+ state |= m_seenAltGr ? Qt::GroupSwitchModifier : Qt::AltModifier;
+ if ((nModifiers & ControlAny) != 0 && (state & Qt::GroupSwitchModifier) == 0)
+ state |= Qt::ControlModifier;
state |= (nModifiers & MetaAny ? int(Qt::MetaModifier) : 0);
-
// A multi-character key or a Input method character
// not found by our look-ahead
if (msgType == WM_CHAR || msgType == WM_IME_CHAR) {
@@ -1010,8 +1039,17 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms
modifiersIndex |= (nModifiers & ControlAny ? 0x2 : 0);
modifiersIndex |= (nModifiers & AltAny ? 0x4 : 0);
+ // Note: For the resulting key, AltGr is equivalent to Alt + Ctrl (as
+ // opposed to Linux); hence no entry in KeyboardLayoutItem is required
int code = keyLayout[vk_key].qtKey[modifiersIndex];
+ // If the bit 24 of lParm is set you received a enter,
+ // otherwise a Return. (This is the extended key bit)
+ if ((code == Qt::Key_Return) && (msg.lParam & 0x1000000))
+ code = Qt::Key_Enter;
+ else if (altGr)
+ code = Qt::Key_AltGr;
+
// Invert state logic:
// If the key actually pressed is a modifier key, then we remove its modifier key from the
// state, since a modifier-key can't have itself as a modifier
@@ -1021,11 +1059,8 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms
state = state ^ Qt::ShiftModifier;
else if (code == Qt::Key_Alt)
state = state ^ Qt::AltModifier;
-
- // If the bit 24 of lParm is set you received a enter,
- // otherwise a Return. (This is the extended key bit)
- if ((code == Qt::Key_Return) && (msg.lParam & 0x1000000))
- code = Qt::Key_Enter;
+ else if (code == Qt::Key_AltGr)
+ state = state ^ Qt::GroupSwitchModifier;
// All cursor keys without extended bit
if (!(msg.lParam & 0x1000000)) {
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.h b/src/plugins/platforms/windows/qwindowskeymapper.h
index d569c82437..a454f0f973 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.h
+++ b/src/plugins/platforms/windows/qwindowskeymapper.h
@@ -81,6 +81,9 @@ public:
void setUseRTLExtensions(bool e) { m_useRTLExtensions = e; }
bool useRTLExtensions() const { return m_useRTLExtensions; }
+ void setDetectAltGrModifier(bool a) { m_detectAltGrModifier = a; }
+ bool detectAltGrModifier() const { return m_detectAltGrModifier; }
+
bool translateKeyEvent(QWindow *widget, HWND hwnd, const MSG &msg, LRESULT *result);
QWindow *keyGrabber() const { return m_keyGrabber; }
@@ -90,7 +93,7 @@ public:
QList<int> possibleKeys(const QKeyEvent *e) const;
private:
- bool translateKeyEventInternal(QWindow *receiver, const MSG &msg, bool grab, LRESULT *lResult);
+ bool translateKeyEventInternal(QWindow *receiver, MSG msg, bool grab, LRESULT *lResult);
bool translateMultimediaKeyEventInternal(QWindow *receiver, const MSG &msg);
void updateKeyMap(const MSG &msg);
@@ -106,6 +109,9 @@ private:
QChar m_lastHighSurrogate;
static const size_t NumKeyboardLayoutItems = 256;
KeyboardLayoutItem keyLayout[NumKeyboardLayoutItems];
+ bool m_detectAltGrModifier = false;
+ bool m_seenAltGr = false;
+
};
enum WindowsNativeModifiers {
diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp
index c4ee820211..6af9f168a5 100644
--- a/src/plugins/platforms/windows/qwindowsopengltester.cpp
+++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp
@@ -60,6 +60,8 @@
QT_BEGIN_NAMESPACE
+static const DWORD VENDOR_ID_AMD = 0x1002;
+
GpuDescription GpuDescription::detect()
{
typedef IDirect3D9 * (WINAPI *PtrDirect3DCreate9)(UINT);
@@ -74,9 +76,16 @@ GpuDescription GpuDescription::detect()
IDirect3D9 *direct3D9 = direct3DCreate9(D3D_SDK_VERSION);
if (!direct3D9)
return result;
+
D3DADAPTER_IDENTIFIER9 adapterIdentifier;
- const HRESULT hr = direct3D9->GetAdapterIdentifier(0, 0, &adapterIdentifier);
- direct3D9->Release();
+ bool isAMD = false;
+ // Adapter "0" is D3DADAPTER_DEFAULT which returns the default adapter. In
+ // multi-GPU, multi-screen setups this is the GPU that is associated with
+ // the "main display" in the Display Settings, and this is the GPU OpenGL
+ // and D3D uses by default. Therefore querying any additional adapters is
+ // futile and not useful for our purposes in general, except for
+ // identifying a few special cases later on.
+ HRESULT hr = direct3D9->GetAdapterIdentifier(0, 0, &adapterIdentifier);
if (SUCCEEDED(hr)) {
result.vendorId = adapterIdentifier.VendorId;
result.deviceId = adapterIdentifier.DeviceId;
@@ -90,7 +99,37 @@ GpuDescription GpuDescription::detect()
result.driverVersion = QVersionNumber(version);
result.driverName = adapterIdentifier.Driver;
result.description = adapterIdentifier.Description;
+ isAMD = result.vendorId == VENDOR_ID_AMD;
}
+
+ // Detect QTBUG-50371 (having AMD as the default adapter results in a crash
+ // when starting apps on a screen connected to the Intel card) by looking
+ // for a default AMD adapter and an additional non-AMD one.
+ if (isAMD) {
+ const UINT adapterCount = direct3D9->GetAdapterCount();
+ for (UINT adp = 1; adp < adapterCount; ++adp) {
+ hr = direct3D9->GetAdapterIdentifier(adp, 0, &adapterIdentifier);
+ if (SUCCEEDED(hr)) {
+ if (adapterIdentifier.VendorId != VENDOR_ID_AMD) {
+ // Bingo. Now figure out the display for the AMD card.
+ DISPLAY_DEVICE dd;
+ memset(&dd, 0, sizeof(dd));
+ dd.cb = sizeof(dd);
+ for (int dev = 0; EnumDisplayDevices(nullptr, dev, &dd, 0); ++dev) {
+ if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) {
+ // DeviceName is something like \\.\DISPLAY1 which can be used to
+ // match with the MONITORINFOEX::szDevice queried by QWindowsScreen.
+ result.gpuSuitableScreen = QString::fromWCharArray(dd.DeviceName);
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ direct3D9->Release();
return result;
}
@@ -103,7 +142,8 @@ QDebug operator<<(QDebug d, const GpuDescription &gd)
<< ", deviceId=" << gd.deviceId << ", subSysId=" << gd.subSysId
<< dec << noshowbase << ", revision=" << gd.revision
<< ", driver: " << gd.driverName
- << ", version=" << gd.driverVersion << ", " << gd.description << ')';
+ << ", version=" << gd.driverVersion << ", " << gd.description
+ << gd.gpuSuitableScreen << ')';
return d;
}
#endif // !QT_NO_DEBUG_STREAM
@@ -113,15 +153,17 @@ QString GpuDescription::toString() const
{
QString result;
QTextStream str(&result);
- str << " Card name: " << description
- << "\n Driver Name: " << driverName
- << "\n Driver Version: " << driverVersion.toString()
- << "\n Vendor ID: 0x" << qSetPadChar(QLatin1Char('0'))
+ str << " Card name : " << description
+ << "\n Driver Name : " << driverName
+ << "\n Driver Version : " << driverVersion.toString()
+ << "\n Vendor ID : 0x" << qSetPadChar(QLatin1Char('0'))
<< uppercasedigits << hex << qSetFieldWidth(4) << vendorId
- << "\n Device ID: 0x" << qSetFieldWidth(4) << deviceId
- << "\n SubSys ID: 0x" << qSetFieldWidth(8) << subSysId
- << "\n Revision ID: 0x" << qSetFieldWidth(4) << revision
+ << "\n Device ID : 0x" << qSetFieldWidth(4) << deviceId
+ << "\n SubSys ID : 0x" << qSetFieldWidth(8) << subSysId
+ << "\n Revision ID : 0x" << qSetFieldWidth(4) << revision
<< dec;
+ if (!gpuSuitableScreen.isEmpty())
+ str << "\nGL windows forced to screen: " << gpuSuitableScreen;
return result;
}
diff --git a/src/plugins/platforms/windows/qwindowsopengltester.h b/src/plugins/platforms/windows/qwindowsopengltester.h
index 5ee2508462..22170f30b0 100644
--- a/src/plugins/platforms/windows/qwindowsopengltester.h
+++ b/src/plugins/platforms/windows/qwindowsopengltester.h
@@ -62,6 +62,7 @@ struct GpuDescription
QVersionNumber driverVersion;
QByteArray driverName;
QByteArray description;
+ QString gpuSuitableScreen;
};
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 528927b0fb..9c31409644 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -58,6 +58,7 @@
#else
# include "qwindowsopenglcontext.h"
#endif
+#include "qwindowsopengltester.h"
#ifdef QT_NO_CURSOR
# include "qwindowscursor.h"
#endif
@@ -541,6 +542,84 @@ static inline void fixTopLevelWindowFlags(Qt::WindowFlags &flags)
flags |= Qt::FramelessWindowHint;
}
+static QScreen *screenForName(const QWindow *w, const QString &name)
+{
+ QScreen *winScreen = w ? w->screen() : QGuiApplication::primaryScreen();
+ if (winScreen && winScreen->name() != name) {
+ const auto screens = winScreen->virtualSiblings();
+ for (QScreen *screen : screens) {
+ if (screen->name() == name)
+ return screen;
+ }
+ }
+ return winScreen;
+}
+
+static QScreen *forcedScreenForGLWindow(const QWindow *w)
+{
+ const QString forceToScreen = GpuDescription::detect().gpuSuitableScreen;
+ return forceToScreen.isEmpty() ? nullptr : screenForName(w, forceToScreen);
+}
+
+static QPoint calcPosition(const QWindow *w, const QWindowCreationContextPtr &context, const QMargins &invMargins)
+{
+ const QPoint orgPos(context->frameX - invMargins.left(), context->frameY - invMargins.top());
+
+ if (!w || (!w->isTopLevel() && w->surfaceType() != QWindow::OpenGLSurface))
+ return orgPos;
+
+ // Workaround for QTBUG-50371
+ const QScreen *screenForGL = forcedScreenForGLWindow(w);
+ if (!screenForGL)
+ return orgPos;
+
+ const QPoint posFrame(context->frameX, context->frameY);
+ const QMargins margins = context->margins;
+ const QRect scrGeo = screenForGL->handle()->availableGeometry();
+
+ // Point is already in the required screen.
+ if (scrGeo.contains(orgPos))
+ return orgPos;
+
+ // If the visible part of the window is already in the
+ // required screen, just ignore the invisible offset.
+ if (scrGeo.contains(posFrame))
+ return posFrame;
+
+ // Find the original screen containing the coordinates.
+ const QList<QScreen *> screens = screenForGL->virtualSiblings();
+ const QScreen *orgScreen = nullptr;
+ for (QScreen *screen : screens) {
+ if (screen->handle()->availableGeometry().contains(posFrame)) {
+ orgScreen = screen;
+ break;
+ }
+ }
+ const QPoint ctPos = QPoint(qMax(scrGeo.left(), scrGeo.center().x()
+ + (margins.right() - margins.left() - context->frameWidth)/2),
+ qMax(scrGeo.top(), scrGeo.center().y()
+ + (margins.bottom() - margins.top() - context->frameHeight)/2));
+
+ // If initial coordinates were outside all screens, center the window on the required screen.
+ if (!orgScreen)
+ return ctPos;
+
+ const QRect orgGeo = orgScreen->handle()->availableGeometry();
+ const QRect orgFrame(QPoint(context->frameX, context->frameY),
+ QSize(context->frameWidth, context->frameHeight));
+
+ // Window would be centered on orgScreen. Center it on the required screen.
+ if (orgGeo.center() == (orgFrame - margins).center())
+ return ctPos;
+
+ // Transform the coordinates to map them into the required screen.
+ const QPoint newPos(scrGeo.left() + ((posFrame.x() - orgGeo.left()) * scrGeo.width()) / orgGeo.width(),
+ scrGeo.top() + ((posFrame.y() - orgGeo.top()) * scrGeo.height()) / orgGeo.height());
+ const QPoint newPosNoMargin(newPos.x() - invMargins.left(), newPos.y() - invMargins.top());
+
+ return scrGeo.contains(newPosNoMargin) ? newPosNoMargin : newPos;
+}
+
void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flagsIn,
unsigned creationFlags)
{
@@ -688,9 +767,12 @@ QWindowsWindowData
<< " custom margins: " << context->customMargins
<< " invisible margins: " << invMargins;
+
+ QPoint pos = calcPosition(w, context, invMargins);
+
result.hwnd = CreateWindowEx(exStyle, classNameUtf16, titleUtf16,
style,
- context->frameX - invMargins.left(), context->frameY - invMargins.top(),
+ pos.x(), pos.y(),
context->frameWidth, context->frameHeight,
parentHandle, NULL, appinst, NULL);
qCDebug(lcQpaWindows).nospace()
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp
index 11397fb9ec..7a91c3d4e2 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp
@@ -180,7 +180,7 @@ long roleToControlTypeId(QAccessible::Role role)
{QAccessible::PropertyPage, UIA_CustomControlTypeId},
{QAccessible::Indicator, UIA_CustomControlTypeId},
{QAccessible::Graphic, UIA_ImageControlTypeId},
- {QAccessible::StaticText, UIA_EditControlTypeId},
+ {QAccessible::StaticText, UIA_TextControlTypeId},
{QAccessible::EditableText, UIA_EditControlTypeId},
{QAccessible::Button, UIA_ButtonControlTypeId},
{QAccessible::CheckBox, UIA_CheckBoxControlTypeId},
diff --git a/src/plugins/printsupport/cups/qcupsprintersupport.cpp b/src/plugins/printsupport/cups/qcupsprintersupport.cpp
index 56191c4dec..19e1df31f6 100644
--- a/src/plugins/printsupport/cups/qcupsprintersupport.cpp
+++ b/src/plugins/printsupport/cups/qcupsprintersupport.cpp
@@ -47,12 +47,14 @@
#include <QtPrintSupport/QPrinterInfo>
+#if QT_CONFIG(dialogbuttonbox)
#include <QGuiApplication>
#include <QDialog>
#include <QDialogButtonBox>
#include <QFormLayout>
#include <QLabel>
#include <QLineEdit>
+#endif // QT_CONFIG(dialogbuttonbox)
#include <cups/ppd.h>
#ifndef QT_LINUXBASE // LSB merges everything into cups.h
@@ -61,6 +63,7 @@
QT_BEGIN_NAMESPACE
+#if QT_CONFIG(dialogbuttonbox)
static const char *getPasswordCB(const char */*prompt*/, http_t *http, const char */*method*/, const char *resource, void */*user_data*/)
{
// cups doesn't free the const char * we return so keep around
@@ -122,13 +125,16 @@ static const char *getPasswordCB(const char */*prompt*/, http_t *http, const cha
return password.constData();
}
+#endif // QT_CONFIG(dialogbuttonbox)
QCupsPrinterSupport::QCupsPrinterSupport()
: QPlatformPrinterSupport()
{
+#if QT_CONFIG(dialogbuttonbox)
// Only show password dialog if GUI application
if (qobject_cast<QGuiApplication*>(QCoreApplication::instance()))
cupsSetPasswordCB2(getPasswordCB, nullptr /* user_data */ );
+#endif // QT_CONFIG(dialogbuttonbox)
}
QCupsPrinterSupport::~QCupsPrinterSupport()
diff --git a/src/testlib/3rdparty/qt_attribution.json b/src/testlib/3rdparty/qt_attribution.json
index 47625634e5..18522b6cd8 100644
--- a/src/testlib/3rdparty/qt_attribution.json
+++ b/src/testlib/3rdparty/qt_attribution.json
@@ -8,6 +8,7 @@
"Description": "An instrumentation framework for building dynamic analysis tools.",
"Homepage": "http://valgrind.org/",
+ "Version": "3.3.0",
"License": "BSD 4-clause \"Original\" or \"Old\" License",
"LicenseId": "BSD-4-Clause",
"LicenseFile": "VALGRIND_LICENSE.txt",
@@ -36,6 +37,8 @@ Copyright (c) 2003, 2006 Massachusetts Institute of Technology"
"Files": "linux_perf_event_p.h",
"Description": "Allows access to the Linux kernel's performance events.",
+ "Homepage": "https://www.kernel.org",
+ "Version": "3.7",
"License": "GNU General Public License v2.0 only with Linux Syscall Note",
"LicenseId": "GPL-2.0 WITH Linux-syscall-note",
"LicenseFile": "LINUX_LICENSE.txt",
diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp
index 29681bf5ce..3b78d2487f 100644
--- a/src/tools/androiddeployqt/main.cpp
+++ b/src/tools/androiddeployqt/main.cpp
@@ -95,6 +95,7 @@ struct Options
, generateAssetsFileList(true)
, build(true)
, gradle(false)
+ , auxMode(false)
, deploymentMechanism(Bundled)
, releasePackage(false)
, digestAlg(QLatin1String("SHA1"))
@@ -126,6 +127,7 @@ struct Options
bool generateAssetsFileList;
bool build;
bool gradle;
+ bool auxMode;
QTime timer;
// External tools
@@ -432,6 +434,8 @@ Options parseOptions()
options.jarSigner = true;
} else if (argument.compare(QLatin1String("--no-generated-assets-cache"), Qt::CaseInsensitive) == 0) {
options.generateAssetsFileList = false;
+ } else if (argument.compare(QLatin1String("--aux-mode"), Qt::CaseInsensitive) == 0) {
+ options.auxMode = true;
}
}
@@ -517,6 +521,9 @@ void printHelp()
" --verbose: Prints out information during processing.\n"
" --no-generated-assets-cache: Do not pregenerate the entry list for\n"
" the assets file engine.\n"
+ " --aux-mode: Operate in auxiliary mode. This will only copy the\n"
+ " dependencies into the build directory and update the XML templates.\n"
+ " The project will not be built or installed.\n"
" --help: Displays this information.\n\n",
qPrintable(QCoreApplication::arguments().at(0))
);
@@ -2826,6 +2833,22 @@ int main(int argc, char *argv[])
: "No"
);
+ if (options.auxMode) {
+ if (!readDependencies(&options))
+ return CannotReadDependencies;
+ if (!copyQtFiles(&options))
+ return CannotCopyQtFiles;
+ if (!copyAndroidExtraResources(options))
+ return CannotCopyAndroidExtraResources;
+ if (!stripLibraries(options))
+ return CannotStripLibraries;
+ if (!updateAndroidFiles(options))
+ return CannotUpdateAndroidFiles;
+ if (options.generateAssetsFileList && !generateAssetsFileList(options))
+ return CannotGenerateAssetsFileList;
+ return 0;
+ }
+
if (options.build) {
if (options.gradle)
cleanAndroidFiles(options);
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index 2742b152f2..9116bf61fe 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -1047,10 +1047,15 @@ void QFileDialog::selectFile(const QString &filename)
return;
if (!d->usingWidgets()) {
- QUrl url = QUrl::fromLocalFile(filename);
+ QUrl url;
if (QFileInfo(filename).isRelative()) {
- QDir dir(d->options->initialDirectory().toLocalFile());
- url = QUrl::fromLocalFile(dir.absoluteFilePath(filename));
+ url = d->options->initialDirectory();
+ QString path = url.path();
+ if (!path.endsWith(QLatin1Char('/')))
+ path += QLatin1Char('/');
+ url.setPath(path + filename);
+ } else {
+ url = QUrl::fromLocalFile(filename);
}
d->selectFile_sys(url);
d->options->setInitiallySelectedFiles(QList<QUrl>() << url);
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index 1c73588b7c..1a2ac4a4dd 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -977,7 +977,10 @@ void QWidgetWindow::handleExposeEvent(QExposeEvent *event)
}
if (exposed) {
+ // QTBUG-39220, QTBUG-58575: set all (potentially fully obscured parent widgets) mapped.
m_widget->setAttribute(Qt::WA_Mapped);
+ for (QWidget *p = m_widget->parentWidget(); p && !p->testAttribute(Qt::WA_Mapped); p = p->parentWidget())
+ p->setAttribute(Qt::WA_Mapped);
if (!event->region().isNull())
wPriv->syncBackingStore(event->region());
} else {
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp
index 94c3fa6e46..646f96c3a1 100644
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp
@@ -4662,4 +4662,236 @@ void tst_QSortFilterProxyModel::checkSetNewModel()
QCoreApplication::processEvents();
}
+enum ColumnFilterMode {
+ FilterNothing,
+ FilterOutMiddle,
+ FilterOutBeginEnd,
+ FilterAll
+};
+Q_DECLARE_METATYPE(ColumnFilterMode)
+
+void tst_QSortFilterProxyModel::filterAndInsertColumn_data()
+{
+
+ QTest::addColumn<int>("insertCol");
+ QTest::addColumn<ColumnFilterMode>("filterMode");
+ QTest::addColumn<QStringList>("expectedModelList");
+ QTest::addColumn<QStringList>("expectedProxyModelList");
+
+ QTest::newRow("at_beginning_filter_out_middle")
+ << 0
+ << FilterOutMiddle
+ << QStringList{{"", "A1", "B1", "C1", "D1"}}
+ << QStringList{{"", "D1"}}
+ ;
+ QTest::newRow("at_end_filter_out_middle")
+ << 2
+ << FilterOutMiddle
+ << QStringList{{"A1", "B1", "C1", "D1", ""}}
+ << QStringList{{"A1", ""}}
+ ;
+ QTest::newRow("in_the_middle_filter_out_middle")
+ << 1
+ << FilterOutMiddle
+ << QStringList{{"A1", "B1", "C1", "", "D1"}}
+ << QStringList{{"A1", "D1"}}
+ ;
+ QTest::newRow("at_beginning_filter_out_begin_and_end")
+ << 0
+ << FilterOutBeginEnd
+ << QStringList{{"A1", "", "B1", "C1", "D1"}}
+ << QStringList{{"", "B1", "C1"}}
+ ;
+ QTest::newRow("at_end_filter_out_begin_and_end")
+ << 2
+ << FilterOutBeginEnd
+ << QStringList{{"A1", "B1", "C1", "D1", ""}}
+ << QStringList{{"B1", "C1", "D1"}}
+ ;
+ QTest::newRow("in_the_middle_filter_out_begin_and_end")
+ << 1
+ << FilterOutBeginEnd
+ << QStringList{{"A1", "B1", "", "C1", "D1"}}
+ << QStringList{{"B1", "", "C1"}}
+ ;
+
+ QTest::newRow("at_beginning_filter_nothing")
+ << 0
+ << FilterAll
+ << QStringList{{"", "A1", "B1", "C1", "D1"}}
+ << QStringList{{"", "A1", "B1", "C1", "D1"}}
+ ;
+ QTest::newRow("at_end_filter_nothing")
+ << 4
+ << FilterAll
+ << QStringList{{"A1", "B1", "C1", "D1", ""}}
+ << QStringList{{"A1", "B1", "C1", "D1", ""}}
+ ;
+ QTest::newRow("in_the_middle_nothing")
+ << 2
+ << FilterAll
+ << QStringList{{"A1", "B1", "", "C1", "D1"}}
+ << QStringList{{"A1", "B1", "", "C1", "D1"}}
+ ;
+
+ QTest::newRow("filter_all")
+ << 0
+ << FilterNothing
+ << QStringList{{"A1", "B1", "C1", "D1", ""}}
+ << QStringList{}
+ ;
+}
+void tst_QSortFilterProxyModel::filterAndInsertColumn()
+{
+
+ class ColumnFilterProxy : public QSortFilterProxyModel {
+ Q_DISABLE_COPY(ColumnFilterProxy)
+ ColumnFilterMode filerMode;
+ public:
+ ColumnFilterProxy(ColumnFilterMode mode)
+ : filerMode(mode)
+ {}
+ bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const override
+ {
+ Q_UNUSED(source_parent)
+ switch (filerMode){
+ case FilterAll:
+ return true;
+ case FilterNothing:
+ return false;
+ case FilterOutMiddle:
+ return source_column == 0 || source_column == sourceModel()->columnCount() - 1;
+ case FilterOutBeginEnd:
+ return source_column > 0 && source_column< sourceModel()->columnCount() - 1;
+ }
+ Q_UNREACHABLE();
+ }
+ };
+ QFETCH(int, insertCol);
+ QFETCH(ColumnFilterMode, filterMode);
+ QFETCH(QStringList, expectedModelList);
+ QFETCH(QStringList, expectedProxyModelList);
+ QStandardItemModel model;
+ model.insertColumns(0, 4);
+ model.insertRows(0, 1);
+ for (int i = 0; i < model.rowCount(); ++i) {
+ for (int j = 0; j < model.columnCount(); ++j)
+ model.setData(model.index(i, j), QString('A' + j) + QString::number(i + 1));
+ }
+ ColumnFilterProxy proxy(filterMode);
+ proxy.setSourceModel(&model);
+ QVERIFY(proxy.insertColumn(insertCol));
+ proxy.invalidate();
+ QStringList modelStringList;
+ for (int i = 0; i < model.rowCount(); ++i) {
+ for (int j = 0; j < model.columnCount(); ++j)
+ modelStringList.append(model.index(i, j).data().toString());
+ }
+ QCOMPARE(expectedModelList, modelStringList);
+ modelStringList.clear();
+ for (int i = 0; i < proxy.rowCount(); ++i) {
+ for (int j = 0; j < proxy.columnCount(); ++j)
+ modelStringList.append(proxy.index(i, j).data().toString());
+ }
+ QCOMPARE(expectedProxyModelList, modelStringList);
+}
+
+void tst_QSortFilterProxyModel::filterAndInsertRow_data()
+{
+ QTest::addColumn<QStringList>("initialModelList");
+ QTest::addColumn<int>("row");
+ QTest::addColumn<QString>("filterRegExp");
+ QTest::addColumn<QStringList>("expectedModelList");
+ QTest::addColumn<QStringList>("expectedProxyModelList");
+
+ QTest::newRow("at_beginning_filter_out_middle")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 0
+ << "^A"
+ << QStringList{{"", "A5", "B5", "B6", "A7"}}
+ << QStringList{{"A5", "A7"}};
+ QTest::newRow("at_end_filter_out_middle")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 2
+ << "^A"
+ << QStringList{{"A5", "B5", "B6", "A7", ""}}
+ << QStringList{{"A5", "A7"}};
+ QTest::newRow("in_the_middle_filter_out_middle")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 1
+ << "^A"
+ << QStringList{{"A5", "B5", "B6", "", "A7"}}
+ << QStringList{{"A5", "A7"}};
+
+ QTest::newRow("at_beginning_filter_out_first_and_last")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 0
+ << "^B"
+ << QStringList{{"A5", "", "B5", "B6", "A7"}}
+ << QStringList{{"B5", "B6"}};
+ QTest::newRow("at_end_filter_out_first_and_last")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 2
+ << "^B"
+ << QStringList{{"A5", "B5", "B6", "A7", ""}}
+ << QStringList{{"B5", "B6"}};
+ QTest::newRow("in_the_middle_filter_out_first_and_last")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 1
+ << "^B"
+ << QStringList{{"A5", "B5", "", "B6", "A7"}}
+ << QStringList{{"B5", "B6"}};
+
+ QTest::newRow("at_beginning_no_filter")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 0
+ << ".*"
+ << QStringList{{"", "A5", "B5", "B6", "A7"}}
+ << QStringList{{"", "A5", "B5", "B6", "A7"}};
+ QTest::newRow("at_end_no_filter")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 4
+ << ".*"
+ << QStringList{{"A5", "B5", "B6", "A7", ""}}
+ << QStringList{{"A5", "B5", "B6", "A7", ""}};
+ QTest::newRow("in_the_middle_no_filter")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 2
+ << ".*"
+ << QStringList{{"A5", "B5", "", "B6", "A7"}}
+ << QStringList{{"A5", "B5", "", "B6", "A7"}};
+
+ QTest::newRow("filter_all")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 0
+ << "$a"
+ << QStringList{{"A5", "B5", "B6", "A7", ""}}
+ << QStringList{};
+}
+
+void tst_QSortFilterProxyModel::filterAndInsertRow()
+{
+ QFETCH(QStringList, initialModelList);
+ QFETCH(int, row);
+ QFETCH(QString, filterRegExp);
+ QFETCH(QStringList, expectedModelList);
+ QFETCH(QStringList, expectedProxyModelList);
+ QStringListModel model;
+ QSortFilterProxyModel proxyModel;
+
+ model.setStringList(initialModelList);
+ proxyModel.setSourceModel(&model);
+ proxyModel.setDynamicSortFilter(true);
+ proxyModel.setFilterRegExp(filterRegExp);
+
+ QVERIFY(proxyModel.insertRow(row));
+ QCOMPARE(model.stringList(), expectedModelList);
+ QCOMPARE(proxyModel.rowCount(), expectedProxyModelList.count());
+ for (int r = 0; r < proxyModel.rowCount(); ++r) {
+ QModelIndex index = proxyModel.index(r, 0);
+ QVERIFY(index.isValid());
+ QCOMPARE(proxyModel.data(index).toString(), expectedProxyModelList.at(r));
+ }
+}
+
#include "tst_qsortfilterproxymodel.moc"
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h
index 92f0b35065..4ea5e8fb6a 100644
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h
@@ -161,6 +161,10 @@ private slots:
void emitLayoutChangedOnlyIfSortingChanged();
void checkSetNewModel();
+ void filterAndInsertRow_data();
+ void filterAndInsertRow();
+ void filterAndInsertColumn_data();
+ void filterAndInsertColumn();
void removeIntervals_data();
void removeIntervals();
diff --git a/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST b/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST
index 402d87b82f..fb7e025b7c 100644
--- a/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST
+++ b/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST
@@ -4,3 +4,4 @@ osx
[registerTimer]
windows
osx
+winrt
diff --git a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp
index 79309f960d..0196dd2d23 100644
--- a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp
+++ b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp
@@ -423,7 +423,12 @@ void tst_QEasingCurve::setCustomType()
QCOMPARE(curve.valueForProgress(0.15), 0.1);
QCOMPARE(curve.valueForProgress(0.20), 0.2);
QCOMPARE(curve.valueForProgress(0.25), 0.2);
+ // QTBUG-69947, MinGW 7.3 returns 0.2
+#if defined(Q_CC_MINGW)
+#if !defined(__GNUC__) || __GNUC__ != 7 || __GNUC_MINOR__ < 3
QCOMPARE(curve.valueForProgress(0.30), 0.3);
+#endif
+#endif
QCOMPARE(curve.valueForProgress(0.35), 0.3);
QCOMPARE(curve.valueForProgress(0.999999), 0.9);
diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp
index 08aa00df56..5ffd75f931 100644
--- a/tests/auto/gui/image/qimage/tst_qimage.cpp
+++ b/tests/auto/gui/image/qimage/tst_qimage.cpp
@@ -120,6 +120,7 @@ private slots:
void smoothScale2();
void smoothScale3_data();
void smoothScale3();
+ void smoothScale4_data();
void smoothScale4();
void smoothScaleBig();
@@ -1681,29 +1682,30 @@ void tst_QImage::smoothScale()
// test area sampling
void tst_QImage::smoothScale2_data()
{
- QTest::addColumn<int>("format");
+ QTest::addColumn<QImage::Format>("format");
QTest::addColumn<int>("size");
int sizes[] = { 2, 3, 4, 6, 7, 8, 10, 16, 20, 32, 40, 64, 100, 101, 128, 0 };
- QImage::Format formats[] = { QImage::Format_RGB32, QImage::Format_ARGB32_Premultiplied, QImage::Format_Invalid };
+ QImage::Format formats[] = { QImage::Format_RGB32, QImage::Format_ARGB32_Premultiplied, QImage::Format_RGBX64, QImage::Format_RGBA64_Premultiplied, QImage::Format_Invalid };
for (int j = 0; formats[j] != QImage::Format_Invalid; ++j) {
- QByteArray formatstr = formats[j] == QImage::Format_RGB32 ? QByteArrayLiteral("rgb32") : QByteArrayLiteral("argb32pm");
+ QString formatstr = formatToString(formats[j]);
for (int i = 0; sizes[i] != 0; ++i) {
const QByteArray sizeB = QByteArray::number(sizes[i]);
- QTest::newRow((formatstr + ' ' + sizeB + 'x' + sizeB).constData())
- << (int)formats[j] << sizes[i];
+ QTest::newRow(QString("%1 %2x%2").arg(formatstr).arg(sizes[i]).toUtf8()) << formats[j] << sizes[i];
}
}
}
void tst_QImage::smoothScale2()
{
- QFETCH(int, format);
+ QFETCH(QImage::Format, format);
QFETCH(int, size);
- QRgb expected = format == QImage::Format_RGB32 ? qRgb(63, 127, 255) : qRgba(31, 63, 127, 127);
+ bool opaque = (format == QImage::Format_RGB32 || format == QImage::Format_RGBX64);
+
+ QRgb expected = opaque ? qRgb(63, 127, 255) : qRgba(31, 63, 127, 127);
- QImage img(size, size, (QImage::Format)format);
+ QImage img(size, size, format);
img.fill(expected);
// scale x down, y down
@@ -1840,21 +1842,31 @@ void tst_QImage::smoothScale3()
}
// Tests smooth upscale is smooth
+void tst_QImage::smoothScale4_data()
+{
+ QTest::addColumn<QImage::Format>("format");
+
+ QTest::newRow("RGB32") << QImage::Format_RGB32;
+ QTest::newRow("RGBx64") << QImage::Format_RGBX64;
+}
+
void tst_QImage::smoothScale4()
{
- QImage img(4, 4, QImage::Format_RGB32);
+ QFETCH(QImage::Format, format);
+ QImage img(4, 4, format);
for (int y = 0; y < 4; ++y) {
for (int x = 0; x < 4; ++x) {
img.setPixel(x, y, qRgb(x * 255 / 3, y * 255 / 3, 0));
}
}
QImage scaled = img.scaled(37, 23, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ QCOMPARE(scaled.format(), format);
for (int y = 0; y < scaled.height(); ++y) {
for (int x = 0; x < scaled.width(); ++x) {
if (x > 0)
- QVERIFY(qRed(scaled.pixel(x, y)) >= qRed(scaled.pixel(x - 1, y)));
+ QVERIFY(scaled.pixelColor(x, y).redF() >= scaled.pixelColor(x - 1, y).redF());
if (y > 0)
- QVERIFY(qGreen(scaled.pixel(x, y)) >= qGreen(scaled.pixel(x, y - 1)));
+ QVERIFY(scaled.pixelColor(x, y).greenF() >= scaled.pixelColor(x, y - 1).greenF());
}
}
}
diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
index a593deb90e..8b24937079 100644
--- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
+++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
@@ -3882,7 +3882,7 @@ void tst_QAccessibility::bridgeTest()
// Label
hr = nodeList.at(4)->get_CurrentControlType(&controlTypeId);
QVERIFY(SUCCEEDED(hr));
- QCOMPARE(controlTypeId, UIA_EditControlTypeId);
+ QCOMPARE(controlTypeId, UIA_TextControlTypeId);
for (auto nd : nodeList) {
nd->Release();
diff --git a/tests/auto/widgets/dialogs/qdialog/BLACKLIST b/tests/auto/widgets/dialogs/qdialog/BLACKLIST
index 3da7337784..dd6a8bfff9 100644
--- a/tests/auto/widgets/dialogs/qdialog/BLACKLIST
+++ b/tests/auto/widgets/dialogs/qdialog/BLACKLIST
@@ -1,2 +1,4 @@
[snapToDefaultButton]
osx
+[showFullScreen]
+osx-10.13 ci
diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST
index 0f207b421e..2be016e99b 100644
--- a/tests/auto/widgets/kernel/qwidget/BLACKLIST
+++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST
@@ -35,7 +35,7 @@ osx-10.11 ci
osx-10.12 ci
osx-10.13 ci
[maskedUpdate]
-opensuse-42.3
+opensuse
[moveInResizeEvent]
ubuntu-16.04
[moveChild:right]
diff --git a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp
index 2da04397d0..f4da4c3e5f 100644
--- a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp
+++ b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp
@@ -44,6 +44,8 @@
#include <qmainwindow.h>
#include <qtoolbar.h>
#include <private/qwindow_p.h>
+#include <private/qguiapplication_p.h>
+#include <qpa/qplatformintegration.h>
#include <QtTest/private/qtesthelpers_p.h>
@@ -79,6 +81,7 @@ private slots:
void tst_showWithoutActivating();
void tst_paintEventOnSecondShow();
+ void tst_exposeObscuredMapped_QTBUG39220();
void tst_paintEventOnResize_QTBUG50796();
#if QT_CONFIG(draganddrop)
@@ -377,6 +380,33 @@ void tst_QWidget_window::tst_paintEventOnSecondShow()
QTRY_VERIFY(w.paintEventCount > 0);
}
+void tst_QWidget_window::tst_exposeObscuredMapped_QTBUG39220()
+{
+ const auto integration = QGuiApplicationPrivate::platformIntegration();
+ if (!integration->hasCapability(QPlatformIntegration::MultipleWindows)
+ || !integration->hasCapability(QPlatformIntegration::NonFullScreenWindows)
+ || QGuiApplication::platformName() == QLatin1String("winrt")) {
+ QSKIP("The platform does not have the required capabilities");
+ }
+ // QTBUG-39220: Fully obscured parent widgets may not receive expose
+ // events (as is the case for frameless, obscured parents on Windows).
+ // Ensure Qt::WA_Mapped is set so updating works.
+ const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
+ const QSize size = availableGeometry.size() / 6;
+ QWidget topLevel;
+ setFrameless(&topLevel);
+ topLevel.resize(size);
+ const QPoint sizeP(size.width(), size.height());
+ topLevel.move(availableGeometry.center() - sizeP / 2);
+ QWidget *child = new QWidget(&topLevel);
+ child->resize(size);
+ child->move(0, 0);
+ QVERIFY(child->winId());
+ topLevel.show();
+ QTRY_VERIFY(child->testAttribute(Qt::WA_Mapped));
+ QVERIFY(topLevel.testAttribute(Qt::WA_Mapped));
+}
+
void tst_QWidget_window::tst_paintEventOnResize_QTBUG50796()
{
const QRect availableGeo = QGuiApplication::primaryScreen()->availableGeometry();