From a8a05b00fc8401e518c70b5deffc383d1081ede3 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 24 Apr 2019 17:44:30 +0200 Subject: [PATCH 1/7] Document that QHostInfo does not guarantee to return all IP addresses Using getaddrinfo, which implements RFC 6724, implies that addresses that are not needed will be trimmed. In particular, IPv6 addresses are often not returned. Also move the implementation detail documentation down in the text, it's a detail with little relevance for the usage of the class, but makes for a good opener regarding this behavior. Change-Id: I516a64f0b39a6a06621a63c1d5236544b7758049 Fixes: QTBUG-31865 Reviewed-by: Thiago Macieira --- src/network/kernel/qhostinfo.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index 0973d0dd524..4d451dfdb76 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -137,8 +137,7 @@ void emit_results_ready(const QHostInfo &hostInfo, const QObject *receiver, \inmodule QtNetwork \ingroup network - QHostInfo uses the lookup mechanisms provided by the operating - system to find the IP address(es) associated with a host name, + QHostInfo finds the IP address(es) associated with a host name, or the host name associated with an IP address. The class provides two static convenience functions: one that works asynchronously and emits a signal once the host is found, @@ -173,6 +172,11 @@ void emit_results_ready(const QHostInfo &hostInfo, const QObject *receiver, To retrieve the name of the local host, use the static QHostInfo::localHostName() function. + QHostInfo uses the mechanisms provided by the operating system + to perform the lookup. As per {https://tools.ietf.org/html/rfc6724}{RFC 6724} + there is no guarantee that all IP addresses registered for a domain or + host will be returned. + \note Since Qt 4.6.1 QHostInfo is using multiple threads for DNS lookup instead of one dedicated DNS thread. This improves performance, but also changes the order of signal emissions when using lookupHost() @@ -180,7 +184,8 @@ void emit_results_ready(const QHostInfo &hostInfo, const QObject *receiver, \note Since Qt 4.6.3 QHostInfo is using a small internal 60 second DNS cache for performance improvements. - \sa QAbstractSocket, {http://www.rfc-editor.org/rfc/rfc3492.txt}{RFC 3492} + \sa QAbstractSocket, {http://www.rfc-editor.org/rfc/rfc3492.txt}{RFC 3492}, + {https://tools.ietf.org/html/rfc6724}{RFC 6724} */ static int nextId() From 78c84c6353257a477efc307e28f713ec70d2247a Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Tue, 9 Apr 2019 15:50:57 +0200 Subject: [PATCH 2/7] qdoc: Fix warnings about missing \inmodule command Fix warnings qtbase/src/corelib/io/qprocess.cpp:776: (qdoc) warning: Class CreateProcessArguments has no \inmodule command; using project name by default: QtCore qtbase/src/corelib/serialization/qcborstream.cpp:1441: (qdoc) warning: Class StringResult has no \inmodule command; using project name by default: QtCore Change-Id: I1c85ca32aff1f89f70898af7b11cfead96c80349 Reviewed-by: Leena Miettinen --- src/corelib/io/qprocess.cpp | 1 + src/corelib/serialization/qcborstream.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index e1f4a3a3114..7b2de02d1d0 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -775,6 +775,7 @@ void QProcessPrivate::Channel::clear() /*! \class QProcess::CreateProcessArguments + \inmodule QtCore \note This struct is only available on the Windows platform. This struct is a representation of all parameters of the Windows API diff --git a/src/corelib/serialization/qcborstream.cpp b/src/corelib/serialization/qcborstream.cpp index df38118805b..87ae316041d 100644 --- a/src/corelib/serialization/qcborstream.cpp +++ b/src/corelib/serialization/qcborstream.cpp @@ -1440,6 +1440,7 @@ bool QCborStreamWriter::endMap() /*! \class QCborStreamReader::StringResult + \inmodule QtCore This class is returned by readString() and readByteArray(), with either the contents of the string that was read or an indication that the parsing is From b4cc29434769b1d6c08ab2fc76cdcc2dac5dede9 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 26 Apr 2019 09:15:52 +0200 Subject: [PATCH 3/7] Fix page breaking with large images Don't go into an infinite loop breaking pages, when an image is about as large as the page. Correctly take top and bottom margins into account when calculating whether the image could fit on one page. Amends change 416b4cf685030114837bd375664fd12047895a62. Fixes: QTBUG-73730 Change-Id: Id311ddf05510be3b1d131702f4e17025a9861e58 Reviewed-by: Simon Hausmann --- src/gui/text/qtextdocumentlayout.cpp | 5 +- .../tst_qtextdocumentlayout.cpp | 60 +++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index 2e1a2b5bff6..bed0a2c4508 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -145,6 +145,9 @@ struct QTextLayoutStruct { inline QFixed absoluteY() const { return frameY + y; } + inline QFixed contentHeight() const + { return pageHeight - pageBottomMargin - pageTopMargin; } + inline int currentPage() const { return pageHeight == 0 ? 0 : (absoluteY() / pageHeight).truncate(); } @@ -2701,7 +2704,7 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi getLineHeightParams(blockFormat, line, scaling, &lineAdjustment, &lineBreakHeight, &lineHeight, &lineBottom); while (layoutStruct->pageHeight > 0 && layoutStruct->absoluteY() + lineBreakHeight > layoutStruct->pageBottom && - layoutStruct->pageHeight >= lineBreakHeight) { + layoutStruct->contentHeight() >= lineBreakHeight) { layoutStruct->newPage(); floatMargins(layoutStruct->y, layoutStruct, &left, &right); diff --git a/tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.cpp b/tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.cpp index c79f787547d..f66b16b970e 100644 --- a/tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.cpp +++ b/tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.cpp @@ -59,6 +59,8 @@ private slots: void imageAtRightAlignedTab(); void blockVisibility(); + void largeImage(); + private: QTextDocument *doc; }; @@ -347,5 +349,63 @@ void tst_QTextDocumentLayout::blockVisibility() QCOMPARE(doc->size(), halfSize); } +void tst_QTextDocumentLayout::largeImage() +{ + auto img = QImage(400, 500, QImage::Format_ARGB32_Premultiplied); + img.fill(Qt::black); + + { + QTextDocument document; + + document.addResource(QTextDocument::ImageResource, + QUrl("data://test.png"), QVariant(img)); + document.setPageSize({500, 504}); + + auto html = ""; + document.setHtml(html); + + QCOMPARE(document.pageCount(), 2); + } + + { + QTextDocument document; + + document.addResource(QTextDocument::ImageResource, + QUrl("data://test.png"), QVariant(img)); + document.setPageSize({500, 508}); + + auto html = ""; + document.setHtml(html); + + QCOMPARE(document.pageCount(), 1); + } + + { + QTextDocument document; + + document.addResource(QTextDocument::ImageResource, + QUrl("data://test.png"), QVariant(img)); + document.setPageSize({585, 250}); + + auto html = ""; + document.setHtml(html); + + QCOMPARE(document.pageCount(), 3); + } + + { + QTextDocument document; + + document.addResource(QTextDocument::ImageResource, + QUrl("data://test.png"), QVariant(img)); + document.setPageSize({585, 258}); + + auto html = ""; + document.setHtml(html); + + QCOMPARE(document.pageCount(), 2); + } +} + QTEST_MAIN(tst_QTextDocumentLayout) #include "tst_qtextdocumentlayout.moc" From a3acf568d1785d15ebf4d9973df6f9c277d5158a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 25 Apr 2019 13:10:51 -0700 Subject: [PATCH 4/7] Make QFile::copy() less likely to create zero-sized QFile::copy() didn't have the syncToDisk() call that QSaveFile::commit() has. So add it. [ChangeLog][QtCore][QFile] Made QFile::copy() issue a filesystem- synchronization system call, which would make it less likely to result in incomplete or corrupt files if the system reboots or uncleanly shuts down soon after the function returns. New code is advised to use QSaveFile instead, which also allows to display a progress report while copying. Fixes: QTBUG-75407 Change-Id: I95ecabe2f50e450c991afffd1598d09ec73f6482 Reviewed-by: Henrik Hartz Reviewed-by: Volker Hilsheimer Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qfile.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 3166fa1b830..1fb9af576c6 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -832,10 +832,16 @@ QFile::copy(const QString &newName) error = true; } } - if (!error && !out.rename(newName)) { - error = true; - close(); - d->setError(QFile::CopyError, tr("Cannot create %1 for output").arg(newName)); + + if (!error) { + // Sync to disk if possible. Ignore errors (e.g. not supported). + d->fileEngine->syncToDisk(); + + if (!out.rename(newName)) { + error = true; + close(); + d->setError(QFile::CopyError, tr("Cannot create %1 for output").arg(newName)); + } } #ifdef QT_NO_TEMPORARYFILE if (error) From bbfc95914fa21f2025bb29ae17103502265e2cf6 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 25 Apr 2019 12:51:49 +0200 Subject: [PATCH 5/7] Fix determination of OpenGL include paths on macOS, take 3 The sysrootification of QMAKE_INCDIR_OPENGL on macOS must happen only once. Commit 49ef3773 addressed this but stored the sysrootified QMAKE_INCDIR_OPENGL in qt_lib_gui_private.pri. For installer packages, these paths are the paths of the build machine and most likely wrong on the user's machine. This reverts commit 4949ef377349ba4dae840c2d5caa36e2d516707baa and restores the sysrootification in sdk.prf. The original include paths are assigned to QMAKE_EXPORT_INCDIR_OPENGL and stored as QMAKE_INCDIR_OPENGL in qt_lib_gui_private.pri. Fixes: QTBUG-75374 Task-number: QTBUG-73736 Change-Id: I4c0f65866d60660c632363dba3adc7ea2e344bfc Reviewed-by: Alexandru Croitor --- mkspecs/common/mac.conf | 2 +- mkspecs/features/mac/sdk.prf | 7 +++++++ mkspecs/features/qt_configure.prf | 8 +++++++- src/gui/configure.json | 2 +- src/gui/configure.pri | 11 ----------- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/mkspecs/common/mac.conf b/mkspecs/common/mac.conf index f21ba5ec515..b77494ec9b2 100644 --- a/mkspecs/common/mac.conf +++ b/mkspecs/common/mac.conf @@ -17,7 +17,7 @@ QMAKE_EXTENSION_SHLIB = dylib QMAKE_EXTENSIONS_AUX_SHLIB = tbd QMAKE_LIBDIR = -# qtConfLibrary_openglMakeSpec will prefix the proper SDK sysroot +# sdk.prf will prefix the proper SDK sysroot QMAKE_INCDIR_OPENGL = \ /System/Library/Frameworks/OpenGL.framework/Headers \ /System/Library/Frameworks/AGL.framework/Headers/ diff --git a/mkspecs/features/mac/sdk.prf b/mkspecs/features/mac/sdk.prf index 50a41657d83..3a9c2778bbe 100644 --- a/mkspecs/features/mac/sdk.prf +++ b/mkspecs/features/mac/sdk.prf @@ -33,6 +33,13 @@ QMAKE_MAC_SDK_PATH = $$xcodeSDKInfo(Path) QMAKE_MAC_SDK_PLATFORM_PATH = $$xcodeSDKInfo(PlatformPath) QMAKE_MAC_SDK_VERSION = $$xcodeSDKInfo(SDKVersion) +isEmpty(QMAKE_EXPORT_INCDIR_OPENGL) { + QMAKE_EXPORT_INCDIR_OPENGL = $$QMAKE_INCDIR_OPENGL + sysrootified = + for(val, QMAKE_INCDIR_OPENGL): sysrootified += $${QMAKE_MAC_SDK_PATH}$$val + QMAKE_INCDIR_OPENGL = $$sysrootified +} + QMAKESPEC_NAME = $$basename(QMAKESPEC) # Resolve SDK version of various tools diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index aa4348235ea..b2dd846b115 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -786,6 +786,11 @@ defineTest(qtConfLibrary_makeSpec) { !qtConfResolvePathIncs($${1}.includedir, $$eval(QMAKE_INCDIR_$$spec), $$2): \ return(false) + !isEmpty(QMAKE_EXPORT_INCDIR_$$spec) { + $${1}.exportincludedir = $$eval(QMAKE_EXPORT_INCDIR_$$spec) + export($${1}.exportincludedir) + } + # note that the object is re-exported, because we resolve the libraries. return(true) @@ -953,7 +958,8 @@ defineTest(qtConfExportLibrary) { } defines = $$eval($${spfx}.defines) !isEmpty(defines): qtConfOutputVar(assign, $$output, QMAKE_DEFINES_$$NAME, $$defines) - includes = $$eval($${spfx}.includedir) + includes = $$eval($${spfx}.exportincludedir) + isEmpty(includes): includes = $$eval($${spfx}.includedir) !isEmpty(includes): qtConfOutputVar(assign, $$output, QMAKE_INCDIR_$$NAME, $$includes) uses = $$eval($${lpfx}.dependencies) !isEmpty(uses) { diff --git a/src/gui/configure.json b/src/gui/configure.json index 6fdcd562a78..5039934c26a 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -448,7 +448,7 @@ ], "sources": [ { "type": "pkgConfig", "args": "gl", "condition": "!config.darwin" }, - { "type": "openglMakeSpec" } + { "type": "makeSpec", "spec": "OPENGL" } ] }, "opengl_es2": { diff --git a/src/gui/configure.pri b/src/gui/configure.pri index 0db106597ef..1b95449a10c 100644 --- a/src/gui/configure.pri +++ b/src/gui/configure.pri @@ -15,17 +15,6 @@ defineTest(qtConfLibrary_freetype) { return(true) } -defineTest(qtConfLibrary_openglMakeSpec) { - darwin:sdk { - sysrootified = - for(val, QMAKE_INCDIR_OPENGL): sysrootified += $${QMAKE_MAC_SDK_PATH}$$val - QMAKE_INCDIR_OPENGL = $$sysrootified - } - $${1}.spec = OPENGL - !qtConfLibrary_makeSpec($$1, $$2): return(false) - return(true) -} - # Check for Direct X shader compiler 'fxc'. # Up to Direct X SDK June 2010 and for MinGW, this is pointed to by the # DXSDK_DIR variable. Starting with Windows Kit 8, it is included in From 71a7f79bc199b79377c5eaeddd74bc75b3f7af68 Mon Sep 17 00:00:00 2001 From: Simeon Kuran Date: Thu, 18 Apr 2019 17:07:21 +0200 Subject: [PATCH 6/7] Windows QPA: Fix blank Cursor on secondary display CreateCursor only works with standard sizes (32, ...) depending on the display hardware. No longer apply the scale factor for the blank cursor, because it might lead to unsupported cursor sizes resulting in random pixels. Change-Id: I48d84bd913d2dd8f62129126c9a41e58ee2cbcae Reviewed-by: Friedemann Kleint --- .../platforms/windows/qwindowscursor.cpp | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index 00d011ccec1..20a81173045 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -184,9 +184,11 @@ static HCURSOR createBitmapCursor(const QCursor &cursor, qreal scaleFactor = 1) return createBitmapCursor(bbits, mbits, cursor.hotSpot(), invb, invm); } -static QSize systemCursorSize(const QPlatformScreen *screen = nullptr) +static QSize systemCursorSize() { return QSize(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR)); } + +static QSize screenCursorSize(const QPlatformScreen *screen = nullptr) { - const QSize primaryScreenCursorSize(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR)); + const QSize primaryScreenCursorSize = systemCursorSize(); if (screen) { // Correct the size if the DPI value of the screen differs from // that of the primary screen. @@ -212,7 +214,7 @@ static inline QSize standardCursorSize() { return QSize(32, 32); } // createBitmapCursor() only work for standard sizes (32,48,64...), which does // not work when scaling the 16x16 openhand cursor bitmaps to 150% (resulting // in a non-standard 24x24 size). -static QWindowsCursor::PixmapCursor createPixmapCursorFromData(const QSize &systemCursorSize, +static QWindowsCursor::PixmapCursor createPixmapCursorFromData(const QSize &screenCursorSize, // The cursor size the bitmap is targeted for const QSize &bitmapTargetCursorSize, // The actual size of the bitmap data @@ -222,7 +224,7 @@ static QWindowsCursor::PixmapCursor createPixmapCursorFromData(const QSize &syst QPixmap rawImage = QPixmap::fromImage(QBitmap::fromData(QSize(bitmapSize, bitmapSize), bits).toImage()); rawImage.setMask(QBitmap::fromData(QSize(bitmapSize, bitmapSize), maskBits)); - const qreal factor = qreal(systemCursorSize.width()) / qreal(bitmapTargetCursorSize.width()); + const qreal factor = qreal(screenCursorSize.width()) / qreal(bitmapTargetCursorSize.width()); // Scale images if the cursor size is significantly different, starting with 150% where the system cursor // size is 48. if (qAbs(factor - 1.0) > 0.4) { @@ -402,13 +404,13 @@ QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursor switch (cursorShape) { case Qt::SplitVCursor: - return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 32, vsplit_bits, vsplitm_bits); + return createPixmapCursorFromData(screenCursorSize(screen), standardCursorSize(), 32, vsplit_bits, vsplitm_bits); case Qt::SplitHCursor: - return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 32, hsplit_bits, hsplitm_bits); + return createPixmapCursorFromData(screenCursorSize(screen), standardCursorSize(), 32, hsplit_bits, hsplitm_bits); case Qt::OpenHandCursor: - return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 16, openhand_bits, openhandm_bits); + return createPixmapCursorFromData(screenCursorSize(screen), standardCursorSize(), 16, openhand_bits, openhandm_bits); case Qt::ClosedHandCursor: - return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 16, closedhand_bits, closedhandm_bits); + return createPixmapCursorFromData(screenCursorSize(screen), standardCursorSize(), 16, closedhand_bits, closedhandm_bits); case Qt::DragCopyCursor: return QWindowsCursor::PixmapCursor(QPixmap(copyDragCursorXpmC), QPoint(0, 0)); case Qt::DragMoveCursor: @@ -454,7 +456,7 @@ QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursor { Qt::DragLinkCursor, 64, "draglinkcursor_64.png", 0, 0 } }; - const QSize cursorSize = systemCursorSize(screen); + const QSize cursorSize = screenCursorSize(screen); const QWindowsCustomPngCursor *sEnd = pngCursors + sizeof(pngCursors) / sizeof(pngCursors[0]); const QWindowsCustomPngCursor *bestFit = nullptr; int sizeDelta = INT_MAX; @@ -507,7 +509,7 @@ HCURSOR QWindowsCursor::createCursorFromShape(Qt::CursorShape cursorShape, const switch (cursorShape) { case Qt::BlankCursor: { - QImage blank = QImage(systemCursorSize(screen), QImage::Format_Mono); + QImage blank = QImage(systemCursorSize(), QImage::Format_Mono); blank.fill(0); // ignore color table return createBitmapCursor(blank, blank); } From c9002ab7eec1649d700865eac418f1f5d3b0d1a2 Mon Sep 17 00:00:00 2001 From: Alvin Wong Date: Thu, 25 Apr 2019 19:08:04 +0800 Subject: [PATCH 7/7] Fix QOpenGLDebugLogger crash on ANGLE The helper in QOpenGLDebugLogger did not account for the extra "KHR" suffix in the function names and results in a crash when ANGLE is being used. This commit fixes this issue. Change-Id: I439d8bfc53b010be5410286b86c090aff171aaef Fixes: QTBUG-62070 Reviewed-by: Giuseppe D'Angelo --- src/gui/opengl/qopengldebug.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/opengl/qopengldebug.cpp b/src/gui/opengl/qopengldebug.cpp index 2e628a2bd54..9f1bb768697 100644 --- a/src/gui/opengl/qopengldebug.cpp +++ b/src/gui/opengl/qopengldebug.cpp @@ -1366,7 +1366,7 @@ bool QOpenGLDebugLogger::initialize() #define GET_DEBUG_PROC_ADDRESS(procName) \ d->procName = reinterpret_cast< qt_ ## procName ## _t >( \ - d->context->getProcAddress(#procName) \ + d->context->getProcAddress(d->context->isOpenGLES() ? (#procName "KHR") : (#procName)) \ ); GET_DEBUG_PROC_ADDRESS(glDebugMessageControl);