Merge remote-tracking branch 'origin/5.12' into dev
Change-Id: I1114f90a2ed04a784a66505960b0f2460778726dbb10
commit
b73f1cc045
|
|
@ -161,6 +161,7 @@
|
|||
},
|
||||
"sources": [
|
||||
{ "libs": "-lzdll", "condition": "config.msvc" },
|
||||
{ "libs": "-lzlib", "condition": "config.msvc" },
|
||||
{ "libs": "-lz", "condition": "!config.msvc" }
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
*/
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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": [
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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() << ')';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -198,6 +198,8 @@ static inline unsigned parseOptions(const QStringList ¶mList,
|
|||
} 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 ¶mList) :
|
|||
d->m_clipboard.registerViewer();
|
||||
#endif
|
||||
d->m_context.screenManager().handleScreenChanges();
|
||||
d->m_context.setDetectAltGrModifier((d->m_options & DetectAltGrModifier) != 0);
|
||||
}
|
||||
|
||||
QWindowsIntegration::~QWindowsIntegration()
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ public:
|
|||
AlwaysUseNativeMenus = 0x100,
|
||||
NoNativeMenus = 0x200,
|
||||
DontUseWMPointer = 0x400,
|
||||
DetectAltGrModifier = 0x800
|
||||
};
|
||||
|
||||
explicit QWindowsIntegration(const QStringList ¶mList);
|
||||
|
|
|
|||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ struct GpuDescription
|
|||
QVersionNumber driverVersion;
|
||||
QByteArray driverName;
|
||||
QByteArray description;
|
||||
QString gpuSuitableScreen;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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},
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -4,3 +4,4 @@ osx
|
|||
[registerTimer]
|
||||
windows
|
||||
osx
|
||||
winrt
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
QImage img(size, size, (QImage::Format)format);
|
||||
QRgb expected = opaque ? qRgb(63, 127, 255) : qRgba(31, 63, 127, 127);
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -1,2 +1,4 @@
|
|||
[snapToDefaultButton]
|
||||
osx
|
||||
[showFullScreen]
|
||||
osx-10.13 ci
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Reference in New Issue